• Java使用lowagie根据模版动态生成PDF(无需额外设置系统字体)


    今天客户给了一个docx文档模板,让页面填写以后下载成pdf格式的文件,之前的项目里面用过wkhtmltopdf 动态生成pdf,但是如果使用这个方式需要先把word文件转化成html,把数据填充到html以后,再转成pdf,这样转起来太复杂了。
    今天无意中发现使用lowagie 可以直接编辑pdf,而且也不需要像itextpdf那样额外引入系统字体。

    话不多说,开始操作:

    第一步 设置pdf模板

    wps 将word 转成pdf,使用Adobe Acrobat DC编辑pdf。
    Adobe Acrobat DC下载:

    地址:https://pan.baidu.com/s/1NoPc0sNfk3hojJphUoPhyQ?pwd=cir7
    密码:cir7
    
    • 1
    • 2

    下载解压后执行这个文件:
    在这里插入图片描述

    为PDF准备表单

    在这里插入图片描述
    表单准备完毕以后,如下图:
    在这里插入图片描述
    双击一个区域,自定义key:
    在这里插入图片描述
    设置两个字段试试:
    在这里插入图片描述

    保存一下,生成一个新的带表单的pdf。

    使用maven的项目

    导入依赖

            
                com.lowagie
                itext
                2.1.7
            
            
                cn.lesper
                iTextAsian
                3.0
            
            
                com.lowagie
                itext-rtf
                2.1.7
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    java代码创建PdfUtils类

    package pdf.kit.util;
    
    import java.io.ByteArrayOutputStream;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.lowagie.text.pdf.AcroFields;
    import com.lowagie.text.pdf.BaseFont;
    import com.lowagie.text.pdf.PdfReader;
    import com.lowagie.text.pdf.PdfStamper;
    /**
     * @ClassName PdfUtils * @Description TODO
     * @Author lgn
     * @Date 16:43 2022/8/22
     * @Version 1.0
     **/
    public class PdfUtils {
        public static void main(String[] args) throws Exception {
            export();
            System.out.println("生成完成");
        }
    
        public static void export(){
            try {
                // pdf模板所在路径,就是网站制作好后下载的pdf模板路径
                String fileName = "C:\\Users\\lgn\\Desktop\\JS-PAS-2208-001222.pdf";
                PdfReader reader = new PdfReader(fileName);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                PdfStamper ps = new PdfStamper(reader, bos);
    
                // 使用中文字体
                BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                ArrayList fontList = new ArrayList();
                fontList.add(bf);
    
                AcroFields fields = ps.getAcroFields();
                fields.setSubstitutionFonts(fontList);
                fillData(fields, data());
    
                //必须要调用这个,否则文档会出现你不想出现的东西
                ps.setFormFlattening(true);
                ps.close();
    
                //生成pdf路径存放的路径
                OutputStream fos = new FileOutputStream("C:\\Users\\lgn\\Desktop\\result.pdf");
                fos.write(bos.toByteArray());
                fos.flush();
                fos.close();
                bos.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        /**
         * 填充模板中的数据
         */
        public static void fillData(AcroFields fields, Map data) {
            try {
                for (String key : data.keySet()) {
                    String value = data.get(key);
                    // 为字段赋值,注意字段名称是区分大小写的
                    fields.setField(key, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 填充数据源
         * 其中data存放的key值与pdf模板中的文本域值相对应
         */
        public static Map data() {
            Map data = new HashMap();
            data.put("executor", "钢铁侠");
            data.put("reviewed", "小辣椒");
            return data;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    验证一下:
    在这里插入图片描述

  • 相关阅读:
    TDengine 上榜 BenchCouncil 全球首个开源贡献榜
    【Redis】hash类型-内部编码&使用场景
    postman做接口自动化测试
    Webpack 打包commonjs 和esmodule 模块的产物对比
    Redis——Jedis中hash类型使用
    1 Go的前世今生
    微信小程序富文本解析器rich-text、web-view、wxParse、mp-html、towxml对比
    目标检测论文解读复现之十四:一种基于残差网络优化的航拍小目标检测算法
    设计模式——抽象工厂模式02
    C++ (Chapter 1)
  • 原文地址:https://blog.csdn.net/u010797364/article/details/126472084