为带有页码的指示的XWPFDocument创建一个目录(Creating a Table of Contents for a XWPFDocument with page numbers' indication)_电脑培训

为带有页码的指示的XWPFDocument创建一个目录(Creating a Table of Contents for a XWPFDocument with page numbers' indication)

实际上,我使用Apache POI生成Word文档,并且需要自动创建引用段落的目录(TOC)以及页面指示。

这是我正在使用的代码(我省略了先决条件和内部方法的主体):

XWPFDocument doc = new XWPFDocument(OPCPackage.openOrCreate(new File(document)));

String strStyleId = "Index Style";
addCustomHeadingStyle(doc, strStyleId, 1);

XWPFParagraph documentControlHeading = doc.createParagraph();
changeText(documentControlHeading, "First try");
documentControlHeading.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading.setPageBreak(true);
documentControlHeading.setStyle(strStyleId);

XWPFParagraph documentControlHeading1 = doc.createParagraph();
changeText(documentControlHeading1, "Second try");
documentControlHeading1.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading1.setPageBreak(true);
documentControlHeading1.setStyle(strStyleId);

doc.createTOC();

当我打开生成的文档时,我得到了这个结果(见蓝色方块):

在这里输入图像描述

在左边部分,我可以看到生成的TOC。 到现在为止还挺好。 然而,在文档的正文中,我只能看到一个静态文本“目录”,根本没有任何迹象(既不是段落也不是页面)。 我甚至无法与之互动。

如果我点击菜单条目“目录”(左上角的红色方块),我想要生成的“真实”内容列表正在生成(当然,请按照箭头......)。

我的问题是: 如何从代码中获得第二个结果(红色TOC)?

非常感谢。

_附注:_我甚至尝试把doc.enforceUpdateFields();doc.createTOC(); ,但是TOC的每个参考都以这种方式消失。

@Sucy,我添加您请求的方法。 不知道你是否能找到它们有用,但:

/*
 * Adds a custom style with the given indentation level at the given document.
 */
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {

    CTStyle ctStyle = CTStyle.Factory.newInstance();
    ctStyle.setStyleId(strStyleId);

    CTString styleName = CTString.Factory.newInstance();
    styleName.setVal(strStyleId);
    ctStyle.setName(styleName);

    CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
    indentNumber.setVal(BigInteger.valueOf(headingLevel));

    // lower number > style is more prominent in the formats bar
    ctStyle.setUiPriority(indentNumber);

    CTOnOff onoffnull = CTOnOff.Factory.newInstance();
    ctStyle.setUnhideWhenUsed(onoffnull);

    // style shows up in the formats bar
    ctStyle.setQFormat(onoffnull);

    // style defines a heading of the given level
    CTPPr ppr = CTPPr.Factory.newInstance();
    ppr.setOutlineLvl(indentNumber);
    ctStyle.setPPr(ppr);

    XWPFStyle style = new XWPFStyle(ctStyle);

    // is a null op if already defined
    XWPFStyles styles = docxDocument.createStyles();

    style.setType(STStyleType.PARAGRAPH);
    styles.addStyle(style);

}

/*
 * Changes the text of a given paragraph.
 */
public static void changeText(XWPFParagraph p, String newText) {
    if (p != null) {
        List<XWPFRun> runs = p.getRuns();
        for (int i = runs.size() - 1; i >= 0; i--) {
            p.removeRun(i);
        }

        if (runs.size() == 0) {
            p.createRun();
        }

        XWPFRun run = runs.get(0);
        run.setText(newText, 0);
    }
}

I am actually generating a Word Document with Apache POI, and I need to automatically create a Table of Contents (TOC) that references the paragraphs, with their page's indication.

This is the code I am using (I omit preconditions and internal methods' body):

XWPFDocument doc = new XWPFDocument(OPCPackage.openOrCreate(new File(document)));

String strStyleId = "Index Style";
addCustomHeadingStyle(doc, strStyleId, 1);

XWPFParagraph documentControlHeading = doc.createParagraph();
changeText(documentControlHeading, "First try");
documentControlHeading.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading.setPageBreak(true);
documentControlHeading.setStyle(strStyleId);

XWPFParagraph documentControlHeading1 = doc.createParagraph();
changeText(documentControlHeading1, "Second try");
documentControlHeading1.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading1.setPageBreak(true);
documentControlHeading1.setStyle(strStyleId);

doc.createTOC();

When I open the resulting document, I am getting this result (see blue squares):

enter image description here

In the left part, I can see the generated TOC. So far, so good. In the document's body, however, I can just see a static text "Table of Contents", with no indications at all (neither paragraphs nor pages). I cannot even interact with it.

If I'd click on the menu entry "Table of Contents" (red square on the upper-left corner), the "real" Table of Content that I want is being generated (follow the arrow, of course...).

My question is: how can I achieve the second result (red TOC) from code?

Thank you so much.

Side note: I even tried putting doc.enforceUpdateFields(); after doc.createTOC();, but every reference of the TOC disappears, this way.

@Sucy, I add the methods that you requested. Don't know if you can find them useful, though:

/*
 * Adds a custom style with the given indentation level at the given document.
 */
private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {

    CTStyle ctStyle = CTStyle.Factory.newInstance();
    ctStyle.setStyleId(strStyleId);

    CTString styleName = CTString.Factory.newInstance();
    styleName.setVal(strStyleId);
    ctStyle.setName(styleName);

    CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
    indentNumber.setVal(BigInteger.valueOf(headingLevel));

    // lower number > style is more prominent in the formats bar
    ctStyle.setUiPriority(indentNumber);

    CTOnOff onoffnull = CTOnOff.Factory.newInstance();
    ctStyle.setUnhideWhenUsed(onoffnull);

    // style shows up in the formats bar
    ctStyle.setQFormat(onoffnull);

    // style defines a heading of the given level
    CTPPr ppr = CTPPr.Factory.newInstance();
    ppr.setOutlineLvl(indentNumber);
    ctStyle.setPPr(ppr);

    XWPFStyle style = new XWPFStyle(ctStyle);

    // is a null op if already defined
    XWPFStyles styles = docxDocument.createStyles();

    style.setType(STStyleType.PARAGRAPH);
    styles.addStyle(style);

}

/*
 * Changes the text of a given paragraph.
 */
public static void changeText(XWPFParagraph p, String newText) {
    if (p != null) {
        List<XWPFRun> runs = p.getRuns();
        for (int i = runs.size() - 1; i >= 0; i--) {
            p.removeRun(i);
        }

        if (runs.size() == 0) {
            p.createRun();
        }

        XWPFRun run = runs.get(0);
        run.setText(newText, 0);
    }
}

更新时间:2022-09-04 06:09

最满意答案

你所看到的XWPF类是一项正在进行的工作,没有真正的总体架构。 随着时间的推移,这将随着时间的推移而变化,但同时您可以尝试用这种方法为段落添加一个简单的TOC字段。

XWPFParagraph p;
...
// get or create your paragraph
....
CTP ctP = p.getCTP();
CTSimpleField toc = ctP.addNewFldSimple();
toc.setInstr("TOC \\h");
toc.setDirty(STOnOff.TRUE);

这将创建一个带有超链接到页面的目录,当Word打开它时应重新计算它,并且目录将基于预定义的HeaderX样式。

The XWPF classes as you have seen are a work in progress, with no real overarching architecture. That will change over time as we work on it, but in the mean time you can try to add a simple TOC field to a paragraph in this way.

XWPFParagraph p;
...
// get or create your paragraph
....
CTP ctP = p.getCTP();
CTSimpleField toc = ctP.addNewFldSimple();
toc.setInstr("TOC \\h");
toc.setDirty(STOnOff.TRUE);

This will create a Table of contents with hyperlinks to the pages, it should be recalculated when Word opens it, and the table of contents will be based on predefined HeaderX styles.

相关问答

更多

  • TCP/IP模型是一个________。[2022-12-11]

    a

  • 下列中不属于面向对象的编程语言的是?[2022-05-30]

    a

  • 为带有页码的指示的XWPFDocument创建一个目录(Creating a Table of Contents for a XWPFDocument with page numbers' indication)[2022-09-04]

    你所看到的XWPF类是一项正在进行的工作,没有真正的总体架构。 随着时间的推移,这将随着时间的推移而变化,但同时您可以尝试用这种方法为段落添加一个简单的TOC字段。 XWPFParagraph p; ... // get or create your paragraph .... CTP ctP = p.getCTP(); CTSimpleField toc = ctP.addNewFldSimple(); toc.setInstr("TOC \h"); toc.setDirty(STOnOff.TRUE ...

  • FPDF目录和页码问题(FPDF table of contents and issues with page numbers)[2022-06-09]

    这可以通过几个简单的步骤完成。 创建PDF文档内容时,请在您希望TOC所在的位置留下一个空页(或多个页面),例如: $this->pdf->AddPage('P','letter'); $this->pdf->AddPage('P','letter'); 在构建pdf内容时将TOC内容添加到数组中。 $toc\[\] = \['label' -> "item", 'page' -> $pdf->PageNo()]; 构建完所有内容后,保存当前页码: $last_page = $pdf->PageNo(); 将页码 ...

  • 具有动态页码的目录页面(Table of Contents Page with Dynamic Page Numbers)[2022-05-12]

    好的,我找到了一个足够的解决方案,我已经建立了一个POC - 它的工作原理。 它是一种双通道方法,使用自定义外部组件。 首先渲染子报告以填充目录表,然后运行主报告并在TOC页面上显示TOC结果,然后再进行子报告。 这是让我走的链接 。 问候, 贾森 Ok, I've found an adequate solution that I've built a POC on - and it works. Its a two pass approach, using custom external assembl ...

  • Apache POI - 如何在XWPFDocument中并排绘制表(Apache POI - How to draw tables side by side in XWPFDocument)[2022-06-24]

    表是块级项目,这意味着它将根据页面的高度和跨度占用垂直空间,无论是否使用该空间。 所以没有办法以相同的方式并排“流动”两个表,无法并排流动两个段落。 有几种方法可以实现这种效果,但在您的情况下最直接的方法可能是创建一个1行乘三列的表,并将左表放在第一个单元格中,将右表放在第三列中。 中间列可用于实现两者之间的间隔。 您可能不希望在包含表上使用任何边框,因为它用于格式化而不是显示。 A table is a block-level item, meaning it will take up vertical ...

  • 带页码的目录 - 如何实现(Table of contents with page number - how to implement)[2023-03-29]

    我建议你从原始文档中查看此示例。 没有办法(或至少我不知道/没有找到如何)在开始时生成目录(因为没有办法知道页码)。 因此,您必须在结束时(在摘要带中)生成它,然后将其移动到您想要放置的位置。 要移动它,请使用JasperPrint类,方法getPages,addPage,removePage。 我猜你会有子报告,如果是这样,你需要传递你将在运行时填充到每个子报告的JRBeanCollectionDataSource(并将值返回给主报告)。 希望有所帮助。 I would recommend you che ...

  • TCPDF目录和页码问题(TCPDF table of contents and issues with page numbers)[2022-08-15]

    在计算页面时,PageNo()有点时髦。 它按照创建的顺序输出它是什么页面,并且因为ToC页面被创建为最后一页,它将显示为最后一页。 所以改为使用 // Page number $this->Cell(0, 12, ' '.$this->getAliasNumPage().' of '.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M'); 您提供的其余代码(如检查它是否是第一页)应与PageNo()一起使用。 Pa ...

  • 如何用Excel VBA引用MS Word目录页码?(How to reference MS Word table of contents page numbers with Excel VBA?)[2022-04-20]

    我不是“沃尔德”,所以这就是我的目标: Function GetPagesNumber(doc As Document) As Long() Dim i As Long Dim myRng As Range Dim myHeadings As Variant With doc Set myRng = .Content myRng.Collapse Direction:=wdCollapseEnd myHeadings = . ...

  • Apache POI XWPFDocument对象序列化(Apache POI XWPFDocument object serialization)[2022-03-12]

    推荐对答案的评论...... 序列化XWPFDocument (或实际上任何POI UserModel文档)的方法是通过write(OutputStream)方法 如果需要序列化为字节数组,则可以执行以下操作: XWPFDocument doc = new XWPFDocument(); ... ByteArrayOutputStream baos = new ByteArrayOutputStream(); doc.write(baos); return baos.toByteArray(); 假设您 ...


原网址: 访问
创建于: 2023-05-08 11:04:37
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论