Landscape and portrait pages in the same word docu

2020-05-07 06:08发布

I am trying to use Java and the Apache POI library to create a word document that contained some landscape and some portrait pages. I can change the orientation of all the pages, but is there a way to change just the orientation of some of them? I have tried using different sections and bodies, but to no avail.

At the moment I have written a function that takes a XWPFDocument as input and changes the orientation of a new body. I had hoped changing the orientation for new body would not affect the previous pages, but it affects the entire document.

private void changeOrientation(XWPFDocument document, String orientation){
    CTDocument1 doc = document.getDocument();
    CTBody body = doc.addNewBody();
    body.addNewSectPr();
    CTSectPr section = body.getSectPr();
    if(!section.isSetPgSz()) {
        section.addNewPgSz();
    }
    CTPageSz pageSize = section.getPgSz();
    if(orientation.equals("landscape")){
        pageSize.setOrient(STPageOrientation.LANDSCAPE);
        pageSize.setW(BigInteger.valueOf(842 * 20));
        pageSize.setH(BigInteger.valueOf(595 * 20));
    }
    else{
        pageSize.setOrient(STPageOrientation.PORTRAIT);
        pageSize.setH(BigInteger.valueOf(842 * 20));
        pageSize.setW(BigInteger.valueOf(595 * 20));
    }
}

Thanks!

2条回答
放我归山
2楼-- · 2020-05-07 06:31

According to OOXML Specification ECMA-376, Fourth Edition, Part 1 - Fundamentals And Markup Language Reference - 17.6.18 sectPr (Section Properties), in a document with multiple sections, section properties (the sectPr element) are stored as the child element of :

  • the last paragraph in the section, for all sections except the final section,
  • the body element, for the final section.

So, to change page orientation of a section one should create or locate corresponding sectPr and use following code:

private void changeOrientation(CTSectPr section, String orientation) {
    CTPageSz pageSize = section.isSetPgSz? section.getPgSz() : section.addNewPgSz();
    if (orientation.equals("landscape")) {
        pageSize.setOrient(STPageOrientation.LANDSCAPE);
        pageSize.setW(BigInteger.valueOf(842 * 20));
        pageSize.setH(BigInteger.valueOf(595 * 20));
    } else {
        pageSize.setOrient(STPageOrientation.PORTRAIT);
        pageSize.setH(BigInteger.valueOf(842 * 20));
        pageSize.setW(BigInteger.valueOf(595 * 20));
    }
}
查看更多
神经病院院长
3楼-- · 2020-05-07 06:38

Turns out a CTPPr (a section break) is needed, which can be done with the following code:

private void changeOrientation(XWPFDocument document, String orientation){
    CTDocument1 doc = document.getDocument();
    CTBody body = doc.getBody();
    CTSectPr section = body.addNewSectPr();
    XWPFParagraph para = document.createParagraph();
    CTP ctp = para.getCTP();
    CTPPr br = ctp.addNewPPr();
    br.setSectPr(section);
    CTPageSz pageSize = section.getPgSz();
    if(orientation.equals("landscape")){
        pageSize.setOrient(STPageOrientation.LANDSCAPE);
        pageSize.setW(BigInteger.valueOf(842 * 20));
        pageSize.setH(BigInteger.valueOf(595 * 20));
    }
    else{
        pageSize.setOrient(STPageOrientation.PORTRAIT);
        pageSize.setH(BigInteger.valueOf(842 * 20));
        pageSize.setW(BigInteger.valueOf(595 * 20));
    }
}

However, this only works once, so pages can't alternate orientations. It has to be all the landscape pages first and portrait last or vice versa.

查看更多
登录 后发表回答