使用 apache poi 转换时如何更改边距
How to change margins when converting with apache poi
当我从 Microsoft Word 文档转换时,我需要更改 PDF 文件的边距。
public class TestCon {
public static final String DEST = "./test.pdf";
public static final String SRC = "./test.docx";
public static void main(String[] args) {
try {
InputStream doc = new FileInputStream(new File(SRC));
XWPFDocument document = new XWPFDocument(doc );
CTSectPr addNewSectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar addNewPgMar = addNewSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
OutputStream out = new FileOutputStream(new File(DEST));
PdfOptions options = PdfOptions.create();
PdfConverter.getInstance().convert(document, out, options);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
这行不通。 pdf
中边距不变
但是当我这样做时:
FileOutputStream out = new FileOutputStream(new File(SRC1));
InputStream doc = new FileInputStream(new File(SRC));
XWPFDocument document = new XWPFDocument(doc );
CTSectPr addNewSectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar addNewPgMar = addNewSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
document.write(out);
out.close();
无需转换为 PDF,也可以。
解决方案:
将与sectPr
和pgMar
相关的代码部分调整为不添加新部分,而是重复使用它们:
CTSectPr getSectPr = document.getDocument().getBody().getSectPr();
getSectPr.unsetPgMar();
CTPageMar addNewPgMar = getSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
// Also good to handle footer and header for more expectable result
addNewPgMar.setFooter(BigInteger.valueOf(0L));
addNewPgMar.setHeader(BigInteger.valueOf(0L));
解释:
问题的原因是 XDocReport 转换器(它是 Apache POI 的一个单独项目)仅处理第一个 sectPr
文档条目。
您的示例将在下面生成 WordprocessingML >>:
<w:sectPr w:rsidR="003F19CD" w:rsidRPr="005E1322">
<w:pgSz w:h="16838" w:w="11906"/>
<w:pgMar w:bottom="1134" w:footer="708" w:header="708" w:left="1701" w:right="850" w:top="1134"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
<w:sectPr>
<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
</w:sectPr>
在转换为 PDF 期间将以第二个方式处理的 pgmar
(<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
) 将被忽略,因为它是第二个 sectPr
.[=29= 的一部分]
同时将调整后的文档保存到新的 Word 文档 pgMar
s 将被合并,您将看到所需的结果(调整后的边距),新 WordprocessingML 看起来是这样的:
<w:sectPr w:rsidR="003F19CD" w:rsidRPr="005E1322">
<w:pgSz w:h="16838" w:w="11906"/>
<w:pgMar w:left="620" w:top="620" w:right="620" w:bottom="620" w:footer="0" w:header="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
<w:sectPr>
<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
</w:sectPr>
来自 解决方案 部分的代码示例将生成单个 sectPr
和单个 pgMar
,因此 PDFConverter
将根据需要工作。
附加信息:
还需要提到的是 XDocReport 提供 configuration possibility >>:
options.setConfiguration(new IPdfWriterConfiguration() {
public void configure(PdfWriter writer) {
writer.setPDFXConformance(PdfWriter.PDFA1A);
}
});
但不幸的是,不可能以这种方式处理边距(docx
文档中的边距值也会在配置完成后覆盖它们)。
另外下面是 pom.xml
使用的依赖项:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
<version>2.0.1</version>
</dependency>
当我从 Microsoft Word 文档转换时,我需要更改 PDF 文件的边距。
public class TestCon {
public static final String DEST = "./test.pdf";
public static final String SRC = "./test.docx";
public static void main(String[] args) {
try {
InputStream doc = new FileInputStream(new File(SRC));
XWPFDocument document = new XWPFDocument(doc );
CTSectPr addNewSectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar addNewPgMar = addNewSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
OutputStream out = new FileOutputStream(new File(DEST));
PdfOptions options = PdfOptions.create();
PdfConverter.getInstance().convert(document, out, options);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
这行不通。 pdf
中边距不变但是当我这样做时:
FileOutputStream out = new FileOutputStream(new File(SRC1));
InputStream doc = new FileInputStream(new File(SRC));
XWPFDocument document = new XWPFDocument(doc );
CTSectPr addNewSectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar addNewPgMar = addNewSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
document.write(out);
out.close();
无需转换为 PDF,也可以。
解决方案:
将与sectPr
和pgMar
相关的代码部分调整为不添加新部分,而是重复使用它们:
CTSectPr getSectPr = document.getDocument().getBody().getSectPr();
getSectPr.unsetPgMar();
CTPageMar addNewPgMar = getSectPr.addNewPgMar();
addNewPgMar.setLeft(BigInteger.valueOf(720L));
addNewPgMar.setTop(BigInteger.valueOf(720L));
addNewPgMar.setRight(BigInteger.valueOf(720L));
addNewPgMar.setBottom(BigInteger.valueOf(720L));
// Also good to handle footer and header for more expectable result
addNewPgMar.setFooter(BigInteger.valueOf(0L));
addNewPgMar.setHeader(BigInteger.valueOf(0L));
解释:
问题的原因是 XDocReport 转换器(它是 Apache POI 的一个单独项目)仅处理第一个 sectPr
文档条目。
您的示例将在下面生成 WordprocessingML >>:
<w:sectPr w:rsidR="003F19CD" w:rsidRPr="005E1322">
<w:pgSz w:h="16838" w:w="11906"/>
<w:pgMar w:bottom="1134" w:footer="708" w:header="708" w:left="1701" w:right="850" w:top="1134"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
<w:sectPr>
<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
</w:sectPr>
在转换为 PDF 期间将以第二个方式处理的 pgmar
(<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
) 将被忽略,因为它是第二个 sectPr
.[=29= 的一部分]
同时将调整后的文档保存到新的 Word 文档 pgMar
s 将被合并,您将看到所需的结果(调整后的边距),新 WordprocessingML 看起来是这样的:
<w:sectPr w:rsidR="003F19CD" w:rsidRPr="005E1322">
<w:pgSz w:h="16838" w:w="11906"/>
<w:pgMar w:left="620" w:top="620" w:right="620" w:bottom="620" w:footer="0" w:header="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="360"/>
</w:sectPr>
<w:sectPr>
<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>
</w:sectPr>
来自 解决方案 部分的代码示例将生成单个 sectPr
和单个 pgMar
,因此 PDFConverter
将根据需要工作。
附加信息:
还需要提到的是 XDocReport 提供 configuration possibility >>:
options.setConfiguration(new IPdfWriterConfiguration() {
public void configure(PdfWriter writer) {
writer.setPDFXConformance(PdfWriter.PDFA1A);
}
});
但不幸的是,不可能以这种方式处理边距(docx
文档中的边距值也会在配置完成后覆盖它们)。
另外下面是 pom.xml
使用的依赖项:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
<version>2.0.1</version>
</dependency>