利用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;
    }

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

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

相关推荐
Python猫2 小时前
付费专栏·Python潮流周刊电子书合集(epub、pdf、markdown)下载
python·计算机·pdf·电子书·资料
JackieZhengChina4 小时前
用python清除PDF文件中的水印(Adobe Acrobat 无法删除)
pdf
geovindu7 小时前
vue3: pdf.js 3.4.120 using javascript
开发语言·javascript·vue.js·pdf
TextIn智能文档云平台19 小时前
PDF文档解析新突破:图表识别、公式还原、手写字体处理,让AI真正读懂复杂文档!
图像处理·人工智能·算法·自然语言处理·pdf·ocr
old_power19 小时前
【Python】PDF文件处理(PyPDF2、borb、fitz)
python·pdf
belldeep1 天前
vite:npm 安装 pdfjs-dist , PDF.js View 预览功能示例
javascript·pdf·pdfjs-dist·pdf.worker
dtzly1 天前
若依定制pdf生成实战
pdf
令狐少侠20111 天前
ai之pdf解析rapidOCR 的两种底层依赖PaddlePaddle 和ONNXRuntime
人工智能·ai·pdf
Kisorge1 天前
【PDF】使用Adobe Acrobat dc添加水印和加密
pdf
sword devil9001 天前
Python实用工具:pdf转doc
python·pdf