SpringBoot整合PDF动态填充数据并下载

目录

目录

一、准备环境

二、iTextPDF介绍

三、步骤

四、访问查看结果

五、源代码参考


一、准备环境

①下载一个万兴pdf软件

②准备一个pdf 文件

二、iTextPDF介绍

这是一个用于生成PDF文档的Java库,

文档创建与修改:iTextPDF能够从零开始创建PDF文档,也可以读取已有的PDF文件并对其中的内容进行修改,如添加、删除或更新页面内容。

文本与图像插入:可以在PDF文档中插入文本、图片、图表等内容。

表格制作:支持复杂表格的创建和填充,包括单元格合并、样式设定等。

表单填写与交互:支持创建和填充交互式PDF表单,包括文本字段、复选框、列表框等,并且可以对表单域进行读写操作。

数字签名:提供对PDF文档进行数字签名的支持,确保文档的安全性和完整性。

水印与书签:可以添加文档级别的水印和页眉/页脚,以及创建和编辑PDF书签结构。

PDF拆分与合并:iTextPDF可以用来拆分现有的PDF文件或合并多个PDF文档为一个单一文件。

PDF/A合规性:支持生成符合PDF/A标准的文档,这种格式特别适合长期保存和归档。

iTextPDF历经多个版本迭代,最新的iText 7系列采用了全新的API设计,提高了性能和灵活性。同时,iText也提供了针对.NET平台的版本(iTextSharp),以及其他多种语言的绑定,满足不同开发者的需求。

三、步骤

  • 将pdf以万兴pdf形式打开,点击表单,然后点击添加文本域 在下方添加相应的文本域,相当于前端表单的name属性,后端填充数据的时候要调用文本域(文中的name和tel)。
  • 将这个文件保存后复制到此文件夹下
  • 引入依赖
XML 复制代码
      <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.2.5</version>
            <type>pom</type>
        </dependency>
  • 代码
java 复制代码
package com.by.controller;

import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 控制器类,用于处理PDF模板填充及下载请求
 */
@RestController
public class PdfController {

    /**
     * 处理GET请求以下载填充了数据的PDF文件
     * @param response HttpServletResponse对象,用于设置响应头和发送下载文件
     * @return 响应实体,包含填充好数据的PDF字节流
     * @throws IOException 如果读取或写入PDF文件时发生异常
     */
    @GetMapping("/download")
    public ResponseEntity<byte[]> test(HttpServletResponse response) throws IOException {
        // 设置响应头,指示浏览器以附件形式下载文件,并设置文件名
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        String downloadFileName = System.currentTimeMillis() + ".pdf";
        response.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);

        /**
         *  准备需要填充到PDF模板中的数据
         *  其中name和tel为pdf中插入模板的表单数据
         */

        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("name", "张三");
        dataMap.put("tel", "17550635678");

        // 填充数据并生成带数据的PDF字节流
        byte[] pdfBytes = getPdf(dataMap);

        // 创建并返回包含填充后PDF字节流的响应实体
        return new ResponseEntity<>(pdfBytes, headers, HttpStatus.CREATED);
    }

    /**
     * 根据提供的数据填充PDF模板并返回填充后的PDF字节流
     *
     * @param dataMap 需要填充到PDF模板中的键值对数据
     * @return 填充好数据的PDF文件字节数组
     * @throws IOException 如果读取或写入PDF文件时发生异常
     */
    private byte[] getPdf(Map<String, String> dataMap) throws IOException {
        // 获取PDF模板文件路径
        String sourcePdf = ResourceUtils.getURL("classpath:").getPath() + "/templates/2.pdf";

        // 使用PDF阅读器加载模板文件
        PdfReader pdfReader = new PdfReader(new FileInputStream(sourcePdf));

        // 创建一个内存输出流用于存储填充好数据的PDF文件
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // 创建PDF文档对象,连接读取器和输出流
        PdfDocument pdf = new PdfDocument(pdfReader, new PdfWriter(outputStream));

        // 设置默认页面大小为A4
        pdf.setDefaultPageSize(PageSize.A4);

        // 获取PDF表单域对象
        PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
        Map<String, PdfFormField> fields = form.getFormFields();

        // 设置字体,这里使用的是"STSong-Light"字体
        PdfFont currentFont = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_NOT_EMBEDDED);

        // 遍历待填充的数据,并将其填入对应的表单域
        dataMap.forEach((key, value) -> {
            Optional<PdfFormField> formFieldOptional = Optional.ofNullable(fields.get(key));
            formFieldOptional.ifPresent(formField -> {
                // 设置字体并替换表单域的值
                formField.setFont(currentFont).setValue(value);
            });
        });

        // 锁定并合并所有表单域,使其无法再编辑
        form.flattenFields();

        // 关闭PDF文档,释放资源
        pdf.close();

        // 将填充好的PDF文件转换为字节数组并返回
        return outputStream.toByteArray();
    }
}

四、访问查看结果

http://localhost:8080/download

五、源代码参考

https://codeup.aliyun.com/62858d45487c500c27f5aab5/huang-spring-boot-pdf.git

相关推荐
墨染辉2 小时前
pdf处理2
pdf
墨染辉13 小时前
10.2 如何解决从复杂 PDF 文件中提取数据的问题?
pdf
shandianchengzi17 小时前
【记录】Excel|Excel 打印成 PDF 页数太多怎么办
pdf·excel
bianshaopeng1 天前
android 原生加载pdf
android·pdf
卢卡斯2331 天前
在线PDF怎么转换成JPG图片?分享14种转换操作!
pdf
J不A秃V头A1 天前
iTextPDF中,要实现表格中的内容在数据长度超过边框时自动换行
java·pdf
嘻嘻仙人2 天前
【杂谈一之概率论】CDF、PDF、PMF和PPF概念解释与分析
pdf·概率论·pmf·cdf
资深前端之路2 天前
vue2 将页面生成pdf下载
前端·vue.js·pdf
Eiceblue2 天前
Python 复制PDF中的页面
vscode·python·pdf
J不A秃V头A3 天前
使用iTextPDF库设置文字为英文样式
java·pdf