现在我有一个docx文件,我加载到XWPFDocument
XWPFDocument doc = new XWPFDocument(InputStream)
通过执行
,我可以看到它存储在style.xml中的不同样式的当前字体大小for (CTStyle ctstyle : doc.getStyle().getStyleList())
{
if (ctstyle.isSetRPr())
{
if (ctstyle.getRPr().isSetSz())
{
CTHpsMeasure size = ctstyle.getRPr().getSz();
System.out.println(size.getVal());
}
}
}
我想用poi更新字体大小,所以我试过
for (CTStyle ctstyle : doc.getStyle().getStyleList())
{
if (ctstyle.isSetRPr())
{
if (ctstyle.getRPr().isSetSz())
{
CTHpsMeasure size = ctstyle.getRPr().getSz();
size.setVal(BigInteger.valueOf(12));
ctstyle.getRPr().setSz(size);
}
}
}
然而,在完成上面的代码之后,如果我使用第一段代码检查我的文档(XWPFDocument doc
对象)的字体大小,字体大小仍然是原始值,而不是12 I打算设定。
有关于如何解决这个问题的建议吗?
答案 0 :(得分:0)
XWPFDocument.getStyle获取org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles
但不获取文档部分/word/styles.xml
。因此,在写出CTStyles
时,不会提交此XWPFDocument
中的更改。
XWPFDocument.getStyles获取XWPFStyles
扩展POIXMLDocumentPart
并覆盖commit
方法。因此,在写出XWPFStyles
时,将在XWPFDocument
中进行更改。
不幸的是,没有一种方法可以从这个XWPFStyles
中获取所有单一样式。有一个字段private CTStyles ctStyles
,也在protected void commit()
中提交,但不可公开访问。所以我用反射来得到它。
根据您之前的问题,我知道您在解析*.docx
文件时遇到问题,该文件的字体大小被错误地设置为双精度<w:sz w:val="24.0"/>
,这绝对是错误的,导致size.getVal()
投掷org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException: Invalid integer value: 24.0
}。
ctstyle.getRPr().getSz()
无崩溃也有<w:sz w:val="24.0"/>
。在这里你可以得到真实的大小。为此,直接解析CTHpsMeasure size
的XML,然后将从那里得到的值设置为BigInteger
。 BigDecimal
为此提供了一种方法。
另外你还应该得到并纠正ctstyle.getRPr().getSzCs()
,这是&#34;复杂脚本的大小&#34;使用的字体也可能是错误的。
以下适用于我,之后所有具有字体大小的样式都设置了整数字体大小。例如,<w:sz w:val="24.0"/><w:szCs w:val="24.0"/>
是<w:sz w:val="24"/><w:szCs w:val="24"/>
。注意这里的测量单位是半点24半点= 12点。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.lang.reflect.Field;
public class WordChangeStyles {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("WordUsingStyles.docx"));
XWPFStyles styles = document.getStyles(); //XWPFStyles extends POIXMLDocumentPart and overwrites commit method
Field _ctStyles = XWPFStyles.class.getDeclaredField("ctStyles");
_ctStyles.setAccessible(true);
CTStyles ctStyles = (CTStyles)_ctStyles.get(styles);
CTHpsMeasure size;
String sz;
for (CTStyle ctstyle : ctStyles.getStyleList()) {
if (ctstyle.isSetRPr()) {
if (ctstyle.getRPr().isSetSz()) {
size = ctstyle.getRPr().getSz();
if (size != null) {
sz = size.selectAttribute("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "val").newCursor().getTextValue();
System.out.println(sz); //here you could get the real meant size out of
size.setVal(new BigDecimal(sz).toBigInteger()); //sets the sz got from size truncated to BigInteger
ctstyle.getRPr().setSz(size); //after that the font size should be integer
System.out.println(ctstyle.getRPr().getSz().getVal());
}
size = ctstyle.getRPr().getSzCs();
if (size != null) {
sz = size.selectAttribute("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "val").newCursor().getTextValue();
System.out.println(sz); //here you could get the real meant size out of
size.setVal(new BigDecimal(sz).toBigInteger()); //sets the sz got from size truncated to BigInteger
ctstyle.getRPr().setSzCs(size); //after that the font size should be integer
System.out.println(ctstyle.getRPr().getSzCs().getVal());
}
}
}
}
document.write(new FileOutputStream("WordUsingStyles.docx")); //while writing out XWPFStyles will be committed
document.close();
}
}