run.getFontFamily()使用Apache POI为.docx文件返回null

时间:2017-05-18 07:04:19

标签: java apache-poi docx

我想逐段读取.docx文件,我想检查每个段落的字体系列,字体大小,边距,对齐方式,颜色等。 这是我的.docx文件的一个例子:

Sample of .docx file

这是我的代码:

FileInputStream fis = new FileInputStream("D:/test3.docx");
XWPFDocument docx = new XWPFDocument(fis);
List<XWPFParagraph> paragraphList = docx.getParagraphs();
for (int i = 0; i < paragraphList.size(); i++) {
            System.out.println("paragraph " + i + " is::    " + paragraphList.get(i).getText());
            for (XWPFRun run : paragraphList.get(i).getRuns()) {
                System.out.println("paragraph :: run text is::    " + run.text());
                System.out.println("paragraph :: run color is::    " + run.getColor());
                System.out.println("paragraph :: run font-famyly is::    " + run.getFontFamily()); //It always return null; why?
                System.out.println("paragraph :: run font-name is::    " + run.getFontName()); //It always return null; why?
                System.out.println("paragraph :: run text position is::    " + run.getTextPosition()); //It always return -1; why?
                System.out.println("paragraph :: run font-size is::    " + run.getFontSize());
                System.out.println("paragraph :: run IsBold::    " + run.isBold());
                System.out.println("paragraph :: run IsItalic::    " + run.isItalic());

            }}

但是fontFamily(对于我选择的每个字体系列),fontName,textPosition始终为null。 我还有另一个代码示例:

            XWPFStyles styles = docx.getStyles();
        for (int i = 0; i < paragraphList.size(); i++) {
            System.out.println("paragraph " + i + " styleID  is::    " + paragraphList.get(i).getStyleID());
            if (paragraphList.get(i).getStyleID() != null) {
                String styleid = paragraphList.get(i).getStyleID();
                XWPFStyle style = styles.getStyle(styleid);
                if (style != null) {
                    System.out.println("style name is::    " + style.getName());
                    if (style.getName().startsWith("heading")) {
                        System.out.println("This part of text is heading!!");
                    }
                }

            }
        }

但除了标题外,样式通常为空。

3 个答案:

答案 0 :(得分:1)

Apache POI解析document.xml文件的.docx部分。当您执行run.getFontFamily()时,只有在运行的运行属性中存在字体系列时,它才会返回该字体系列。否则它将返回null。例如,请考虑此示例运行

<w:r>
    <w:rPr>
        <w:lang w:val="en-US"/>
    </w:rPr>
    <w:t>The quick brown fox jumps over the lazy dog.</w:t>
</w:r>

这确实在<w:rPr>运行属性标记中指定了其字体系列。在这种情况下,您必须上升层次结构,看看具有此运行的段落是否具有样式。如果即使<w:Pr>段落属性没有样式,也会应用默认为文档的字体系列。文档默认值在styles.xml文件中指定。

答案 1 :(得分:1)

以下是使用apache POI从style.xml中获取样式的示例代码。

     XWPFDocument docx;                                                 // Set the docx
       XWPFRun run;                                                    //get the required run
       String fontFamily= run.getFontFamily();
        if(fontFamily == null){                                         // When the font in the run is null check for the default fonts in styles.xml
            String styleID = run.getParagraph().getStyleID();
            XWPFStyle style = docx.getStyle(styleID);
            CTStyle ctStyle = style.getCTStyle();
            CTRPr ctrPr = ctStyle.getRPr();
            CTFonts ctFonts = ctrPr.getRFonts();
            if(ctFonts!= null){
                fontFamily = ctFonts.getAscii();               // Or you may getCs() , getAnsi() etc.
            }
//                        else {
//                            fontFamily = ctStyle.getPPr().getRPr().getRFonts().getAscii();
//                        }
//                        System.out.println();
        }
        return fontFamily;

希望这会有所帮助。

答案 2 :(得分:0)

我发现我想检查的字体不是标准的!!因此,对于另一种标准字体,以上所有代码都可以完美地工作。