根据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 随笔

相关推荐
程序员清风17 分钟前
小红书二面:Spring Boot的单例模式是如何实现的?
java·后端·面试
belhomme30 分钟前
(面试题)Redis实现 IP 维度滑动窗口限流实践
java·面试
Be_Better34 分钟前
学会与虚拟机对话---ASM
java
开源之眼3 小时前
《github star 加星 Taimili.com 艾米莉 》为什么Java里面,Service 层不直接返回 Result 对象?
java·后端·github
Maori3164 小时前
放弃 SDKMAN!在 Garuda Linux + Fish 环境下的优雅 Java 管理指南
java
用户908324602734 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
小王和八蛋4 小时前
DecimalFormat 与 BigDecimal
java·后端
beata5 小时前
Java基础-16:Java内置锁的四种状态及其转换机制详解-从无锁到重量级锁的进化与优化指南
java·后端
IT探险家5 小时前
你的第一个 Java 程序就翻车?HelloWorld 的 8 个隐藏陷阱
java
随风飘的云5 小时前
SpringBoot 的自动配置原理
java