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

java 复制代码
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;
    }

该板块主要用于利用模板生成入驻企业的合同信息,便于在线发起合同签署功能。

采用了模板的变量替换方式,需要将变量信息预先插入到模板的指定位置。

相关推荐
皓月盈江5 小时前
使用谷歌浏览器自带功能将网页转换为PDF文件
chrome·pdf·html·网页转pdf·谷歌浏览器打印功能
云只上7 小时前
PDF转excel+json ,vue3+SpringBoot在线演示+附带源码
前端·javascript·spring boot·后端·pdf·json·excel
令狐少侠20117 小时前
AI之pdf解析:Tesseract、PaddleOCR、RapidPaddle(可能为 RapidOCR)和 plumberpdf 的对比分析及使用建议
人工智能·python·pdf
usdoc文档预览7 小时前
Office文件内容提取 | 获取Word文件内容 |Javascript提取PDF文字内容 |PPT文档文字内容提取
javascript·pdf·word·ppt·office文件在线预览·word文档在线预览·ofd预览转pdf
安替-AnTi12 小时前
Google Colab测试部署Qwen大模型,实现PDF转MD场景OCR 识别(支持单机环境)
pdf·ocr·多模态·qwen 2.5·图片转文本
AI偶然13 小时前
AI智能体|扣子(Coze)搭建【一键转换为Word/pdf/Excel】工作流保姆级教学
人工智能·pdf·word
朴拙数科14 小时前
LangChain实现PDF中图表文本多模态数据向量化及RAG应用实战指南
langchain·pdf
青柠过敏14 小时前
Itext进行PDF的编辑开发
pdf
摸鱼仙人~1 天前
开源的 PDF 文件翻译软件
pdf
辣香牛肉面1 天前
PDF多功能转换编辑及扫描仪 iLovePDF 3.10.0
pdf·多功能转换·pdf编辑扫描