最近項目中客戶提了一個奇葩的需求;批量把html轉爲pdf文件用於存檔。聽到這個需求不知所錯,最開始研究iText使用java開發,各種中文亂碼,中文不顯示問題。後來在網上搜索到wkhtmltopdf工具,以下是完整的說明以及代碼。
首先下載文件:html轉爲pdf文件(wkhtmltox)(包括windows下exe安裝文件和linux下可執行文件),官方下載地址
一、windows下操作步驟
安裝:wkhtmltox-0.12.3.2_msvc2013-win64.exe,cmd命令進入安裝目錄
運行:wkhtmltopdf.exe [參數,可選,可多個;wkhtmltopdf中文參數詳解] <需要轉的html路徑,必填,可多個> <轉成功後的pdf文件存放地址,必填>
a.例子: wkhtmltopdf.exe –page-size A4 www.baidu.com test.pdf
二、linux下操作步驟
解壓:命令:tar -xvf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
解決中文不顯示或亂碼問題:需要字體文件cjkuni-uming、smc、stix放入/usr/share/fonts目錄下
運行:進入wkhtmltox/bin目錄 ./wkhtmltopdf [參數,可選,可多個;wkhtmltopdf中文參數詳解] <需要轉的html路徑,必填,可多個> <轉成功後的pdf文件存放地址,必填>
a.例子: ./wkhtmltopdf –page-size A4 www.baidu.com pdf.pdf
三、通過java調用wkhtmltox的可執行文件實現批量html轉pdf
public class Htmltopdf {
private static final Logger LOG = LoggerFactory.getLogger(Htmltopdf.class);
private static final String TOPDFTOOL = "/root/wkhtmltox/bin/wkhtmltopdf";
/**
* html轉pdf
* @param srcPath html路徑,可以是硬盤上的路徑,也可以是網絡路徑
* @param destPath pdf保存路徑
* @return 轉換成功返回true
*/
public static boolean convert(String srcPath, String destPath) {
File file = new File(destPath);
File parent = file.getParentFile();
// 如果pdf保存路徑不存在,則創建路徑
if (!parent.exists()) {
parent.mkdirs();
}
StringBuilder cmd = new StringBuilder();
cmd.append(TOPDFTOOL);
cmd.append(" ");
cmd.append("--page-size A2");// 參數
cmd.append(" ");
cmd.append(srcPath);
cmd.append(" ");
cmd.append(destPath);
boolean result = true;
try {
Process proc = Runtime.getRuntime().exec(cmd.toString());
HtmlToPdfInter error = new HtmlToPdfInter(
proc.getErrorStream());
HtmlToPdfInter output = new HtmlToPdfInter(
proc.getInputStream());
error.start();
output.start();
proc.waitFor();
LOG.info("HTML2PDF成功,參數---html路徑:{},pdf保存路徑 :{}", new Object[] {srcPath, destPath });
} catch (Exception e) {
LOG.error("HTML2PDF失敗,srcPath地址:{},錯誤信息:{}", new Object[]{srcPath, e.getMessage()});
result = false;
}
return result;
}
}
/**
* 當java調用wkhtmltopdf時,用於獲取wkhtmltopdf返回的內容
*/
public class HtmlToPdfInter extends Thread {
private static final Logger LOG = LoggerFactory
.getLogger(HtmlToPdfInter.class);
private InputStream is;
public HtmlToPdfInter(InputStream is) {
this.is = is;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
br.readLine();
} catch (IOException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
}
}
/**
* 測試
*/
public class Test {
public static void main(String[] args) {
String htmlUrl = "www.baidu.com";
String path = "/root/file/pdf_test.pdf";
HtmlToPdf.convert(htmlUrl , path );
}
}
注:html的table中不能用thead,用了後換頁會出現兩個表頭問題如圖:
大概就是這些,如果有什麼問題請留言。