使用Java生成PDF文件

2022-07-02 00:00:00 java 文件 生成

最近遇到一个需求,需要使用Java生成PDF文件,网上的资料很杂乱,故整理记录一下

首先引入pom依赖

<!-- pdf:start -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.11</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.11</version>
        </dependency>
        <!-- 支持中文 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- 支持css样式渲染 -->
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf-itext5</artifactId>
            <version>9.1.16</version>
        </dependency>
        <!-- 转换html为标准xhtml包 -->
        <dependency>
            <groupId>net.sf.jtidy</groupId>
            <artifactId>jtidy</artifactId>
            <version>r938</version>
        </dependency>
<!-- pdf:end -->

将生成代码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<String, Object> 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<String, Object> contractParam;// 合同所需参数


	public ContractDynamicParam(String templatePath, String templateName, String contractPath, String contractName, Map<String, Object> 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<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("XM", "張三冯");
		paramMap.put("AH", "(2015)****字第0***0号");
		paramMap.put("CSKSRQ", "2016年10月31日00时00分");
		paramMap.put("KHZH", "271**********07279975");
		paramMap.put("FYMC", "****人民法院");
		paramMap.put("JSRQ", "2017-06-14");
		paramMap.put("KZZT", "1");
		paramMap.put("LCZH", "987234234");
		paramMap.put("DATE", "2017年03月24日09时39分");
		paramMap.put("CKWH", "(2015)*****字第0**20-1**0号裁定书");
		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的可以移步链接去下载

java使用itext生成pdfdemo,直接执行main方法可用!代码文档中有配置文件的详细介绍-Java文档类资源-CSDN下载java使用itext导出pdf,可以生成表格、文字、图片等,demo中详细介绍了使用的版本,可能出更多下载资源、学习资料请访问CSDN下载频道.《使用Java生成PDF文件》https://download.csdn.net/download/enhengguodong/85007061

    原文作者:老醋先生~
    原文地址: https://blog.csdn.net/enhengguodong/article/details/123368312
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章