使用 apache poi 转换时如何更改边距 [英] How to change margins when converting with apache poi

查看:34
本文介绍了使用 apache poi 转换时如何更改边距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从 Microsoft Word 文档转换时,我需要更改 PDF 文件的边距.

I need to change the margin of the PDF file when I convert from Microsoft Word document.

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 即可工作.

Without converting to PDF, it works.

推荐答案

解决方案:

调整与 sectPrpgMar 相关的代码部分,不添加新部分,而是重用它们:

Solution:

Adjust code part related to sectPr and pgMar to not add new sections, but reuse them:

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 条目文档.


Explanation:

Reason of the issue is that XDocReport converter (which is a separate project from Apache POI) handles only the first sectPr entry of the document.

您的示例将在下面生成WordprocessingML >>:

Your sample will generate WordprocessingML >> below:

<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 的一部分.

Which during conversion to PDF will be handled in the way second pgmar (<w:pgMar w:bottom="620" w:left="620" w:right="620" w:top="620"/>) will be ignored, since it is part of the second sectPr.

同时将调整后的文档保存到新的Word文档pgMars将被合并,您将看到所需的结果(调整后的边距),新的WordprocessingML 看起来是这样:

Same time in case of saving adjusted document to a new Word document pgMars will be merged and you will see needed result (adjusted margin), new WordprocessingML will look so:

<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 将根据需要工作.


Code sample from the Solution section will generate single sectPr with single pgMar so PDFConverter will work as needed.

还需要提到的是,XDocReport 提供了配置可能性>>:

Also need to mention that XDocReport provides configuration possibility >>:

options.setConfiguration(new IPdfWriterConfiguration() {
    public void configure(PdfWriter writer) {
        writer.setPDFXConformance(PdfWriter.PDFA1A);
    }
});

但不幸的是,无法以这种方式处理边距(无论如何,docx 文档中的边距值也会在配置完成后覆盖它们).

But unfortunately it is not possible to handle margins this way (also margin values from the docx document will overwrite them after configuration will be done anyway).

另外下面是使用的pom.xml依赖项:

Additionally below is pom.xml dependencies used:

<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>

这篇关于使用 apache poi 转换时如何更改边距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆