Java⼀键⽣成PDF合同以及骑缝章、盖章处的精准盖章
最近项⽬做到根据订单⽣成pdf合同。要求像阿⾥云的合同⼀样,有骑缝章,并且合同末尾处要进⾏盖章。为了做出这个功能搜集了很多博主的内容,最后终于做出了。现在做⼀个从头到尾的详细总结,也供⼤家参考⼀下,免得向我⼀样搜罗太多资料,浪费时间。废话不多说 直接开始上代码。第⼀次写博客,可能有表达的不好的地⽅,望见谅。不明⽩的可以私信,看到了尽量解答。
涉及的依赖如下:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
优秀团员申请书
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>l</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.verter.pdf-gae</artifactId>
<version>2.0.1</version>
</dependency>
1、准备⼀个word格式的模板,主要内容如下:
2、⽣成和同类
* @return: java.lang.String 返回云端地址
**/
private String makeCont(List<OrderInfo> orderInfos, ContInfo contInfo) throws Exception {
String urlPath;
String id = ContFileName();// 合同ID
String contractPath = Property("ur.dir") + "/website/cont/templet/";
/
/获取合同信息
Map<String, String> replaceMap = getReplaceMap(contInfo, orderInfos);
String urId = ("urId");
StringBuilder destPathDOCX = new StringBuilder(contractPath).append(urId); //合同信息填充后的保存路径
// 判断⽤户⽂件夹是否存在,不存在则新建
File urNumFile = new String());
if (!ists()) {
urNumFile.mkdirs();
}
destPathDOCX.append(File.parator).append(urId).append(".docx");
Map<String, String> replaceTableMap = new HashMap<String, String>();
replaceTableMap.put("totalAmount", ve("totalAmount"));
replaceTableMap.put("date", ve("date"));
replaceTableMap.put("totalCapitalizeAmount", ve("totalCapitalizeAmount"));
// 替换合同⾥⾯的参数
郭玉成placeAndGenerateWord(contractPath + "templet.docx", String(), replaceMap, replaceTableMap); //更新合同中的产品服务信息
String(), orderInfos);
//设置转换后pdf⽂件的保存路径
StringBuilder pdfFile = new StringBuilder(contractPath).append(urId).append(File.parator).append(id).append(".pdf");
// 将word转pdf⽂件
Boolean bool = WordUtil.String(), String());
//盖章
InputStream inputStream = new String());
PdfUtil.itextPDFAddPicture(inputStream, String());
//将盖章后的pdf⽂档保存到云端
urlPath = aliyunOSS.uploadFile("files/contract/", id + ".pdf", new String()));
// 删除word电⼦合同
File fileDOCX = new String());
if (ists()) {
fileDOCX.delete();
}
//删除pdf电⼦合同
File filePdf = new String());
if (ists()) {
filePdf.delete();
}
return urlPath;
}
3、word⼯具类
package com.util;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.aspo.words.Licen;
import org.apache.poi.xwpf.urmodel.XWPFDocument;
import org.apache.poi.xwpf.urmodel.XWPFParagraph;
import org.apache.poi.xwpf.urmodel.XWPFRun;
import org.apache.poi.xwpf.urmodel.XWPFTable;
import org.apache.poi.xwpf.urmodel.XWPFTableCell;
import org.apache.poi.xwpf.urmodel.XWPFTableRow;
import com.aliyuncs.utils.StringUtils;
/**
* @ClassName:WordUtil
* @Description:操作word⽂档⼯具类
* @Version:V1.0
* @Author:wuyongqiang
* @Date:2021/12/7 13:53:32
友的成语*/
public class WordUtil {
/**
* @Author: wuyongqiang
* @Description:替换word中需要替换的特殊字符
* @Date: 2021/12/7 16:59
12种包子包法* @Param srcPath: 需要替换的⽂档全路径
* @Param exportFile: 替换后⽂档的保存路径
* @Param contentMap: {key:将要被替换的内容,value:替换后的内容}
* @Param replaceTableMap: {key:将要被替换的表格内容,value:替换后的表格内容}
* @return: boolean 返回成功状态
**/
public static boolean replaceAndGenerateWord(String srcPath, String exportFile, Map<String, String> contentMap, Map<String, String> replaceTableMap) thro boolean bool = true;
FileInputStream inputStream = new FileInputStream(srcPath);
XWPFDocument document = new XWPFDocument(inputStream);
// 替换段落中的指定⽂字
腊肠煮多久Iterator<XWPFParagraph> itPara = ParagraphsIterator();
while (itPara.hasNext()) {
XWPFParagraph paragraph = ();
commonCode(paragraph, contentMap);
}
// 替换表格中的指定⽂字
Iterator<XWPFTable> itTable = TablesIterator();
while (itTable.hasNext()) {
痰多的原因XWPFTable table = ();
真的见证int rcount = NumberOfRows();
for (int i = 0; i < rcount; i++) {
XWPFTableRow row = Row(i);
List<XWPFTableCell> cells = TableCells();
for (XWPFTableCell cell : cells) {
//单元格中有段落,得做段落处理
List<XWPFParagraph> paragraphs = Paragraphs();
for (XWPFParagraph paragraph : paragraphs) {
commonCode(paragraph, replaceTableMap);
}
}
}
}
FileOutputStream outStream = new FileOutputStream(exportFile);
document.write(outStream);
outStream.clo();
inputStream.clo();
return bool;
}
/**
* @Author: wuyongqiang
* @Description:替换内容
* @Date: 2021/12/7 16:56
* @Param paragraph: 被替换的⽂本信息
* @Param contentMap: {key:将要被替换的内容,value:替换后的内容}
* @return: void
**/
private static void commonCode(XWPFParagraph paragraph,Map<String, String> contentMap){
List<XWPFRun> runs = Runs();
for (XWPFRun run : runs) {
String oneparaString = TextPosition());
if (StringUtils.isEmpty(oneparaString)){
continue;
}
for (Map.Entry<String, String> entry : Set()) {
oneparaString = Key(), StringUtils.Value()) ? "--" : Value());
}
run.tText(oneparaString, 0);
}
}
/**
* @Author: wuyongqiang
* @Description:验证licen许可凭证
* @Date: 2021/12/7 16:57
* @return: boolean 返回验证Licen状态
**/
private static boolean getLicen() {
boolean result = true;
try {
String path = Property("ur.dir")+"/website/l";
new Licen().tLicen(new FileInputStream(new File(path).getAbsolutePath()));
} catch (Exception e) {
result = fal;
e.printStackTrace();
}
return result;
}
/**
* @Author: wuyongqiang
* @Description:word转pdf
* @Date: 2021/12/7 16:58
* @Param wordPath: word 全路径,包括⽂件全称
* @Param pdfPath: pdf 保存路径,包括⽂件全称
* @return: boolean 返回转换状态
**/
public static boolean wordConverterToPdf(String wordPath, String pdfPath) {
遵守社会公德情况boolean bool = fal;
// 验证Licen,若不验证则转化出的pdf⽂档会有⽔印产⽣
if (!getLicen()) return bool;
try {
FileOutputStream os = new FileOutputStream(new File(pdfPath));// 新建⼀个pdf⽂档输出流
com.aspo.words.Document doc = new com.aspo.words.Document(wordPath);// Address是将要被转化的word⽂档
doc.save(os, com.aspo.words.SaveFormat.PDF);// 全⾯⽀持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换 os.clo();