itext生成pdf文件demo示例

需求

在PDF文件中植入一些信息(pdf模版)

制作模版

可以看到下面红色箭头标注位置,这都是我们需要动态写入数据的表单域,可以使用wps等工具来制作

点击编辑表单,可以给对应空间添加表单域,表单域名称是key,在后续我们填充数据时以此来映射

实战

pdf编辑好以后我们就可以开始编写代码了,首先添加Maven坐标

java 复制代码
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

添加pdf处理工具类

java 复制代码
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.List;

import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;

/**
 * pdf电子合同工具
 */
public class PdfUtil {

    /**
     * 根据PDF模版生成PDF文件
     *
     * @param templateFilePath
     *            PDF模版文件路径
     * @param data
     *            表单数据
     * @param imageData
     *            图片数据 VALUE为图片文件路径
     * @param formFlattening
     *            false:生成后的PDF文件表单域仍然可编辑 true:生成后的PDF文件表单域不可编辑
     * @param pdfFilePath
     *            生成PDF的文件路径
     */
    public static void createPdf(String templateFilePath, HashMap<String, String> data,
        HashMap<String, String> imageData, boolean formFlattening, String pdfFilePath) throws Exception {
        PdfReader reader = null;
        ByteArrayOutputStream bos = null;
        PdfStamper pdfStamper = null;
        FileOutputStream fos = null;
        try {
            // 读取PDF模版文件
            reader = new PdfReader(templateFilePath);
            // 输出流
            bos = new ByteArrayOutputStream();
            // 构建PDF对象
            pdfStamper = new PdfStamper(reader, bos);

            // 获取表单数据
            AcroFields form = pdfStamper.getAcroFields();

            // 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体 Adobe 宋体 std L
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(bfChinese);

            // 表单赋值
            for (String key : data.keySet()) {
                form.setField(key, data.get(key), true);
                // 也可以指定字体
                form.setFieldProperty(key, "textfont", bfChinese, null);
            }

            // 添加图片
            if (null != imageData && imageData.size() > 0) {
                for (String key : imageData.keySet()) {
                    List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(key);
                    int pageNo = fieldPositions.get(0).page;
                    Rectangle signRect = form.getFieldPositions(key).get(0).position;
                    float x = signRect.getLeft();
                    float y = signRect.getBottom();
                    // 读图片
                    Image image = Image.getInstance(imageData.get(key));
                    // 获取操作的页面
                    PdfContentByte under = pdfStamper.getOverContent(pageNo);
                    // 根据域的大小缩放图片
                    image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                    // 添加图片
                    image.setAbsolutePosition(x, y);
                    under.addImage(image);
                }
            }

            // 如果为false那么生成的PDF文件还能编辑,一定要设为true
            pdfStamper.setFormFlattening(formFlattening);
            pdfStamper.close();

            // 保存文件
            fos = new FileOutputStream(pdfFilePath);
            fos.write(bos.toByteArray());
            fos.flush();
        } finally {
            if (null != fos) {
                try {
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (null != bos) {
                try {
                    bos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (null != reader) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
java 复制代码
public static void main(String[] args) throws Exception {
    HashMap<String, String> data = new HashMap<>();
    data.put("busLicenseName", "李四便利店");
    data.put("provinceName", "李四");
    data.put("cityName", "深圳");
    data.put("areaName", "南山区");
    data.put("address", "科兴科技园");
    data.put("busLicenseNum", "XXXXXXX");
    // busLicense 为多选框
    data.put("busLicense", "Yes");
    data.put("cardName", "李四");
    data.put("phone", "手机");
    data.put("mailbox", "123465798@qq.com");

    data.put("crpExpY", "2028");
    data.put("crpExpM", "06");
    data.put("crpExpD", "10");

    data.put("idCardNo", "李四身份证");
    data.put("now", DateUtil.format(new Date(), DatePattern.CHINESE_DATE_PATTERN));

    // HashMap<String, String> data = new HashMap<>();
    HashMap<String, String> imageData = new HashMap<>();
    // 在线签名网址:https://tools.kalvinbg.cn/txt/sign
    imageData.put("signPic", "C:\\Users\\XXXX\\Downloads\\Kalvin在线工具签名.png");
    String templateFilePath = "C:\\Users\\XXXX\\Downloads\\测试pdf.pdf";
    String pdfFilePath = "C:\\Users\\XXXX\\Downloads\\new_" + "xxxx" + ".pdf";
    File file = new File(pdfFilePath);

    // 根据PDF模版生成PDF文件
    PdfUtil.createPdf(templateFilePath, data, imageData, true, pdfFilePath);
}

最终生成如下,这里有用到文本域、多选按钮、签名植入,下面圈出多选框以及签名图片,文字大小样式可在制作pdf模版时指定

相关推荐
reasonsummer5 小时前
【办公类-53-12】20261016(预测)Python模仿制作2026学年第二学期校历(excel+pdf,上下学期都包含)
pdf·excel
开开心心就好9 小时前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
开开心心就好10 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
BD_Marathon14 小时前
PyPDFLoader和MinerU加载pdf文件
pdf
ydjs678899-bot2 天前
如何在Java中打印pdf静默打印和打印对话框选择
java·python·pdf
SamChan902 天前
PDF 翻译后 1,250 变成 1.250,是错了吗?用 Python 核对数字格式
python·pdf·ocr·数据校验·文档翻译
开开心心就好2 天前
打印机卡住打不了?一键清理卡死打印队列
服务器·开发语言·算法·pdf·ocr·idea·visual studio code
打工仔折腾 AI3 天前
在线PDF工具隐私焦虑?把BentoPDF部署到极空间NAS本地处理
人工智能·后端·python·pdf·ai agent 实战
霸道流氓气质3 天前
AI 简历制作平台:结构化输出解析、多模板渲染与 PDF 导出的 Vue3 + Spring AI 全栈实战
人工智能·spring·pdf
开开心心_Every3 天前
黄金价格软件国内外价格实时监控超方便
运维·服务器·游戏·智能手机·pdf·lua·perl