HTML文件模板替换到转换PDF文件并下载PDF文件

话不多说了,由于最近有通过数据生成PDF的需求,所以做完后在这里记录分享一下。直接用iText创建pdf文件考虑到html中的表格等等要合并或者什么的太麻烦,就直接通过Html模板替换之后再转换PDF来的更简单。具体实现直接分享代码给大家,高手勿喷!哈哈!

1.html文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
body {
	font-family: SimSun;
	font-size: 14px;
}

table {
	border-collapse: collapse;
	border: 1px solid #999;
	border-width: 1px 0 0 1px;
	width: 650px;
	height: auto;
}

table th {
	border: 1px solid #999;
	border-width: 0 1px 1px 0;
	padding: 2px;
	height: 50px;
	font-weight: bold;
	font-size: 23px;
}

table td {
	border: 1px solid #999;
	border-width: 0 1px 1px 0;
	padding: 2px;
	height: 40px;
}

.hfont {
	font-weight: bold;
	font-size: 18px;
}

.cheight {
	height: 320px;
}

.fheight {
	height: 60px;
}
</style>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta>
</head>
<body>
    <table>
    	<tr>
    		<th align="center" colspan="4">HTML模板替换并转换PDF文件</th>
    	</tr>
    	<tr>
    		<td class="hfont" width="20%" align="center" rowspan="4">基本信息</td>
    		<td align="left">姓名:###name###</td>
    	</tr>
    	<tr>
    		<td align="left">年龄:###age###</td>
    	</tr>
    	<tr>
    		<td align="left">性别:###sex###</td>
    	</tr>
    	<tr>
    		<td align="left">手机:###phone###</td>
    	</tr>
    </table>
  </body>
</html>
2.java工具类

package com.shangmai.tobacco.util;
  
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

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

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import com.shangmai.tobacco.common.DateUtils;

/**
 * Html模板替换并转PDF文件-下载PDF
 * @author cavancao
 * 2015-09-24
 */
public class Html2PdfUtil{
	private static final String FONTPATH = "C:/WINDOWS/Fonts/SIMSUN.TTC";//支持中文字体(放哪里都行)
	/**
	 * 定义各个模板内需要替换的参数
	 */
	// 通用表格导出
	private static final String[] USER_PDF = { "name", "age", "sex", "phone" };
	
	/**
	 * 通过参数获取对应的属性数组进行文本替换
	 */
	public static String[] findAttributes(String attributeKey) {
		if (attributeKey.equals("USER_PDF")) {
			return USER_PDF;
		} else {
			return new String[]{};
		}
	}
	
	/**
     * html转换pdf文件
     * 注:支持中文,目前iText只支持上面FONTPATH定义的这种字体,所以html文件中也需要用样式设置字体为:SimSun
     * htmlPath 需要转换的html源文件
     * pdfPath 转换后pdf文件存放地址
     */
	public static String html2Pdf(String htmlPath, String pdfPath) {
		try {
			String url = new File(htmlPath).toURI().toURL().toString();
			OutputStream output = new FileOutputStream(pdfPath);
			ITextRenderer renderer = new ITextRenderer();
			renderer.setDocument(url);
			
			//解决中文支持问题(html的中文必须用SimSun字体,Java只能支持这1种字体)
			ITextFontResolver fontResolver = renderer.getFontResolver();
			fontResolver.addFont(FONTPATH, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
			renderer.layout();
			renderer.createPDF(output);
			output.close();
			//删除模板替换生成的新html文件
			File htmlFile = new File(htmlPath);
			if(htmlFile.exists()){
				htmlFile.delete();
			}
			return pdfPath;
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return null;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (DocumentException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 通过html模板替换特定字符生成新的html文件
	 * @param htmlPath html文件地址
	 * @param targetPath 替换模板生成新html的存放地址
	 * @param data 替换的数据
	 * @param attributeKey 获取替换文本列表的数组标识
	 * @return
	 */
	public static String createHtml(String htmlPath, String targetPath,
			Map<String, String> data, String attributeKey) {

		StringBuffer sb = new StringBuffer();
		BufferedReader br = null;
		try {
			// 读取html文件模板内容
			br = new BufferedReader(new InputStreamReader(new FileInputStream(
					new File(htmlPath)), "UTF-8"));
			String temp = "";
			while (null != (temp = br.readLine())) {
				sb.append(temp);
			}
			String htmlContext = sb.toString();
			// 替换html模板内的指定字符
			for (String attribute : findAttributes(attributeKey)) {
				htmlContext = htmlContext.replaceAll("###" + attribute + "###",
						data.get(attribute));
			}
			// 写入新的html文件
			targetPath = targetPath + DateUtils.formatDate(new Date(), "yyyyMMddHHmmsss") + ".html";
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(new File(targetPath)), "UTF-8"));
			bw.write(htmlContext);
			bw.flush();
			bw.close();
			return targetPath;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 文件下载-支持中文名称
	 * @param sourcePath下载文件全路径(D:/test.pdf)
	 * @param fileName需要生成的下载文件名(HTML转PDF测试.pdf)
	 * @param response
	 */
	public static void downloadFile(String sourcePath, String fileName,
			HttpServletResponse response) {
		// 读到流中
		InputStream inStream = null;
		try {
			inStream = new FileInputStream(sourcePath);// 文件的存放路径
			// 设置输出的格式
			response.reset();
			String name = new String((fileName));
			response.addHeader("Content-Disposition", "attachment; filename=\""
					+ toUtf8String(name) + "\"");
			// 循环取出流中的数据
			byte[] b = new byte[100];
			int len;
			
			while ((len = inStream.read(b)) > 0) {
				response.getOutputStream().write(b, 0, len);
			}
			response.getOutputStream().flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				inStream.close();
				response.getOutputStream().close();
				//删除源文件
				File sourceFile = new File(sourcePath);
				if(sourceFile.exists()){
					sourceFile.delete();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 下载中文名文件进行编码转换
	 */
	public static String toUtf8String(String s) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				try {
					b = Character.toString(c).getBytes("utf-8");
				} catch (Exception ex) {
					b = new byte[0];
				}
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					if (k < 0)
						k += 256;
					sb.append("%" + Integer.toHexString(k).toUpperCase());
				}
			}
		}
		return sb.toString();
	}
	
	public static void main(String[] args){
		//map中put的key要和上面定义的USER_PDF数组一致
		Map<String,String> data = new HashMap<String,String>();
		//在html文件中必须为###name###才会被map中的name替换
		data.put("name", "王小二");
		data.put("age", "20");
		data.put("sex", "男");
		data.put("phone", "13800000000");
		String html = createHtml("D:/test.html", "D:/", data, "USER_PDF");
		String pdf = html2Pdf(html, "D:/"+DateUtils.formatDate(new Date(), "yyyyMMddHHmmsss")+".pdf");
		
		//如果在控制类有response对象可以直接转换后的pdf文件,在控制类方法需要return null
		//downloadFile(pdf, "我的PDF文件.pdf", response);
		//return null;
		
		System.out.println("create html success! 文件存放路径:" + pdf);
	}
}

3.相关支持文件(自行下载吧,我竟然不会上传!第1次写博客):2个jar包;1个中文字体

iText-2.0.8.jar.jar

core-renderer.jar.jar


simsun.ttc 宋体(如果电脑里没有就去下载一个)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值