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):
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 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); } }