解决Java通过POI获取不到word中目录的内容、样式问题

        发现通过遍历所有的XWPFParagraph不能拿到文档自动生成的目录(如下图这种“带框的”)

        原因是:在xml里面,自动生成的目录不在<w:p>中,而在<w:sdt>中 的<w:sdtContent>中的<w:p>中

         然而从XWPFDocument中并不能直接获取XWPFSDT,所以要先获得XWPFSDT、XWPFParagraph、XWPFTable类实现的接口IBodyElement,这样就可以获取目录的内容了。

        代码如下:


        XWPFDocument doc = new XWPFDocument(is);
        Iterator<IBodyElement> bodyElementsIterator = doc.getBodyElementsIterator();
        while (bodyElementsIterator.hasNext()) {
            IBodyElement bodyElement = bodyElementsIterator.next();
            // 根据元素是不是需要的XWPFSDT
            if (bodyElement instanceof XWPFSDT) {
                //getContent获取内容
                System.out.println(((XWPFSDT) bodyElement).getContent());
            }

        }

        但是这样还是不能获取到目录中字体的样式,因为XWPFSDT类中压根没写这玩意,所以想获取样式该怎么办呢?

        观察XWPFSDT类,发现构造函数之中有样式,如下图

        于是选择重写一个和它类似的类,代码如下...(第一次这么干,有没有懂的大手子指点一下这样做有没有啥危险、正常应该怎么办啊..)

public class MyXWPFSDT extends XWPFAbstractSDT implements IBodyElement, IRunBody, ISDTContents, IRunElement {

    private final ISDTContent content;
    private CTSdtBlock block;

    public MyXWPFSDT(CTSdtRun sdtRun, IBody part) {
        super(sdtRun.getSdtPr(), part);
        this.content = new XWPFSDTContent(sdtRun.getSdtContent(), part, this);
    }

    public MyXWPFSDT(CTSdtBlock block, IBody part) {
        super(block.getSdtPr(), part);
        this.content = new XWPFSDTContent(block.getSdtContent(), part, this);
        this.block = block;
    }
    public ISDTContent getContent() {
        return this.content;
    }
    public CTSdtBlock getBlock(){
        return this.block;
    }

}

        然后修改一下XWPFDocument中的onDocumentRead()方法。

        当遍历到CTSdtBlock时,把我们新写的MyXWPFSDT加入bodyElements列表中,代码如下(本来是想写类继承XWPFDocument的,但是XWPFDocument很多调用XWPFDocument为返回值的函数,感觉很麻烦..所以直接修改了...):

    protected void onDocumentRead() throws IOException {
        try {
            InputStream stream = this.getPackagePart().getInputStream();
            Throwable var3 = null;

            DocumentDocument doc;
            try {
                doc = (DocumentDocument)DocumentDocument.Factory.parse(stream, POIXMLTypeLoader.DEFAULT_XML_OPTIONS);
                this.ctDocument = doc.getDocument();
            } catch (Throwable var15) {
                var3 = var15;
                throw var15;
            } finally {
                if (stream != null) {
                    if (var3 != null) {
                        try {
                            stream.close();
                        } catch (Throwable var14) {
                            var3.addSuppressed(var14);
                        }
                    } else {
                        stream.close();
                    }
                }

            }

            this.initFootnotes();
            XmlCursor docCursor = this.ctDocument.newCursor();
            docCursor.selectPath("./*");

            while(true) {
                XmlObject o;
                do {
                    if (!docCursor.toNextSelection()) {
                        docCursor.dispose();
                        if (doc.getDocument().getBody().getSectPr() != null) {
                            this.headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
                        }

                        Iterator var20 = this.getRelationParts().iterator();

                        while(true) {
                            while(var20.hasNext()) {
                                POIXMLDocumentPart.RelationPart rp = (POIXMLDocumentPart.RelationPart)var20.next();
                                POIXMLDocumentPart p = rp.getDocumentPart();
                                String relation = rp.getRelationship().getRelationshipType();
                                if (relation.equals(XWPFRelation.STYLES.getRelation())) {
                                    this.styles = (XWPFStyles)p;
                                    this.styles.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.NUMBERING.getRelation())) {
                                    this.numbering = (XWPFNumbering)p;
                                    this.numbering.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.FOOTER.getRelation())) {
                                    XWPFFooter footer = (XWPFFooter)p;
                                    this.footers.add(footer);
                                    footer.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.HEADER.getRelation())) {
                                    XWPFHeader header = (XWPFHeader)p;
                                    this.headers.add(header);
                                    header.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
                                    this.comments = (XWPFComments)p;
                                    this.comments.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) {
                                    this.settings = (XWPFSettings)p;
                                    this.settings.onDocumentRead();
                                } else if (relation.equals(XWPFRelation.IMAGES.getRelation())) {
                                    XWPFPictureData picData = (XWPFPictureData)p;
                                    picData.onDocumentRead();
                                    this.registerPackagePictureData(picData);
                                    this.pictures.add(picData);
                                } else if (relation.equals(XWPFRelation.CHART.getRelation())) {
                                    XWPFChart chartData = (XWPFChart)p;
                                    this.charts.add(chartData);
                                } else if (relation.equals(XWPFRelation.GLOSSARY_DOCUMENT.getRelation())) {
                                    Iterator var7 = p.getRelations().iterator();

                                    while(var7.hasNext()) {
                                        POIXMLDocumentPart gp = (POIXMLDocumentPart)var7.next();
                                        POIXMLDocumentPart._invokeOnDocumentRead(gp);
                                    }
                                }
                            }

                            this.initHyperlinks();
                            return;
                        }
                    }

                    o = docCursor.getObject();
                } while(!(o instanceof CTBody));

                XmlCursor bodyCursor = o.newCursor();
                bodyCursor.selectPath("./*");

                while(bodyCursor.toNextSelection()) {
                    XmlObject bodyObj = bodyCursor.getObject();
                    if (bodyObj instanceof CTP) {
                        XWPFParagraph p = new XWPFParagraph((CTP)bodyObj, this);
                        this.bodyElements.add(p);
                        this.paragraphs.add(p);
                    } else if (bodyObj instanceof CTTbl) {
                        XWPFTable t = new XWPFTable((CTTbl)bodyObj, this);
                        this.bodyElements.add(t);
                        this.tables.add(t);
                    } else if (bodyObj instanceof CTSdtBlock) {
                        XWPFSDT c = new XWPFSDT((CTSdtBlock)bodyObj, this);
                        MyXWPFSDT cc = new MyXWPFSDT((CTSdtBlock)bodyObj, this);
                        this.bodyElements.add(c);
                        this.contentControls.add(c);
                        this.bodyElements.add(cc);
                        this.mycontentControls.add(cc);
                    }
                }

                bodyCursor.dispose();
            }
        } catch (XmlException var17) {
            throw new POIXMLException(var17);
        }
    }

        最后就是获取目录内容、样式的代码了,代码如下

@Test
    void Testdirectory() throws Exception {
        InputStream is = new FileInputStream("...");

        XWPFDocument doc = new XWPFDocument(is);
        Iterator<IBodyElement> bodyElementsIterator = doc.getBodyElementsIterator();
        while (bodyElementsIterator.hasNext()) {
            IBodyElement bodyElement = bodyElementsIterator.next();

            if (bodyElement instanceof MyXWPFSDT) {
                System.out.println(((MyXWPFSDT) bodyElement).getContent().getText());
                CTSdtBlock block = ((MyXWPFSDT) bodyElement).getBlock();

                System.out.println("***********");
                CTSdtContentBlock sdtContent = block.getSdtContent();
                CTP[] pArray = sdtContent.getPArray();
                System.out.println(pArray.length);

                for (int i = 0; i< pArray.length; i++){
                    System.out.println("-----------");
                    //这就是样式
                    System.out.println(pArray[i].getPPr());
                }
                System.out.println("***********");
            }
        }

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值