为了账号安全,请及时绑定邮箱和手机立即绑定

使用 apache poi 转换时如何更改边距

使用 apache poi 转换时如何更改边距

皈依舞 2021-10-06 12:52:34
当我从 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,它就可以工作。
查看完整描述

1 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

解决方案:

调整相关代码的一部分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 的过程中,它将以 second pgmar( <w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>) 被忽略的方式处理,因为它是 second 的一部分sectPr。


同时在将调整后的文档保存到新的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提供了配置可能性 >>:


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>


查看完整回答
反对 回复 2021-10-06
  • 1 回答
  • 0 关注
  • 295 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信