0

I am creating reports using docx4j and docx stamper

(https://github.com/thombergs/docx-stamper)

I have a main docx, which contains my TOC and Logo and page numbering set to it. Then I start filling other docx layouts using docx stamper and then add them to the end of the main part. The problem is that if I set page orientation in one docx layout as landscape after adding it to the main part it loses the orientation. The result contains both parts and the correct page numbering. All Styles are kept but the first and third part which have the landscape orientation are shown as portrait as in the main document.

documentPartBase = wordMLPackageBase.getMainDocumentPart();
WordprocessingMLPackage wordMLPackageOne = fillFirstTemplate.fillTempLe();
    for (Object obj : wordMLPackageOne.getMainDocumentPart().getContent()) {
        documentPartBase.addObject(obj);
    }
    documentPartBase.addObject(pageBreak);
  WordprocessingMLPackage wordMLPackageTwo = fillSecTemplate.fillTempLe();
    for (Object obj : wordMLPackageTwo.getMainDocumentPart().getContent()) {
        documentPartBase.addObject(obj);
    }
    documentPartBase.addObject(pageBreak);
 WordprocessingMLPackage wordMLPackageThree = fillThirdTemplate.fillTempLe();
    for (Object obj : wordMLPackageThree.getMainDocumentPart().getContent()) {
        documentPartBase.addObject(obj);
    }
    documentPartBase.addObject(pageBreak);
    wordMLPackageBase.save(new File(Paths.get(".").getFileSystem().getPath("D:").toString(), resultFileName))

I tried adding a landscape package before adding a part to the main but it did not help:

WordprocessingMLPackage aPackage;
    try {
        aPackage = createPackage(PageSizePaper.A4, true);
    } catch (InvalidFormatException e) {
        throw new RuntimeException("Unhandled exception occurred.", e);
    }
    for (Object obj :aPackage.getMainDocumentPart().getContent()){
        documentPartBase.addObject(obj);
    }
WordprocessingMLPackage wordMLPackageThree = fillThirdTemplate.fillTempLe();
    for (Object obj : wordMLPackageThree.getMainDocumentPart().getContent()) {
        documentPartBase.addObject(obj);
    }

And also tried adding:

try {
        sectPr = (SectPr) XmlUtils.unmarshalString("<w:sectPr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
            + "<w:pgSz w:w=\"16839\" w:h=\"11907\" w:orient=\"landscape\"/>"
            + "</w:sectPr>");
    } catch (JAXBException e) {
        throw new RuntimeException("Unhandled exception occurred.", e);
    }
    wordMLPackageThree.getMainDocumentPart().getContent().add(sectPr);

Adding the folowing method according to

Change the page orientation in middle of doc

like the code bellow made the whole doc appears as landscape!

    makeLandscape(wordMLPackageThree.getMainDocumentPart(), STPageOrientation.LANDSCAPE);
            for (Object obj : wordMLPackageThree.getMainDocumentPart().getContent()) 
{
        //Properties properties = Docx4jProperties.getProperties();
        //properties.setProperty("docx4j.PageOrientationLandscape", "true");
        documentPartBase.addObject(obj);
}
        private void makeLandscape(MainDocumentPart mdp, STPageOrientation stPageOrientation) 
    {
          ObjectFactory objectFactory = new ObjectFactory();
          SectPr sectionLandscape = objectFactory.createSectPr();
          SectPr.PgSz landscape = new SectPr.PgSz();
          landscape.setOrient(stPageOrientation);
          landscape.setH(BigInteger.valueOf(11906));
          landscape.setW(BigInteger.valueOf(16383));
          sectionLandscape.setPgSz(landscape);
          org.docx4j.wml.P p = objectFactory.createP();
          PPr createPPr = objectFactory.createPPr();
          createPPr.setSectPr(sectionLandscape);
          p.setPPr(createPPr);
          mdp.addObject(p);
    }

I tried as said in the first comment but whole document was Landscape and an empty portrait page was added to the end:

makeLandscape(documentPartBase,STPageOrientation.LANDSCAPE);
    WordprocessingMLPackage wordMLPackageThree= fillFunktionenLe.fillFunktionenLe();
    for (Object obj : wordMLPackageThree.getMainDocumentPart().getContent()) {
            documentPartBase.addObject(obj);
        }
    makeLandscape(documentPartBase,STPageOrientation.PORTRAIT);

which did not help either.

How can I keep page orientation using docx4j after appending contents together?

Iman
  • 769
  • 1
  • 13
  • 51
  • Adding a sectPr element after the content you want in landscape is what you need to do. This implies that unless page 1 is landscape, you'll also need to add a sectPr before the landscape content (ie specifying you want portrait content). – JasonPlutext Oct 05 '18 at 08:55
  • I tried changing the orientation before and after the third part, but it just made my footer disappear! – Iman Oct 08 '18 at 07:37
  • Well, you'll need to understand how footers work in sectPr. If its all too hard, the MergeDocx component in Plutext's commercial Docx4j Enterprise might help: https://www.plutext.com/m/index.php/products – JasonPlutext Oct 08 '18 at 22:33

1 Answers1

0

I added a section break as continues in the first layout.docx in the TOC. Then in the layout which is to be appear as landscape I sat a section break before the content as portrait and sat the other page to landscape, then added another section break as portrait after that. finally I merged the filled layouts as explained here, modifying it a bit to get a list of layouts:

//the mainDocIn is an empty docx. All other layout are merged there afther filling
    void mergeDocx(OutputStream out, InputStream mainDocIn, InputStream... chaptersIn) {
    try {
        WordprocessingMLPackage mainDoc = WordprocessingMLPackage.load(mainDocIn);

        for (int i = 0; i < chaptersIn.length; i++) {
            insertDocx(mainDoc.getMainDocumentPart(), 
            IOUtils.toByteArray(chaptersIn[i]), i);
        }
        mainDoc.save(out);
    } catch (IOException | Docx4JException e) {
        logger.error("Error in merging", e);
    }
}

private static void insertDocx(MainDocumentPart main, byte[] bytes, int chunkIndex) {
    try {
        AlternativeFormatInputPart afiPart = new 
        AlternativeFormatInputPart(new PartName("/part" + (chunkIndex) + ".docx"));
        afiPart.setContentType(new ContentType(CONTENT_TYPE));
        afiPart.setBinaryData(bytes);
        Relationship altChunkRel = main.addTargetPart(afiPart);

        CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
        chunk.setId(altChunkRel.getId());

        main.addObject(chunk);
    } catch (InvalidFormatException e) {
        logger.error("Data format wrong!", e);
    }
}
Iman
  • 769
  • 1
  • 13
  • 51