話不多說了,由於最近有通過數據生成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 宋體(如果電腦裏沒有就去下載一個)