当前位置: 首页 > article >正文

利用apache-pdfbox库修改pdf文件模板,进行信息替换

public String createSignFile(Long id) throws IOException {
        // 1.验证企业信息
        CompanyDO company = validateCompanyExists(id);
        // 2.验证签约状态
        if(company.getSignStatus()!=0){
            throw exception(COMPANY_SIGN_STATUS_NOT_ZERO);
        }
        // 3.获取合同模板(合同模板有独立模板管理板块)
        String enterType = company.getEnterCompanyType()==1?"franchisee_enter":"service_provider_enter";
        AgreementRespDTO agreementDTO = operateAgreementApi.getAgreementByType(enterType);
        if(agreementDTO==null){
            throw exception(COMPANY_AGREEMENT_NOT_EXISTS);
        }
        String templatePath = agreementDTO.getFile();
        // 4.设定合同参数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        String currentDate = sdf.format(new Date());

        Map<String, String> data = new HashMap<>();
        data.put("companyName", company.getName());
        data.put("secrecyInfo", "无");
        data.put("yearLimit", "一");
        data.put("StartDate", currentDate);
        // 5.生成合同文件
        // 5.1加载 pdf 模板和字体库文件
        //适用于本地资源路径(本地用于调试,信息为e:/file.pdf)
//        FileInputStream fis = new FileInputStream(templatePath);
        // 采用网络资源路径(系统中采用oss对象存储,所以获取的是网络路径)
        URL url = new URL(templatePath);
        URLConnection connection = url.openConnection();
        InputStream fis = connection.getInputStream();
        // 字体文件【华文仿宋】,可以自己换字体库
        URL fontUrl = new URL("https://你自己的地址.oss-cn-beijing.aliyuncs.com/stfangso.ttf");
        URLConnection fontConnection = fontUrl.openConnection();
        InputStream fontFile = fontConnection.getInputStream();
        // 开始读取
        //============ pdf 文件读取处理 ===============
        PDDocument pdf = PDDocument.load(fis);
        Map<COSName, PDFont> oldfont = new HashMap<COSName, PDFont>();
        COSName fontName = null;
        PDType0Font targetfont= PDType0Font.load(pdf,fontFile);

        for (PDPage page : pdf.getPages()) {
            PDFStreamParser pdfsp = new PDFStreamParser(page);
            pdfsp.parse();
            List<Object> tokens = pdfsp.getTokens();
            for (int j = 0; j < tokens.size(); j++) {
                //创建一个object对象去接收标记
                Object next = tokens.get( j );
                //instanceof判断其左边对象是否为其右边类的实例
                if(next  instanceof COSName) {
                    fontName= (COSName)next;
                    if(!oldfont.containsKey(fontName)) {
                        oldfont.put(fontName, page.getResources().getFont(fontName));
                    }
                }else
                if(next  instanceof COSString) {
                    COSString previous = (COSString)next;
                    try(InputStream in = new ByteArrayInputStream(previous.getBytes())){
                        StringBuffer sb = new StringBuffer();
                        while (in.available()>0) {
                            int rc = oldfont.get(fontName).readCode(in);
                            sb.append(oldfont.get(fontName).toUnicode(rc));
                        }
                        //重置COSString对象
                        previous.setValue(targetfont.encode(sb.toString()));
                    }
                }else if(next  instanceof COSArray) {
                    //PDF中的字符串
                    byte[] pstring = {};
                    int prej = 0;
                    COSArray previous  =(COSArray)next;
//                    //循环previous
                    for (int k = 0; k < previous.size(); k++) {
                        Object arrElement = previous.getObject( k );
                        if( arrElement instanceof COSString ){
                            //COSString对象>>创建java字符串的一个新的文本字符串。
                            COSString cosString =(COSString)arrElement;
                            //将此字符串的内容作为PDF文本字符串返回。
                            if (j == prej) {
                                byte[] thisbyte = cosString.getBytes();
                                byte[] temp = new byte[pstring.length+thisbyte.length];
                                System.arraycopy(pstring, 0, temp, 0, pstring.length);
                                System.arraycopy(thisbyte, 0, temp, pstring.length, thisbyte.length);
                                pstring=temp;
                            } else {
                                prej = j;
                                pstring = cosString.getBytes();
                            }
                        }
                    }
                    try(InputStream in = new ByteArrayInputStream(pstring)){
                        StringBuffer sb = new StringBuffer();
                        while (in.available()>0) {
                            int rc = oldfont.get(fontName).readCode(in);
                            sb.append(oldfont.get(fontName).toUnicode(rc));
                        }
                        String str =sb.toString();
                        for (Map.Entry<String, String> entry : data.entrySet()) {
                            String key = "${" + entry.getKey() + "}";
                            if (str.contains(key)) {
                                str = str.replace(key, entry.getValue() != null ? entry.getValue() : "");
                                break;
                            }
                        }
                        COSString cosString2 = (COSString) previous.getObject(0);
                        cosString2.setValue(targetfont.encode(str));
                    }
                    int total = previous.size()-1;
                    for (int k = total; k > 0; k--) {
                        previous.remove(k);
                    }
                }
            }
            PDStream updatedStream = new PDStream(pdf);
            OutputStream out = updatedStream.createOutputStream();
            ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
            tokenWriter.writeTokens(tokens);
            out.close();
            oldfont.forEach((k,v)->{
                page.getResources().put(k, targetfont);
            });
            page.setContents(updatedStream);
        }
        //保存到本地中(主要用于调试)
        //pdf.save("d:/1.pdf");
        //pdf.close();
        //将文件直接保存上传(由于生成后,前台展示所以要直接上传获取上传地址进行前台回显)
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        pdf.save(out);
        pdf.close();//记得关闭资源哦
        // 将输出流的内容转换为Base64编码的字符串
        byte[] bytes = out.toByteArray();

        String pdfUrl =fileApi.createFile(bytes);
        // 将上传后的文件,存到数据库中
        companyMapper.updateById(new CompanyDO().setId(id).setSignFileUrl(pdfUrl));

        return pdfUrl;
    }

该板块主要用于利用模板生成入驻企业的合同信息,便于在线发起合同签署功能。
采用了模板的变量替换方式,需要将变量信息预先插入到模板的指定位置。


http://www.kler.cn/a/303178.html

相关文章:

  • 基于yolov8、yolov5的车型检测识别系统(含UI界面、训练好的模型、Python代码、数据集)
  • STM32设计学生宿舍监测控制系统
  • 自动驾驶系列—从数据采集到存储:解密自动驾驶传感器数据采集盒子的关键技术
  • sql专题 之 where和join on
  • React中 修改 html字符串 中某些元素的属性
  • 安全见闻1-5
  • 【基础算法总结】二分查找
  • 在Python的Pandas库中,`df.iloc[::500]`是一个用于数据选择的索引器,它允许我们从DataFrame中选择特定的行和列。
  • golang学习笔记19——golang做服务发现与注册的深度剖析
  • 从安装ffmpeg开始,把一个视频按照每秒30帧fps剪切为图片
  • Vue组件:模板引用ref属性的使用
  • 微信小程序之轮播图组件封装
  • CTF常见编码及加解密(超全)第二篇
  • java程序员入行科目一之CRUD轻松入门教程(二)
  • layui监听table表单的多选框
  • 高级实时通信:基于 Python 的 WebSocket 实现与异步推送解决方案
  • 商务办公tips1:如何将网页转换为pdf
  • Python 数学建模——Vikor 多标准决策方法
  • 基于react native的锚点
  • 鼎捷新一代PLM 荣膺维科杯 “2023年度行业优秀产品奖”
  • 基于Service Worker实现WebRTC局域网大文件传输能力
  • C语言可变参数函数和可变参数宏
  • Python 数学建模——方差分析
  • 无人机之伯努利定律
  • RabbitMQ消费者确认和重复机制
  • Python爬虫案例七:抓取南京公交信息数据并将其保存成excel多表形式