Java 使用Itext导出固定模板的pdf文件

场景:java中使用Itext导出pdf

前期准备:下载Adobe Acrobat DC 软件 前期制作需要导出的pdf模板
模板制作步骤

  • 先在word文档上制作出自己需要的模板样式,例如:

  • 在这里插入图片描述

  • 把该word保存成pdf格式,然后再用软件打开
    在这里插入图片描述

  • 给需要填值的地方添加文本域,并填上代码中对应的字段
    在这里插入图片描述

  • 最后另存到需要存放的地址,格式为pdf

具体代码实现

依赖

 <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.10</version>
        </dependency>

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

这里要注意,依赖一定要添加到工具类或者具体实现的模块项目,并且两个必须添加
(昨天只添加了第一个依赖,代码不报错,但导出的pdf文件没有值,死活找不到问题)

工具类

public class PdfUtil {

    /**
     *
     * @param o 写入的数据
     * @param out 自定义保存pdf的文件流
     * @param templatePath pdf模板路径
     */
    // 利用模板生成pdf
    public  void fillTemplate(Map<String,Object> o, OutputStream out, String templatePath) {
        PdfReader reader;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        try {

            reader = new PdfReader(templatePath);// 读取pdf模板
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();

            java.util.Iterator<String> it = form.getFields().keySet().iterator();

            while (it.hasNext()) {
                String name = it.next().toString();
                String value = o.get(name)!=null?o.get(name).toString():"";
                form.setField(name,value);
            }
            stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
            stamper.close();

            Document doc = new Document();
            //            Font font = new Font(bf, 32);
            PdfCopy copy = new PdfCopy(doc, out);
            doc.open();
            
            PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
            copy.addPage(importPage);
            
            doc.close();

        } catch (IOException e) {
            System.out.println(e);
        } catch (DocumentException e) {
            System.out.println(e);
        }
    }
}

这里需要注意一下,这串代码只会导出一页,如果想导出多页,则需把代码改成

   //改成这样就不会只显示一页了。
            PdfImportedPage importPage = null;
            ///循环是处理成品只显示一页的问题
            for (int i=1;i<=reader.getNumberOfPages();i++){
                importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i);
                copy.addPage(importPage);
            }

具体controller代码

  public AjaxResult exportRecord(@PathVariable("recordId") String recordId,HttpServletResponse response) throws IOException {
        String fileName = FileUtils.encodingPdfFilename("******"); //导出时具体的文件名
        CykEnterpriseReportRecord cykEnterpriseReportRecord = cykEnterpriseReportRecordService.selectCykEnterpriseReportRecordByReportRecordId(recordId);
        String templateFileName = "";
        
        templateFileName =  EcenterConfig.getProfile() +  "/template_endwise.pdf";//找到pdf模板
        //这个是查询出来的实体类,如果是其他类型的也改成String类型的就可
         String json = JSONObject.toJSONString(cykEnterpriseReportRecord);
        try {
            json = java.net.URLDecoder.decode(json,"UTF-8");  //解码
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JSONObject jsonObject = JSONObject.parseObject(json);
        Map<String, Object> mapJson = (Map<String, Object>) JSONObject.toJSON(jsonObject);
        // 设置response参数,可以打开下载页面
        response.reset();
        response.setCharacterEncoding("UTF-8");
        // 定义输出类型
        response.setContentType("application/PDF;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment; filename=" + "assessment.pdf");
        try {
            OutputStream out = new FileOutputStream(FileUtils.getAbsoluteFile(fileName));
            PdfUtil pdf = new PdfUtil();
            pdf.fillTemplate(mapJson ,out,templateFileName);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return AjaxResult.success(fileName);
    }

具体导出结果
在这里插入图片描述
完美收官!!!!撒花~~

加个后续:
使用过程中发现有中文字段缺失的情况,比如应该导出“我爱我的祖国”的字符串,但在实际中只导出了“我爱祖国” 类似这样的情况,解决方法如下:

BaseFont bf =BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
Font f = new Font(bf,12,Font.NORMAL);
form.addSubstitutionFont(bf);

在这里插入图片描述
这次真的完美收官!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值