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));}}elseif(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;
// //循环previousfor (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;}
该板块主要用于利用模板生成入驻企业的合同信息,便于在线发起合同签署功能。
采用了模板的变量替换方式,需要将变量信息预先插入到模板的指定位置。