Java web项目中如何将静态HTML或jsp动态生成PDF文件

直接奔入正题,首先引入下方maven依赖复制到pom.xml中,如果不是maven项目,可到https://search.maven.org/ 直接去下载。

<dependency>  
	<groupId>org.xhtmlrenderer</groupId>
	<artifactId>flying-saucer-pdf-itext5</artifactId>  
	<version>9.0.6</version>  
</dependency>
<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.28</version>
</dependency>

下面代码撸起来

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;

import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.itextpdf.text.pdf.BaseFont;
import com.tintinloan.codelets.support.exception.BusinessException;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import net.sf.json.JSONObject;

/***
 * 
 * 作者: 
 *
 * 创建时间:2019年7月29日 下午2:25:56
 * 
 * 实现功能:ftl转html转PDF工具类
 */
public class Html2Pdf {
	
	/***
	 * 通过模板转换为html
	 * @param modeName 模板名称
	 * @param params 参数
	 * @return html的字符串形式
	 * @throws Exception
	 */
	public String createHtmlStr(String modelName, JSONObject params) {
		Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
	    try {
	        // 设置模板所在路径
	        cfg.setDirectoryForTemplateLoading(new File("D:\\ftl"));
	        // 设置默认编码
	        cfg.setDefaultEncoding("utf-8");
	        //若发生错误,HTML_DEBUG_HANDLER会生成错误信息到生成页面;RETHROW_HANDLER错误信息会输出到控制台
	        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	    StringWriter out = null;
	    try {
            // 创建模版对象
            Template template = cfg.getTemplate(modelName);
            out = new StringWriter();
            // 模版数据插入参数,通过输出流插入到HTML中
            template.process(params, out);
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        } finally {
            if (null != out) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
	    return out.toString();
    }
	
	/***
	 * 把html字符串转换为PDF
	 * @param outputFile
	 * @param content
	 * @throws Exception
	 */
	public boolean htmlToPdf(String outputFile, String content) throws IOException,DocumentException {
		File outFile = new File(outputFile);
		if (!outFile.exists()) {
			outFile.getParentFile().mkdirs();
		}
		/*
		 * response.setHeader("Content-disposition","attachment;filename=test.pdf");
		 * response.setContentType("application/pdf"); 
		 * OutputStream os = response.getOutputStream();
		 */
		OutputStream os = new FileOutputStream(outputFile);
		ITextRenderer renderer = new ITextRenderer();
		
        // 该参入是传入需要转为PDF的页面的网络路径,比如:http://xxx.xxx/xxx.html
        // 或者可以返回modelAndview的controller
        // renderer.setDocument(url);
        // 该参入是传入需要转为PDF的HTML字符串
		renderer.setDocumentFromString(content);
		// 将宋体文件
		String fontPath = "D\\ttc\\simsun.ttc";
		// 设置中文字体
		ITextFontResolver fontResolver = renderer.getFontResolver();
		fontResolver.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
		renderer.layout();
		renderer.createPDF(os);
		renderer.finishPDF();
		os.flush();
		os.close();
		return true;
	}
}

上面两个方法中第一个是将ftl转换成HTML并返回HTML的string形式,第二个方法是将HTML转换为pdf文件并保存到指定的路径下。注释很详细,就不单独细说了。字体文件下载地址,下载后解压后放到D:/ttc文件夹下

     链接:https://pan.baidu.com/s/1xxONpDF_zUAYZC0o4M477Q 提取码:nufc  

下面开始定义一个ftl模板文件放到D:/ftl文件夹下,模板文件名称为:test.ftl

<html>
<head>
<title>测试ftl</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type='text/css'>
<!-- 设置页面大小 -->
@page {
	size: 297mm 210mm;
}
</style>
</head>
<!-- body中要设置文字的字体,与Java代码中引用的字体一致 -->
<body bgcolor='white'
	style='font-family: SimSun; height: 100%;word-break: break-all;'
	screen_capture_injected='true' ryt11773='1'>
	<div class="" style="margin-top:5px">
		<p
			style="background-color: #ffffff;; line-height: 125%; margin: 0pt; text-align: center">
			<span style="font-size:25px;font-weight: bold">${content}</span>
		</p>
		
	</div>
</body>
</html>

模板写好之后,开始调用测试能不能生成就可以了。

public static void main(String[] args) {
        // PDF生成后存放目录
        final String outputFile = "D://ftest.pdf";
        Html2Pdf html2Pdf = new Html2Pdf();
        // 创建jsonobject对象给ftl模板传参
        JSONObject json = new JSONObject();
        json.put("content","Hello World!");
        try {
            html2Pdf.htmlToPdf(outputFile, html2Pdf.createHtmlStr("test.ftl", json));
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
		
	}

运行后,就是这样的了。其他的api自行研究吧。

 

如果完成上面这一步,不要高兴的太早:

看下面这张图,明白了什么?

这就是我要特别提醒的:有时候,在HTML转PDF的时候页面转换错误,或者标签解析错误,那是因为仅支持css2.1样式,itext支持5.x。大家应该都懂得。所以如果页面需要转换为PDF,那么请放下你大神的姿态。

 就这样了,如有更好的解决方案可共同探讨。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值