在 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 元素,用于最后一节。
您可以使用 CTPPr
的 addNewSectPr
方法为其添加 CTSectPr
。
CTBody
末尾有一个 CTSectPr
。您可以使用 getSectPr
方法获取它。
我曾尝试在 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 元素,用于最后一节。
您可以使用 CTPPr
的 addNewSectPr
方法为其添加 CTSectPr
。
CTBody
末尾有一个 CTSectPr
。您可以使用 getSectPr
方法获取它。