Bootstrap

itext 7使用笔记

一、前言

iText 采用APGL许可协议,个人或开源项目免费,商用版本收取授权费。

名称点击次数描述
iText6353iText是一个能够快速产生PDF文件的java类库。iText的java类对于那些要产生包含文本,表格,图形的只读文档是很有用的。它的类库尤其与java Servlet有很好的给合。使用iText与PDF能够使你正确的控制Servlet的输出。
PDF Box1958PDFBox是一个Apache开源的x项目。可以操作PDF文档的Java PDF类库。它可以创建一个新PDF文档,操作现有PDF文档并提取文档中的内容。
JFreeReport2146JFreeReport的数据继承自Swing组件的TableModel接口。JFreeReport生成的报表可以分页预览、打印或者保存为多种格式的文件包括pdf、Excel、html等。
PJX1214PJX支持读取,组合,处理,和生成PDF文档(注意:PJX需要 J2SE 1.4.0 或更高版本)。
FOP912FOP是由James Tauber发起的一个开源项目,原先的版本是利用xsl-fo将xml文件转换成pdf文件。但最新的版本它可以将xml文件转换成pdf,mif,pcl,txt等多种格式以及直接输出到打印机,并且支持使用SVG描述图形
gnujpdf782gnujpdf是一个java类包(gnu.jpdf.*),它提供了一个简单的API来创建与打印PDF文件。遵循LGPL开源协议
Connla986Connla是一个Java包用于创建可导成TXT,CSV,HTML,XHTML,XML,PDF和XLS等格式的数据集。

二、使用

1.pom.xml

注意不同意itext7版本对字体的处理结果不一样,可能会出现部分字体无法显示问题

      <dependency>
          <groupId>com.itextpdf</groupId>
          <artifactId>itext7-core</artifactId>
          <version>7.1.0</version>
          <type>pom</type>
      </dependency>

2.pdf模板编辑

可使用PDF编辑软件如福昕、万兴PDF(推荐)、Adobe Acrobat Pro编辑器,增加表单域

3.工具类

  • 文本读取
    /**
     * 读取PDF文本内容
     * 
     * @param inputStream 文件输入流
     * @return 文本
     * @throws IOException 
     */
    public static String extractText(InputStream inputStream) throws IOException {
        StringBuilder sb = new StringBuilder();
        PdfDocument pdf = new PdfDocument(new PdfReader(inputStream));
        int pages = pdf.getNumberOfPages();
        for (int i = 1; i <= pages; i++) {
            String textFromPage = PdfTextExtractor.getTextFromPage(pdf.getPage(i));
            sb.append(textFromPage);
            sb.append("\n");
        }
        pdf.close();
        return sb.toString();
    }
  • 图片导出
package com.iflytek.voicecloud.iflyrecruit;

import com.itextpdf.kernel.pdf.canvas.parser.EventType;
import com.itextpdf.kernel.pdf.canvas.parser.data.IEventData;
import com.itextpdf.kernel.pdf.canvas.parser.data.ImageRenderInfo;
import com.itextpdf.kernel.pdf.canvas.parser.listener.IEventListener;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

public class ImageRenderListener implements IEventListener {

    private final String savePath;

    public ImageRenderListener(String savePath) {
        this.savePath = savePath;
    }

    @Override
    public void eventOccurred(IEventData data, EventType type) {
        if (data instanceof ImageRenderInfo) {
            ImageRenderInfo imageRenderInfo = (ImageRenderInfo) data;
            PdfImageXObject pdfImageXObject = imageRenderInfo.getImage();
            if (Objects.nonNull(pdfImageXObject)) {
                String fileFullPath = savePath + File.separator + UUID.randomUUID() + "." + pdfImageXObject.identifyImageFileExtension();
                try (FileOutputStream outputStream = new FileOutputStream(fileFullPath)) {
                    outputStream.write(pdfImageXObject.getImageBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    @Override
    public Set<EventType> getSupportedEvents() {
        return Collections.singleton(EventType.RENDER_IMAGE);
    }
}

    /**
     * 读取PDF中的图片
     *
     * @param inputStream 文件输入流
     * @return 图片
     * @throws IOException
     */
    public static void exportImage(InputStream inputStream, String savePath) throws IOException {
        PdfCanvasProcessor pdfCanvasProcessor = new PdfCanvasProcessor(new ImageRenderListener(savePath));
        PdfDocument pdf = new PdfDocument(new PdfReader(inputStream));
        int pages = pdf.getNumberOfPages();
        for (int i = 1; i <= pages; i++) {
            pdfCanvasProcessor.processPageContent(pdf.getPage(i));
        }
        pdf.close();
    }
  • 填充变量(”抠模板“)
    /**
     * 填充变量
     *
     * @param inputStream  输入流
     * @param outputStream 输出流
     * @param variables    变量
     */
    public static void fillVariables(InputStream inputStream, OutputStream outputStream, Map<String, String> variables) throws IOException {
        PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", true);
        PdfDocument pdf = new PdfDocument(new PdfReader(inputStream), new PdfWriter(outputStream));

        // 表单域
        PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
        Map<String, PdfFormField> fields = form.getFormFields();
        String keys = String.join(",", fields.keySet());
        LOGGER.debug("表单域字段列表=>{}", keys);

        // 变量替换
        for (Map.Entry<String, String> entry : variables.entrySet()) {
            PdfFormField pdfFormField = fields.get(entry.getKey());
            if (Objects.nonNull(pdfFormField)) {
                pdfFormField.setFont(font).setValue(entry.getValue());
            }
        }
        // 冻结表单窗格
        form.flattenFields();
        pdf.close();
    }

参考:

pdfReader 解析pdf(ItextPdf)

ITEXT7表单域处理(文字和图片)及添加水印

使用iText 7读取PDF文件中的文本和图片

为何选择iText?java PDF开源库选择与iText发展历史

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;