1. 程式人生 > >Java操作wkhtmltopdf實現Html轉PDF

Java操作wkhtmltopdf實現Html轉PDF

做java開發的都知道,java生成pdf大部分都是用itext,itext的確是java開源元件的第一選擇。不過itext也有侷限,就是要自己寫模版,系統中的表單數量有好幾百個,為每個表單做一個匯出模版不現實。 所以找了個直接可以呼叫的工具wkhtmltopdf,將生成好的html直接轉換成pdf。功能很強大。

wkhtmltopdf是一個使用webkit網頁渲染引擎開發的用來將 html轉成 pdf的工具,可以跟多種指令碼語言進行整合來轉換文件。

wkhtmltopdf把html轉成pdf很簡單,只要在windows命令列中輸入c:\wkhtmltopdf.exe http://www.cnblogs.com c:\cnblogs.pdf

就可以把部落格園網頁轉成pdf,並儲存到C盤根目錄。

在java中呼叫wkhtmltopdf的命令Runtime.getRuntime().exec("c:\wkhtmltopdf.exe http://www.cnblogs.com c:\cnblogs.pdf")就可以實現轉換。

下面把命令封裝成java工具類,方便呼叫。

/**
 * 版權所有(C) 2016 www.xiongge.club
 * @author xsw
 * @date 2016-12-8 上午10:17:33 
 */
package wkhtmltopdf;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/** 
 * @ClassName: HtmlToPdfInterceptor 
 * @Description: TODO() 
 * @author xsw
 * @date 2016-12-8 上午10:17:33 
 *  
 
*/ public class HtmlToPdfInterceptor extends Thread { private InputStream is; public HtmlToPdfInterceptor(InputStream is){ this.is = is; } public void run(){ try{ InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br
= new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { System.out.println(line.toString()); //輸出內容 } }catch (IOException e){ e.printStackTrace(); } } }
/**
 * 版權所有(C) 2016 www.xiongge.club
 * @author xsw
 * @date 2016-12-8 上午10:14:54 
 */
package wkhtmltopdf;

import java.io.File;

/** 
 * @ClassName: HtmlToPdf 
 * @Description: TODO() 
 * @author xsw
 * @date 2016-12-8 上午10:14:54 
 *  
 */

public class HtmlToPdf {
    //wkhtmltopdf在系統中的路徑
    private static final String toPdfTool = "D:\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";
    
    /**
     * 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("  --header-line");//頁首下面的線
        cmd.append("  --header-center 這裡是頁首這裡是頁首這裡是頁首這裡是頁首 ");//頁首中間內容
        //cmd.append("  --margin-top 30mm ");//設定頁面上邊距 (default 10mm) 
        cmd.append(" --header-spacing 10 ");//    (設定頁首和內容的距離,預設0)
        cmd.append(srcPath);
        cmd.append(" ");
        cmd.append(destPath);
        
        boolean result = true;
        try{
            Process proc = Runtime.getRuntime().exec(cmd.toString());
            HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());
            HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());
            error.start();
            output.start();
            proc.waitFor();
        }catch(Exception e){
            result = false;
            e.printStackTrace();
        }
        
        return result;
    }
    public static void main(String[] args) {
        HtmlToPdf.convert("http://www.cnblogs.com/xionggeclub/p/6144241.html", "d:/wkhtmltopdf.pdf");
    }
}

附上wkhtmltopdf 引數詳解  

wkhtmltopdf [OPTIONS]... <input file> [More input files] <output file>
常規選項
     --allow <path>  允許載入從指定的資料夾中的檔案或檔案(可重複)
    --book*  設定一會列印一本書的時候,通常設定的選項 
     --collate  列印多份副本時整理 
     --cookie <name> <value>  設定一個額外的cookie(可重複) 
     --cookie-jar <path>  讀取和寫入的Cookie,並在提供的cookie jar檔案 
     --copies <number>  影印列印成pdf檔案數(預設為1) 
     --cover* <url>  使用HTML檔案作為封面。它會帶頁首和頁尾的TOC之前插入 
     --custom-header <name> <value>  設定一個附加的HTTP頭(可重複) 
     --debug-javascript  顯示的javascript除錯輸出 
    --default-header*  新增一個預設的頭部,與頁面的左邊的名稱,頁面數到右邊,例如: --header-left '[webpage]' --header-right '[page]/[toPage]'  --header-line 
     --disable-external-links*  禁止生成連結到遠端網頁
     --disable-internal-links*  禁止使用本地連結
    --disable-javascript  禁止讓網頁執行JavaScript 
     --disable-pdf-compression*  禁止在PDF物件使用無失真壓縮 
     --disable-smart-shrinking*  禁止使用WebKit的智慧戰略收縮,使畫素/ DPI比沒有不變 
     --disallow-local-file-access  禁止允許轉換的本地檔案讀取其他本地檔案,除非explecitily允許用 --allow 
    --dpi <dpi>  顯式更改DPI(這對基於X11的系統沒有任何影響) 
     --enable-plugins  啟用已安裝的外掛(如Flash
     --encoding <encoding>  設定預設的文字編碼 
     --extended-help  顯示更廣泛的幫助,詳細介紹了不常見的命令開關 
     --forms*  開啟HTML表單欄位轉換為PDF表單域 
    --grayscale  PDF格式將在灰階產生
    --help  Display help 
     --htmldoc  輸出程式HTML幫助
     --ignore-load-errors  忽略claimes載入過程中已經遇到了一個錯誤頁面 
    --lowquality  產生低品質的PDF/ PS。有用縮小結果文件的空間 
     --manpage  輸出程式手冊頁 
    --margin-bottom <unitreal>  設定頁面下邊距 (default 10mm) 
    --margin-left <unitreal>  將左邊頁邊距 (default 10mm) 
    --margin-right <unitreal>  設定頁面右邊距 (default 10mm) 
    --margin-top <unitreal>  設定頁面上邊距 (default 10mm) 
     --minimum-font-size <int>  最小字型大小 (default 5) 
     --no-background  不列印背景
    --orientation <orientation>  設定方向為橫向或縱向 
     --page-height <unitreal>  頁面高度 (default unit millimeter) 
     --page-offset* <offset>  設定起始頁碼 (default 1) 
    --page-size <size>  設定紙張大小: A4, Letter, etc. 
    --page-width <unitreal>  頁面寬度 (default unit millimeter) 
     --password <password>  HTTP驗證密碼 
     --post <name> <value>  Add an additional post field (repeatable) 
     --post-file <name> <path>  Post an aditional file (repeatable) 
     --print-media-type*  使用的列印介質型別,而不是螢幕 
    --proxy <proxy>  使用代理 
    --quiet  Be less verbose 
    --read-args-from-stdin  讀取標準輸入的命令列引數 
    --readme  輸出程式自述
    --redirect-delay <msec>  等待幾毫秒為JS-重定向(default 200) 
    --replace* <name> <value>  替換名稱,值的頁首和頁尾(可重複) 
    --stop-slow-scripts  停止執行緩慢的JavaScripts 
    --title <text>  生成的PDF檔案的標題(第一個文件的標題使用,如果沒有指定) 
    --toc*  插入的內容的表中的檔案的開頭
    --use-xserver*  使用X伺服器(一些外掛和其他的東西沒有X11可能無法正常工作) 
    --user-style-sheet <url>  指定使用者的樣式表,載入在每一頁中
    --username <username>  HTTP認證的使用者名稱 
    --version  輸出版本資訊退出
     --zoom <float>  使用這個縮放因子 (default 1) 

頁首和頁尾選項
--header-center*    <text>    (設定在中心位置的頁首內容)  
--header-font-name* <name>    (default Arial)  (設定頁首的字型名稱)
--header-font-size* <size>    (設定頁首的字型大小)
--header-html*  <url> (新增一個HTML頁首,後面是網址)
--header-left*  <text>   (左對齊的頁首文字)
--header-line*      (顯示一條線在頁首下)
--header-right* <text>    (右對齊頁首文字)
--header-spacing*   <real>    (設定頁首和內容的距離,預設0)
--footer-center*    <text>    (設定在中心位置的頁尾內容)  
--footer-font-name* <name>    (設定頁尾的字型名稱) 
--footer-font-size* <size>    (設定頁尾的字型大小default 11)
--footer-html*  <url> (新增一個HTML頁尾,後面是網址)
--footer-left*  <text>    (左對齊的頁尾文字)
--footer-line*      顯示一條線在頁尾內容上)
--footer-right* <text>    (右對齊頁尾文字)
--footer-spacing*   <real>    (設定頁尾和內容的距離)
./wkhtmltopdf --footer-right '[page]/[topage]' http://www.baidu.com baidu.pdf
./wkhtmltopdf --header-center '報表' --header-line --margin-top 2cm --header-line http://192.168.212.139/oma/  oma.pdf
表內容選項中
 --toc-depth* <level>  Set the depth of the toc (default 3) 
 --toc-disable-back-links*  Do not link from section header to toc 
 --toc-disable-links*  Do not link from toc to sections 
 --toc-font-name* <name>  Set the font used for the toc (default Arial) 
 --toc-header-font-name* <name>  The font of the toc header (if unset use --toc-font-name) 
 --toc-header-font-size* <size>  The font size of the toc header (default 15) 
 --toc-header-text* <text>  The header text of the toc (default Table Of Contents) 
 --toc-l1-font-size* <size>  Set the font size on level 1 of the toc (default 12) 
 --toc-l1-indentation* <num>  Set indentation on level 1 of the toc (default 0) 
 --toc-l2-font-size* <size>  Set the font size on level 2 of the toc (default 10) 
 --toc-l2-indentation* <num>  Set indentation on level 2 of the toc (default 20) 
 --toc-l3-font-size* <size>  Set the font size on level 3 of the toc (default 8) 
 --toc-l3-indentation* <num>  Set indentation on level 3 of the toc (default 40) 
 --toc-l4-font-size* <size>  Set the font size on level 4 of the toc (default 6) 
 --toc-l4-indentation* <num>  Set indentation on level 4 of the toc (default 60) 
 --toc-l5-font-size* <size>  Set the font size on level 5 of the toc (default 4) 
 --toc-l5-indentation* <num>  Set indentation on level 5 of the toc (default 80) 
 --toc-l6-font-size* <size>  Set the font size on level 6 of the toc (default 2) 
 --toc-l6-indentation* <num>  Set indentation on level 6 of the toc (default 100) 
 --toc-l7-font-size* <size>  Set the font size on level 7 of the toc (default 0) 
 --toc-l7-indentation* <num>  Set indentation on level 7 of the toc (default 120) 
 --toc-no-dots*  Do not use dots, in the toc
輪廓選項
 --dump-outline <file>  轉儲目錄到一個檔案
 --outline  顯示目錄(文章中h1,h2來定)
 --outline-depth <level>  設定目錄的深度(預設為4)
頁尾和頁首
 * [page]       由當前正在列印的頁的數目代替
 * [frompage]   由要列印的第一頁的數量取代
 * [topage]     由最後一頁要列印的數量取代
 * [webpage]    通過正在列印的頁面的URL替換
 * [section]    由當前節的名稱替換
 * [subsection] 由當前小節的名稱替換
 * [date]       由當前日期系統的本地格式取代
 * [time]       由當前時間,系統的本地格式取代