在 Java 中使用 Apache POI XWPF 在 word 文档中切换 Landscape/portrait

Switching between Landscape/portrait in word document using Apache POI XWPF in Java

我曾尝试在 here 的帮助下在单个页面上设置页面方向,但没有成功。此代码片段生成一个文档,但它只将最后一页设置为横向。我不知道哪里出了问题...任何帮助或指导将不胜感激!

public static void main(String[] args) throws Exception {   
    XWPFDocument document = new XWPFDocument();   
    XWPFParagraph paragraph = document.createParagraph();   
    XWPFRun run = paragraph.createRun();   
    run.setText("FIRST PAGE");   

    changeOrientation(document, "landscape");
    paragraph = document.createParagraph();   
    run = paragraph.createRun();   
    run.setText("SECOND PAGE");

    changeOrientation(document, "portrait");
    paragraph = document.createParagraph();   
    run = paragraph.createRun();   
    run.setText("THIRD PAGE");

    changeOrientation(document, "landscape");
    paragraph = document.createParagraph();   
    run = paragraph.createRun();   
    run.setText("FOURTH PAGE");

    FileOutputStream fos = new FileOutputStream(new File("C:/test.docx"));   
    document.write(fos);   
    fos.close();   
}   

private static 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.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));
    }
}

编辑: 这给了我 document.xml(看起来不对):

<?xml version="1.0" encoding="UTF-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body>
<w:p><w:r><w:t>FIRST PAGE</w:t></w:r></w:p>
<w:p><w:pPr><w:sectPr/></w:pPr></w:p>
<w:p><w:r><w:t>SECOND PAGE</w:t></w:r></w:p>
<w:p><w:pPr><w:sectPr/></w:pPr></w:p>
<w:p><w:r><w:t>THIRD PAGE</w:t></w:r></w:p>
<w:p><w:pPr><w:sectPr/></w:pPr></w:p>
<w:p><w:r><w:t>FOURTH PAGE</w:t></w:r></w:p>
<w:sectPr><w:pgSz w:orient="landscape" w:w="16840" w:h="11900"/></w:sectPr>
<w:sectPr><w:pgSz w:orient="portrait" w:h="16840" w:w="11900"/></w:sectPr>
<w:sectPr><w:pgSz w:orient="landscape" w:w="16840" w:h="11900"/></w:sectPr>
</w:body></w:document>

编辑 2:这是 document.xml 使用 Word 创建时的样子(删除了一些不相关的内容...)。恐怕我在 POI 方面还不够好,不知道该怎么做才能让它像这样生成 xml:

<w:p w:rsidR="004E2FF4" w:rsidRDefault="004E2FF4"><w:pPr><w:sectPr w:rsidR="004E2FF4"><w:pgSz w:w="11906" w:h="16838"/></w:sectPr></w:pPr><w:r><w:t>FIRST PAGE</w:t></w:r></w:p>
<w:p w:rsidR="004E2FF4" w:rsidRDefault="004E2FF4"><w:pPr><w:sectPr w:rsidR="004E2FF4" w:rsidSect="004E2FF4"><w:pgSz w:w="16838" w:h="11906" w:orient="landscape"/></w:sectPr></w:pPr>
<w:r><w:lastRenderedPageBreak/><w:t>SECOND PAGE</w:t></w:r></w:p><w:p w:rsidR="004E2FF4" w:rsidRDefault="004E2FF4"><w:pPr><w:sectPr w:rsidR="004E2FF4"><w:pgSz w:w="11906" w:h="16838"/></w:sectPr></w:pPr>
<w:r><w:lastRenderedPageBreak/><w:t>THIRD PAGE</w:t></w:r></w:p><w:p w:rsidR="00D70BD0" w:rsidRDefault="004E2FF4">
<w:r><w:lastRenderedPageBreak/><w:t>FOURTH PAGE</w:t></w:r></w:p><w:sectPr w:rsidR="00D70BD0" w:rsidSect="004E2FF4"><w:pgSz w:w="16838" w:h="11906" w:orient="landscape"/></w:sectPr>

编辑 3: 感谢您的指导,但我仍然无法使其 100% 正常工作。我现在已将代码更改为以下内容。但这导致设置上一页方向而不是所需的方向。其余的都不正确。 Image that shows the resulting pages

private static void changeOrientation(XWPFDocument document, String orientation, boolean pFinalSection){
    CTSectPr section;
    if (pFinalSection) {
        CTDocument1 doc = document.getDocument();
        CTBody body = doc.getBody();
        section = body.getSectPr() != null ? body.getSectPr() : body.addNewSectPr();
        XWPFParagraph para = document.createParagraph();
        CTP ctp = para.getCTP();
        CTPPr br = ctp.addNewPPr();
        br.setSectPr(section);
    } else {
        XWPFParagraph para = document.createParagraph();
        CTP ctp = para.getCTP();
        CTPPr br = ctp.addNewPPr();
        section = br.addNewSectPr();
        br.setSectPr(section);
    }
    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));
    }
}

请检查我在 post Landscape and portrait pages in the same word document using Apache POI XWPF in Java.

中对相同问题的回答

根据 OOXML 规范 ECMA-376, Fourth Edition, Part 1 - Fundamentals And Markup Language Reference - 17.6.18 sectPr(节属性),在具有多个节的文档中,节属性(sectPr 元素)存储为 :[=18= 的子元素]

  • 该部分的最后一段,适用于除最后一段之外的所有部分 部分,
  • body 元素,用于最后一节。

您可以使用 CTPPraddNewSectPr 方法为其添加 CTSectPrCTBody 末尾有一个 CTSectPr。您可以使用 getSectPr 方法获取它。