Page 1 of 1

PageNumbers in Table of Content with export-fo

PostPosted: Fri Jun 04, 2021 8:15 pm
by IntershipAlex
Hello everyone,

I'm currently in a internship. I've been given a the task to generate .docx files with docx4j, a given template and input from a database.
Because the resulting application should run on a server, I'm not allowed to use documents4j because of the lack of a Word instance.
Until now everything worked fine, but now if run into some problems concerning the page-numbering for the table of contents with export-fo.
I've now added images and that throws the numbering off the rails.
When opening the word page numbers are off by ~half a page per image.
That is exactly the size for each individual picture (they are by Default all the same size).
Is there anyway to improve that kind of lag in the resulting file before saving it.
I already tried it with the default methods i've found in docx4j libs. I use the newest version of export-fo and docx4j-JAXB-ReferenceImpl.

Yours sincerely
Alex

Re: PageNumbers in Table of Content with export-fo

PostPosted: Mon Jun 07, 2021 10:11 am
by jason
Hi Alex

As you may be aware, a user can have Word update the page numbers after they open the document.

But if the document is to become a PDF (before it is ever opened in Word), the page numbers need to be correct.

I'm afraid that the results you are seeing are what one would expect using export-fo. The reason being that the FO page layout model is different to Word's. So for example, Word places an image on one page, but FOP places it on another.

It would be possible to adapt FOP so its layout was closer to Word's, and we'd like to see this happen, but it isn't something we're currently working on. Perhaps you could find some quick wins around image handling?

Another alternative would be to build a page layout model for docx4j from the ground up.

Re: PageNumbers in Table of Content with export-fo

PostPosted: Fri Jun 18, 2021 6:44 pm
by IntershipAlex
Thank you for your help and quick reply. Also, sorry for my late reply.
I've not tried it yet, but maybe, for a quick win, i will try to set the images to background images and fill up the front space with empty lines.
I'm not quite sure how to build a page layout. It would need to be pretty flexible behause i can not determine here the picture will be. This will depend on the amount of input i get additionally to the images, which i will have to put to the resulting file.

Re: PageNumbers in Table of Content with export-fo

PostPosted: Fri Jun 18, 2021 6:56 pm
by IntershipAlex
While going on with my work, i' Ive found another issue.
When im trying to add a hyperlink to the document it always kills my toc totally.
I'm trying to do something like that:

Code: Select all
...
               if (document.getMainDocumentPart().getRelationshipsPart() != null) {
                  id = report.getMainDocumentPart().getRelationshipsPart().size() + 1;
               } else {
                  id += 1;
               }
               P.Hyperlink phyperlink = factory.createPHyperlink();
               JAXBElement<P.Hyperlink> phyperlinkWrapped = factory.createPHyperlink(phyperlink);

               phyperlink.setId("rId" + id);
               id++;
               phyperlink.setHistory(true);
               // Create object for r
               R r = factory.createR();
               phyperlink.getContent().add(r);
               // Create object for rPr
               RPr rprh = factory.createRPr();
               r.setRPr(rprh);
               // Create object for rStyle
               RStyle rstyle = factory.createRStyle();
               rprh.setRStyle(rstyle);
               rstyle.setVal("Hyperlink");
               // Create object for t (wrapped in JAXBElement)
               Text text = factory.createText();
               JAXBElement<org.docx4j.wml.Text> textWrapped = factory.createRT(text);
               r.getContent().add(textWrapped);
               text.setValue("www.google.com");
               paragraph.getContent().add(phyperlinkWrapped);
               org.docx4j.relationships.ObjectFactory relFactory = new org.docx4j.relationships.ObjectFactory();
               org.docx4j.relationships.Relationship rel = relFactory.createRelationship();

               rel.setId("rId" + id);
               rel.setType(Namespaces.HYPERLINK);
               rel.setTarget("www.google.com");
               rel.setTargetMode("External");
               document.getMainDocumentPart().getRelationshipsPart().addRelationship(rel);
...


also I've tried just doing:

Code: Select all
...

                  String openXML = "<w:hyperlink r:id=\"rId4\" w:history=\"true\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
                        + "<w:r>"
                        + "<w:rPr>"
                        + "<w:rStyle w:val=\"Hyperlink\"/>"
                        + "</w:rPr>"
                        + "<w:t>www.google.com</w:t>"
                        + "</w:r>"
                        + "</w:hyperlink>";
                  P.Hyperlink phyperlink = (P.Hyperlink) XmlUtils.unmarshalString(openXML);
                  paragraph.getContent().add(phyperlink);
...


With both variants I get errors/exceptions when updating my toc.


Origin is: tocGenerator.updateToc(false, true);
Thrown error is:
org.docx4j.toc.TocException: Exception exporting package
at org.docx4j.toc.TocGenerator.getPageNumbersMapViaFOP(TocGenerator.java:812)
at org.docx4j.toc.TocGenerator.getPageNumbersMap(TocGenerator.java:655)
at org.docx4j.toc.TocGenerator.populateToc(TocGenerator.java:402)
at org.docx4j.toc.TocGenerator.generateToc(TocGenerator.java:306)
at org.docx4j.toc.TocGenerator.updateToc(TocGenerator.java:536)
at org.docx4j.toc.TocGenerator.updateToc(TocGenerator.java:484)
...
Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Exception exporting package
at org.docx4j.convert.out.common.AbstractExporter.export(AbstractExporter.java:106)
at org.docx4j.Docx4J.toFO(Docx4J.java:712)
at org.docx4j.toc.TocGenerator.getPageNumbersMapViaFOP(TocGenerator.java:784)
... 19 more
Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Exception writing Document to OutputStream: org.apache.fop.fo.ValidationException: Missing attribute on fo:basic-link: Either external-destination or internal-destination must be specified. (Siehe Position 7:236)
at org.docx4j.utils.XmlSerializerUtil.serialize(XmlSerializerUtil.java:56)
at org.docx4j.utils.XmlSerializerUtil.serialize(XmlSerializerUtil.java:18)
at org.docx4j.convert.out.fo.renderers.FORendererApacheFOP.calcResults(FORendererApacheFOP.java:272)
at org.docx4j.convert.out.fo.renderers.FORendererApacheFOP.render(FORendererApacheFOP.java:152)
at org.docx4j.convert.out.fo.AbstractFOExporter.postprocess(AbstractFOExporter.java:168)
at org.docx4j.convert.out.fo.AbstractFOExporter.postprocess(AbstractFOExporter.java:47)
at org.docx4j.convert.out.common.AbstractExporter.export(AbstractExporter.java:81)
... 21 more
Caused by: javax.xml.transform.TransformerException: org.apache.fop.fo.ValidationException: Missing attribute on fo:basic-link: Either external-destination or internal-destination must be specified. (Siehe Position 7:236)
at org.docx4j.org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:535)
at org.docx4j.utils.XmlSerializerUtil.serialize(XmlSerializerUtil.java:51)
... 27 more
Caused by: org.apache.fop.fo.ValidationException: Missing attribute on fo:basic-link: Either external-destination or internal-destination must be specified. (Siehe Position 7:236)
at org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38)
at org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58)
at org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173)
at com.sun.proxy.$Proxy234.missingLinkDestination(Unknown Source)
at org.apache.fop.fo.flow.BasicLink.bind(BasicLink.java:95)
at org.apache.fop.fo.FObj.processNode(FObj.java:131)
at org.apache.fop.fo.FOTreeBuilder$MainFOHandler.startElement(FOTreeBuilder.java:293)
at org.apache.fop.fo.FOTreeBuilder.startElement(FOTreeBuilder.java:179)
at org.docx4j.convert.out.fo.PlaceholderReplacementHandler.startElement(PlaceholderReplacementHandler.java:106)
at org.docx4j.org.apache.xalan.transformer.TransformerIdentityImpl.startElement(TransformerIdentityImpl.java:1119)
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:510)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2710)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216)
at org.docx4j.org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:518)



Am i missing something or what do I do wrong? Can somebody please help me with that problem.

Re: PageNumbers in Table of Content with export-fo

PostPosted: Sat Jun 19, 2021 11:49 am
by jason
Per the example at https://github.com/plutext/docx4j/blob/ ... kTest.java getRelationshipsPart().addRelationship(rel) should set the rel's @Id correctly, so try doing it that way.

If the hyperlink is correctly set up in the docx, then export-fo should handle it properly.

Example: <basic-link xmlns="http://www.w3.org/1999/XSL/Format" external-destination="url(http://davidpritchard.org/images/pacsoc-s1b.png)">