简体   繁体   English

如何使用Apache POI更改docx的style.xml中的字体大小

[英]How to change font size in style.xml for docx using apache poi

Right now I have a docx file that I loaded into XWPFDocument 现在,我有一个docx文件已加载到XWPFDocument

XWPFDocument doc = new XWPFDocument(InputStream)

I can see it's current font size for different styles that's stored in style.xml by doing 我可以通过执行以下操作查看存储在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());
        }
    }
}

I want to update the font size using poi, so I tried 我想使用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);
        }
    }
}

However, after finish the above piece of code, if I check the font size of my document ( XWPFDocument doc object) using the first piece of code, the font size is still the original value, not the 12 I intended to set. 但是,完成上述代码后,如果我使用第一段代码检查文档( XWPFDocument doc对象)的字体大小,则字体大小仍然是原始值,而不是我打算设置的12。

Is there any suggestions for how to fix this? 关于如何解决此问题有什么建议吗?

XWPFDocument.getStyle gets org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles but not the document part /word/styles.xml . XWPFDocument.getStyle获取org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles但不获取文档部分/word/styles.xml So changings in this CTStyles will not be committed while writing out the XWPFDocument . 因此, CTStyles将不会提交对此CTStylesXWPFDocument

XWPFDocument.getStyles gets the XWPFStyles which extends POIXMLDocumentPart and overwrites commit method. XWPFDocument.getStyles获取XWPFStyles ,它扩展POIXMLDocumentPart并覆盖commit方法。 So changings in this XWPFStyles will be committed while writing out the XWPFDocument . 因此,在XWPFStyles将提交对XWPFDocument

Unfortunately there is not a method for getting all single style out of this XWPFStyles . 不幸的是,没有一种方法可以从XWPFStyles获取所有单一样式。 There is a field private CTStyles ctStyles , which also is committed in protected void commit() , but not public accessible. 有一个private CTStyles ctStyles字段private CTStyles ctStyles ,它也可以在protected void commit() ,但不能公共访问。 So I have used reflection to get it. 所以我用反射来得到它。

From your previous questions I know that you have problems parsing a *.docx file which has font sizes wrongly set as doubles <w:sz w:val="24.0"/> which is definitely wrong and leads size.getVal() throwing org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException: Invalid integer value: 24.0 . 从先前的问题中,我知道您在解析*.docx文件时遇到问题,该文件的字体大小错误地设置为doubles <w:sz w:val="24.0"/> ,这肯定是错误的,并导致size.getVal()引发org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException: Invalid integer value: 24.0

The ctstyle.getRPr().getSz() works without crash also having <w:sz w:val="24.0"/> . ctstyle.getRPr().getSz()运行也不会崩溃,并且<w:sz w:val="24.0"/> Here you could get the real meant size out of. 在这里,您可以获得实际的实际尺寸。 For this do parsing the XML of the CTHpsMeasure size directly and then set the the value got from there truncated to BigInteger . 为此,请直接解析CTHpsMeasure size的XML,然后将从那里截取的值设置为BigInteger BigDecimal provides a method for this. BigDecimal为此提供了一种方法。

And you additionally should also get and correct ctstyle.getRPr().getSzCs() , which is the size of the "Complex script" font used and also could be wrong. 另外,您还应该获取并纠正ctstyle.getRPr().getSzCs() ,它是所使用的“复杂脚本”字体的大小,也可能是错误的。

The following works for me and after that all styles having font size have integer font size set. 以下对我有用,然后所有具有字体大小的样式都设置了整数字体大小。 For example <w:sz w:val="24.0"/><w:szCs w:val="24.0"/> is <w:sz w:val="24"/><w:szCs w:val="24"/> then. 例如, <w:sz w:val="24.0"/><w:szCs w:val="24.0"/><w:sz w:val="24"/><w:szCs w:val="24"/>然后是<w:sz w:val="24"/><w:szCs w:val="24"/> Note the measurement unit here is half points 24 half points = 12 pt. 请注意,此处的测量单位是半点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();
 }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM