How to change margins when converting with apache poi

假装没事ソ 提交于 2019-12-08 10:38:22

问题


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();
        }
    }
}

This does not work. The margin does not change in pdf


But when I do this:

        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();

Without converting to PDF, it works.


回答1:


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

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.

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>

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.

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>

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


Additional information:

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

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

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


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>


来源:https://stackoverflow.com/questions/52466352/how-to-change-margins-when-converting-with-apache-poi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!