最近遇到一个需求,需要使用Java生成PDF文件,网上的资料很杂乱,故整理记录一下
首先引入pom依赖
com.itextpdf
itextpdf
5.5.11
com.itextpdf.tool
xmlworker
5.5.11
com.itextpdf
itext-asian
5.2.0
org.xhtmlrenderer
flying-saucer-pdf-itext5
9.1.16
net.sf.jtidy
jtidy
r938
将生成代码PDF的工具类放入项目中
package com.seezoon.admin.framework.utils;
import com.itextpdf.text.pdf.BaseFont;
import com.seezoon.admin.framework.utils.bean.ContractDynamicParam;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
/
* @Description: 生成PDF合同工具类
* @author liguodong
* @date 2022年3月6日 下午5:19:32
*/
public class GeneratePdfUtil {
//private static final String TEMPORARY_CONTRACT_HTML = "E:\\workspace\\dytc\\dytc\\seezoon-admin-server\\src\\main\\resources\\contract\\temporary.html";// 临时HTML合同,用于转PDF格式
private static final String TEMPORARY_CONTRACT_HTML = "/data/file/contract/temporary.html";
//private static final String SIMSUM_FILE = "E:\\workspace\\dytc\\dytc\\seezoon-admin-server\\src\\main\\resources\\common\\simsun.ttc";// 添加字体,解决中文支持问题
private static final String SIMSUM_FILE = "/data/file/common/simsun.ttc";
public static String GenerateContract(ContractDynamicParam param) throws Exception {
// 生成html合同
generateHTML(param.getTemplatePath(), param.getTemplateName(), param.getContractParam());
// 根据html合同生成pdf合同
generatePDF(param.getContractPath() + param.getContractName());
// 删除临时html格式合同
removeFile(TEMPORARY_CONTRACT_HTML);
return param.getContractPath() + param.getContractName();
}
/
* @Description 生成html格式合同
*/
private static void generateHTML(String templatePath, String templateName, Map
paramMap) throws Exception { Configuration cfg = new Configuration(); cfg.setDefaultEncoding("UTF-8"); / * 1.setClassForTemplateLoading(this.getClass(), "/HttpWeb"); * 基于类路径,HttpWeb包下的framemaker.ftl文件 * 2.setDirectoryForTemplateLoading(new File("/template")); * 基于文件系统,template目录下的文件 * 3.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template"); * 基于Servlet Context,指的是基于WebRoot下的template下的framemaker.ftl文件 */ cfg.setDirectoryForTemplateLoading(new File(templatePath)); // templateName.ftl为要装载的模板 Template template = cfg.getTemplate(templateName); File outHtmFile = new File(TEMPORARY_CONTRACT_HTML); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outHtmFile))); // 将参数输出到模版,并操作到HTML上 template.process(paramMap, out); out.close(); } / * @Description 根据html生成pdf格式合同 */ private static void generatePDF(String pdfUrl) throws Exception { File htmFile = new File(TEMPORARY_CONTRACT_HTML); File pdfFile = new File(pdfUrl); System.out.println(pdfUrl); String url = htmFile.toURI().toURL().toString(); OutputStream os = new FileOutputStream(pdfFile); ITextRenderer renderer = new ITextRenderer(); renderer.setDocument(url); org.xhtmlrenderer.pdf.ITextFontResolver fontResolver = renderer.getFontResolver(); // 解决中文支持问题 fontResolver.addFont(SIMSUM_FILE, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); renderer.layout(); renderer.createPDF(os); os.close(); } / * @Description 移除文件 */ private static void removeFile(String fileUrl) { File file = new File(fileUrl); file.delete(); } public static void returnPdfStream(HttpServletResponse response, String pathName) throws Exception { response.setContentType("application/pdf"); File file = new File(pathName); if (file.exists()) { FileInputStream in = new FileInputStream(file); OutputStream out = response.getOutputStream(); byte[] b = new byte[1024 * 5]; int n; while ((n = in.read(b)) != -1) { out.write(b, 0, n); } out.flush(); in.close(); out.close(); } } }
package com.seezoon.admin.framework.utils.bean; import lombok.Data; import java.util.Map; / * @Description: 生成PDF参数 * @author lgd * @date 2022年4月27日 下午6:04:56 */ @Data public class ContractDynamicParam { private String templatePath;// 模版路径 private String templateName;// 模板文件名(.ftl结尾) private String contractPath;// 合同生成路径 private String contractName;// 合同生成文件名(.pdf结尾) private Map
contractParam;// 合同所需参数 public ContractDynamicParam(String templatePath, String templateName, String contractPath, String contractName, Map
contractParam) { this.templatePath = templatePath; this.templateName = templateName; this.contractPath = contractPath; this.contractName = contractName; this.contractParam = contractParam; } }
工具类中配置了项目的路径,一个是临时模板,另一个是字体,需要放入相应的路径下,临时模板不用建,项目会自动生成,字体需要进行引入
配置相应的模板!!!重点
先使用world画出模板的表格,我这边使用的是office 2019,然后转化为HTML格式
转化的链接Word转HTML——免费在线Word转网页 (docpe.com)
将转化的html后缀修改为ftl格式,并且在插入值得地方用${值}表示
注意!!!
我这边遇到了一个font-family字体无法转化的bug,修改方法是将项目中的所有的font-family用空格替换掉
然后调用main方法进行测试
public static void main(String[] args) throws Exception { Map
paramMap = new HashMap
(); paramMap.put("XM", "張三冯"); paramMap.put("AH", "(2015)字第0*0号"); paramMap.put("CSKSRQ", "2016年10月31日00时00分"); paramMap.put("KHZH", ""); paramMap.put("FYMC", "人民法院"); paramMap.put("JSRQ", "2017-06-14"); paramMap.put("KZZT", "1"); paramMap.put("LCZH", ""); paramMap.put("DATE", "2017年03月24日09时39分"); paramMap.put("CKWH", "(2015)*字第020-10号裁定书"); paramMap.put("SKSE", "100"); paramMap.put("CSJSRQ", "2016年10月31日 00时00分"); paramMap.put("KHWD", "images/stamp.jpg"); ContractDynamicParam param = new ContractDynamicParam(TEMPLATES_PATH, "pdfDemo.ftl", CONTRACT_PATH, "pdfDemo5.pdf", paramMap); GeneratePdfUtil.GenerateContract(param); System.out.println("====test生成PDF合同成功===="); }
至此就完成了,以后有空会补充一下具体细节
有需要demo的可以移步链接去下载
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218533.html原文链接:https://javaforall.net
https://download.csdn.net/download/enhengguodong/85007061