根据PDF模版填充数据并生成新的PDF

准备模版

  1. 使用 福昕高级PDF编辑器(本人用的这个,其他的也行,能作模版就行)
  2. 打开PDF文件点击 表单 选项,点击 文本域
  3. 在需要填充数据的位置设计文本域
  4. 设置 名称、提示
  5. 名称相当于 属性名,提示就是提示,说明这个是什么

导入依赖

XML 复制代码
        <!--itext-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.13</version>
        </dependency>

函数编写

generatePdf

放 ServiceIMpl 里就行,这个是直接浏览器下载生成后的附件

java 复制代码
    private final HttpServletResponse response;

    public PdfServiceImpl(HttpServletResponse response) {
        this.response = response;
    }
public void generatePdf(Map<String, String> params) {
        // 读取资源文件夹下的模板
        ClassPathResource resource = new ClassPathResource("pdf-template/文件.pdf");
        InputStream inputStream = resource.getInputStream();

        PdfReader reader = null;
        ByteArrayOutputStream bos = null;
        try {
            reader = new PdfReader(inputStream);
            bos = new ByteArrayOutputStream();
            PdfStamper pdfStamper = new PdfStamper(reader, bos);
            AcroFields acroFields = pdfStamper.getAcroFields();

            // 字体设置
            BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

            for (Map.Entry<String, String> param : params.entrySet()) {
                // 设置文本域的字体为中文字体
                acroFields.setFieldProperty(param.getKey(), "textFont", font, null);
                // 将 map 中的值写到 pdf 模板对应的文本域中
                acroFields.setField(param.getKey(), param.getValue());
            }

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

            // 返回文件
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(bos.toByteArray());
            ServletUtils.writeAttachment(response, "新文件.pdf", bos.toByteArray());
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        } finally {
            try {
                assert bos != null;
                bos.close();
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

工具类

ServletUtils

java 复制代码
import cn.hutool.core.io.IoUtil;
import org.springframework.http.MediaType;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * @Package_Name com.lesliecheung.javacase.util.pdf
 * @Author Leslie Lee
 * @TIME
 * @Version
 */
public class ServletUtils {
    /**
     * 返回附件
     *
     * @param response 响应
     * @param filename 文件名
     * @param content  附件内容
     */
    public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
        // 设置 header 和 contentType
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        // 输出附件
        IoUtil.write(response.getOutputStream(), false, content);
    }
}

获取模版 inputStream流

从url下载文件

java 复制代码
            // 获取文件地址
            String urlPath = "模板资源文件链接-url";
            // 下载文件
            URL url = new URL(urlPath);
            URLConnection connection = url.openConnection();
            // 设置请求超时时长为 5 秒
            connection.setConnectTimeout(5*1000);
            // 读取数据
            InputStream inputStream = connection.getInputStream();

从某路径下直接取

java 复制代码
        String urlPath = "D:\\文件.pdf";
        File file1 = new File(urlPath);
        InputStream inputStream = new FileInputStream(file1);

新文件写入其他位置,操作 **bos.toByteArray()**就好了

java 复制代码
            File file = new File("D:/新文件.pdf");
            FileOutputStream fos = new FileOutputStream(file);
            BufferedOutputStream boss = new BufferedOutputStream(fos);
            boss.write(bos.toByteArray());

            fos.close();
            boss.close();
            System.out.println("成了");

Leslie Lee 随笔

相关推荐
夜之眷属14 小时前
Core dump 崩溃排查:JVM 宕机后,那份 core 文件怎么用 gdb 还原现场
java·运维·服务器·jvm
波加曼大王14 小时前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
SL_staff14 小时前
目标健康度自检清单:开发者视角下的目标-计划-任务链路断点诊断
java·开源·github
for_ever_love__14 小时前
MySQL 高频面试题 30 问:索引、事务、锁、日志、主从与分库分表(MySQL 8.0 版)
java·数据库·spring boot·mysql·spring cloud·面试·总结
神仙别闹14 小时前
基于C++实现的贪吃蛇游戏平台
java·c++·游戏
布吉岛的石头14 小时前
Java 程序员第 49 阶段11:Java 接 BERT:用 ONNX Runtime 做句向量推理
java·人工智能·python·深度学习·bert·transformer
niucloud-admin14 小时前
JAVA V6 多商户商城 开发文档——JAVA服务端
java·开发语言
SL_staff14 小时前
设备越多系统越崩?根源在三层抽象失效
spring boot·物联网·github
alexlifexyz14 小时前
写了个 Claude Code 插件:AI 写的 Java 违反阿里规约,就写不进文件
java
威哥爱编程14 小时前
【AI全栈12-01】Spring Boot 为何是 AI 全栈后端优选
java·spring boot·后端