Itext7使用详解——操作PDF

939 阅读3分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

在上一篇中讲述了一些基础的操作以及如何解决中文不显示的问题:# Itext7使用详解

接下来就是一些对pdf的操作,比如合并,拆分,翻转等等。Itext还支持HTMl2PDF,将html页面转换成pdf,但是存在较多的限制,只适用于一些简单的页面转换,而且在前后端分离的模式下有些问题不知道怎么解决,比如说前端怎么把html的全部相关信息传递给后端。

1.PDF的拆分

按自定义大小等分PDF

PdfSplitter就是用于操作PDF拆分的类,具体的依赖在上一篇中讲到了,PdfSplitter接受一个pdfDocument对象然后在内部重写getNextPdfWriter方法进行PDF的命名。

@PostMapping("/PDFSplitter1")
public String PDFSplitter1() throws IOException {
    final String ORIG = "PATH/xxxx.pdf";

    final int maxPageCount = 5; // create a new PDF per maxPageCount pages from the original file
    PdfDocument pdfDocument = new PdfDocument(new PdfReader(new File(ORIG)));
    PdfSplitter pdfSplitter = new PdfSplitter(pdfDocument) {
        int partNumber = 1;

        @Override
        protected PdfWriter getNextPdfWriter(PageRange documentPageRange) {
            try {
                return new PdfWriter(PATH + "/splitDocument_" + partNumber++ + ".pdf");
            } catch (final FileNotFoundException ignored) {
                throw new RuntimeException();
            }
        }
    };
    //官方给出的示例,第二个参数是当另一个文档准备就绪时调用的事件侦听器。例如,可以在此侦听器中关闭此文档。
    pdfSplitter.splitByPageCount(maxPageCount, (pdfDoc, pageRange) -> pdfDoc.close());
    pdfDocument.close();
    return "success";
}

这种方式拆分的PDF是根据我们定义的maxPageCount来决定每一份PDF的大小的,比如一个十页的PDF,按maxPageCount=3进行拆分,最后得到四个PDF,最后一个PDF只有一页,还有一种可以自定义选取片段大小的方式。

自定义选取片段大小的pdf

我的自定义选取片段大小其实是通过copyPagesTo这个方法复制需要的片段出来生成一个新的PDF达到拆分的目的,也可以通过删除特定的页面达到自己的需求:

pdfDocument.removePage(1);//需要删除的页码

copyPagesTo的用法如下:

@PostMapping("/PDFSplitter2")
public String PDFSplitter2() throws IOException {
    final String ORIG = "PATH/XXXXX.pdf";
    //源文档
    PdfReader pdfReader = new PdfReader(ORIG);
    PdfDocument pdf = new PdfDocument(pdfReader);
    //生成目标文档
    PdfWriter pdfWriter = new PdfWriter(PATH + "/splitedDocument" + ".pdf");
    PdfDocument outPdfDocument = new PdfDocument(pdfWriter);
    //从页数第一页开始,
    pdf.copyPagesTo(2, 3, outPdfDocument);
    //关闭
    outPdfDocument.close();
    pdfWriter.close();
    pdf.close();
    pdfReader.close();
    return "success";
}

2.PDF合并

在需要将两个PDF进行拼接的时候可以用到PdfMerger这个对象进行PDF之间的拼接:

@PostMapping("/PdfMerge")
public String PdfMerge() throws IOException {
    final String FILE1 = "要合并的文件1路径";
    final String FILE2 = "要合并的文件2路径";
    PdfDocument pdfDocument = new PdfDocument(new PdfReader(FILE1), new PdfWriter(PATH + "/merged.pdf"));
    PdfDocument pdfDocument2 = new PdfDocument(new PdfReader(FILE2));
    //要生成的文件
    PdfMerger merger = new PdfMerger(pdfDocument);
    //要合并的文件,第二个参数是起始页,第三个参数是结束页,我这样写就是全部合并,也可以选择合并一部分
    merger.merge(pdfDocument2, 1, pdfDocument2.getNumberOfPages());
    pdfDocument2.close();
    pdfDocument.close();
    return "success";
}

在拼接的时候将要放在前面的PDF作为参数传给PdfMerger,然后把要放在后面的PDF进行合并,合并的时候可以选择需要的片段进行合并。

3.PDF旋转

有时候PDF生成的时候角度不对的话可以用setRotation方法调整页面角度,可以设置要调整的角度,也可以选择要调整的具体页码:

@PostMapping("/PDFRotator")
public String PDFRotator() throws IOException {
    final int ROTATION_DEGREES = 90; //顺时针旋转角度
    final String ORIG = "PATh/XXXX.pdf";

    PdfDocument pdfDocument = new PdfDocument(new PdfReader(ORIG), new PdfWriter(PATH + "/Rotated.pdf"));

    for (int p = 1; p <= pdfDocument.getNumberOfPages(); p++) {
        PdfPage page = pdfDocument.getPage(p);
        int rotate = page.getRotation();
        if (rotate == 0) {
            page.setRotation(ROTATION_DEGREES);
        } else {
            page.setRotation((rotate + ROTATION_DEGREES) % 360);
        }
    }

    pdfDocument.close();
    return "success";
}