话不多说了,由于最近有通过数据生成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 宋体(如果电脑里没有就去下载一个)