1. 程式人生 > >PDF技術(四)-Java實現Html轉PDF檔案

PDF技術(四)-Java實現Html轉PDF檔案

html轉換為pdf的關鍵技術是如何處理網頁中複雜的css樣式、以及中文亂碼處理。

各實現對比表

於Windows平臺進行測試:

 

基於IText

基於FlyingSaucer

基於WKHtmlToPdf

基於pd4ml

跨平臺性

跨平臺

跨平臺

跨平臺

跨平臺

是否安裝軟體

需安裝WKHtmlToPdf

是否收費

免費

免費

免費

收費

轉換Html

效率

速度快

未測

速度慢。相比URL來說,效率較慢。能忽略一些html語法或資源是否存在問題。

速度快。部分CSS樣式不支援。

效果

存在樣式失真問題。

對html語法有一定要求

存在樣式失真問題。對html語法有較高要求。

失真情況較小

大部分網頁能按Chome瀏覽器顯示的頁面轉

部分CSS樣式有問題。

轉換URL

效率

未測

未測

效率不是特別高

未測

效果

未測

未測

部分網頁由於其限制,或將出現html網頁不完整。

未測

優點

不需安裝軟體、轉換速度快

不需安裝軟體、轉換速度快

生成PDF質量高

不需要安裝軟體、轉換速度快

缺點

對html標籤嚴格,少一個結束標籤就會報錯;

伺服器需要安裝字型

對html標籤嚴格,少一個結束標籤就會報錯;

伺服器需要安裝字型

 

需要安裝軟體、時間效率不高

對部分CSS樣式不支援。

評價

 

 

 

 

綜合:使用WKHtmlToPdf效果(樣式)最好。但速度較慢(對於檔案來說)。其餘均有大大小小的失真問題。

 

 

分頁

圖片

表格

連結

中文

特殊字元

整體樣式

速度

IText

支援

支援

支援

支援

支援

支援

失真問題

FlyingSaucer

未知

未知

未知

未知

未知

未知

未知

WKHtmlToPdf

支援

支援

支援

支援

支援

支援

很好

pd4ml

支援

支援

支援

支援

支援

支援

失真問題

html網頁完整轉換為pdf,所有的方案均有不足。

itext有時並不能滿足需求,不能相容html的樣式,且從html頁面匯出的圖片到pdf中也並不好處理。

Flying Sauser實現html2pdf,糾錯能力差,支援多種中文字型(部分樣式不能識別),且對html的格式也是十分的嚴格,如果用一種模版的話用Flying Sauser技術倒是不錯的選擇,但對於不規則的html匯出pdf就並不是那麼的適用。

PD4ML實現html2pdf,速度快,糾錯能力強可以過濾不規則的html標記,支援多種中文字型,支援css。

WKHtmlToPdf效果最好,但轉換速度慢。

 

1. wkhtmltopdf(速度慢、需要安裝軟體)

wkhtmltopdf是一個用webkit網頁渲染引擎開發的用來將html轉成 pdf的工具,可跟多種指令碼語言進行整合來轉換文件,有windows、linux等平臺版本。官網地址 http://wkhtmltopdf.org/

 

技術特點

Wkhtmltopdf可直接把瀏覽器中瀏覽的網頁轉換成一個pdf,他是一個把html頁面轉換成pdf的軟體(需要安裝在伺服器上)。使用時可通過java程式碼呼叫cmd指令完成網頁轉換為pdf的功能。

功能測試:

直接在cmd裡輸入測試指令,可檢視處理進度。

https://images2017.cnblogs.com/blog/626790/201707/626790-20170728145110133-2123660962.png

原理:

使用wkhtmltopdf工具對url或html進行轉換

使用命令:

Wkhtmltopdf  https:baidu.com  /usr/local/temp/baidu.pdf

安裝

下載地址:https://wkhtmltopdf.org/downloads.html

wkhtmltopdf安裝方法

1.解壓wkhtmltox.tar到某個資料夾$DIR

2.設定環境變數

vim /etc/profile

在最後一行加 export PATH=$DIR/wkhtmltox/bin:$PATH 儲存退出、

source /etc/profile

3.執行 wkhtmltopdf 報wkhtmltopdf: error while loading shared libraries: libXrender.so.1: cannot open shared object file: No such file or directory這個錯,請執行 apt-get/yum install libXrender*

執行 wkhtmltopdf 報wkhtmltopdf: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory這個錯,請執行apt-get/yum install libfontconfig*

執行 wkhtmltopdf 報wkhtmltopdf: error while loading shared libraries: libXext.so.6: cannot open shared object file: No such file or directory這個錯,請執行 apt-get/yum install libXext*

 

執行 wkhtmltopdf

yum install xorg-x11-fonts-75dpi.noarch

yum install xorg-x11-fonts-Type1.noarch

yum install icu.x86_64

yum install libjpeg

yum install libpng

 

優點:

支援中文、圖片、CSS等

缺點:

有時對於html檔案的轉化可能比較慢,對於url的轉化速度較快。存在失真情況

具體實現:

Java呼叫命令。

public class HtmlToPdf {

    // wkhtmltopdf在系統中的路徑
    private static String toPdfTool = Consts.WEB.CONVERSION_PLUGSTOOL_PATH_WINDOW;

    /**
     * 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();
        if (System.getProperty("os.name").indexOf("Windows") == -1) {
            // 非windows 系統
            toPdfTool = Consts.WEB.CONVERSION_PLUGSTOOL_PATH_LINUX;
        }
        cmd.append(toPdfTool);
        cmd.append(" ");
        cmd.append(" \"");
        cmd.append(srcPath);
        cmd.append("\" ");
        cmd.append(" ");
        cmd.append(destPath);

        System.out.println(cmd.toString());
        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.baidu.com", "F:/pdf/baidu.pdf");
        String filename = "JAVA將圖片轉換成pdf檔案-CSDN部落格";
        HtmlToPdf.convert("F:/pdf/"+filename+".html", "F:/pdf/"+filename+".pdf");
//        HtmlToPdf.convert("http://api.gyingyuan.com/", "F:/pdf/"+ UUID.randomUUID().toString()+".pdf");
//        HtmlToPdf.convert("https://www.aliyun.com/jiaocheng/285649.html", "F:/pdf/baidu.pdf");
    }
}
public class HtmlToPdfInterceptor extends Thread {
    private InputStream is;

    public HtmlToPdfInterceptor(InputStream is){
        this.is = is;
    }

    @Override
    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();
        }
    }
}

效果:

URL轉換

 

 

對於url轉會遇到一些網站限制的問題。

https://blog.csdn.net/m0_38138387/article/details/79314260

如果轉為html則效率較慢,但能很大程度比較完美地轉換

檔案轉換:速度較慢,失真情況比較小

68.225s

 

2. PhantomJS(樣式有問題,需要安裝軟體)

PhantomJS是一個基於webkit核心的無頭瀏覽器,即沒有UI介面,即它是一個瀏覽器,只是其內的點選、翻頁等人為相關操作需要程式設計實現。它提供javaScript API介面,即通過編寫JS程式可以直接與webkit核心互動,在此之上可以結合java語言等,通過java呼叫js等相關操作,從而解決了以前c/c++才能比較好的基於webkit開發優質採集器的限制。它同時提供windows、linux、mac等不同os的安裝使用包,也就是說可以在不同平臺上二次開發採集專案或是自動專案測試等工作。官網地址http://phantomjs.org/

PhantomJS可做網頁分析,功能很多,本次僅呼叫網頁的截圖功能。在cmd中的測試如下:

https://images2017.cnblogs.com/blog/626790/201707/626790-20170728151542321-313520.png

URL轉

測試效果並沒有wkhtmltopdf好。

html2pdf.js

var page = require('webpage').create();
var system = require('system');
 
////讀取命令列引數,也就是js檔案路徑。
if (system.args.length === 1) {
  console.log('Usage: loadspeed.js <some URL>');
//這行程式碼很重要。凡是結束必須呼叫。否則phantomjs不會停止
  phantom.exit();
}
page.settings.loadImages = true;  //載入圖片
page.settings.resourceTimeout = 30000;//超過10秒放棄載入
//截圖設定,
//page.viewportSize = {
//  width: 1000,
//  height: 3000
//};
var address = system.args[1];
page.open(address, function(status) {
	
	function checkReadyState() {//等待載入完成將頁面生成pdf
        setTimeout(function () {
            var readyState = page.evaluate(function () {
                return document.readyState;
            });
 
            if ("complete" === readyState) {
                
				page.paperSize = { width:'297mm',height:'500mm',orientation: 'portrait',border: '1cm' };
				var timestamp = Date.parse(new Date());
				var pdfname = 'HT_'+timestamp + Math.floor(Math.random()*1000000);
				var outpathstr = "E:/POMFiles/HTPDF/"+pdfname+".pdf";
				page.render(outpathstr);
				//page.render("c://test.png");
				//console.log就是傳輸回去的內容。
				console.log("生成成功");
				console.log("$"+outpathstr+"$");
				phantom.exit(); 
				
            } else {
                checkReadyState();
            }
        },1000);
    }
    checkReadyState();
});

PhantomJS對bootstap的樣式支援較好。對css3的新特性如圓形圖片樣式支援行不好。部分頁面樣式會失效。對於echart圖表展示,也可直接匯出

 

 

3. IText(技術老舊,對樣式不支援)

iText是一個第三方報表java外掛,可以在後端利用java隨意生成、轉化pdf檔案,提供了很多api,比較靈活

IText實現html2pdf,速度快,糾錯能力差,支援中文(要求HTML使用unicode編碼),但中支援一種中文字型,開源。

原理:

使用IText將HTML檔案轉化為PDF檔案

優點:

速度快,支援中文(要求HTML使用unicode編碼)、開源

缺點:

糾錯能力差,

對CSS樣式支援不是很好。

失真情況可能比較大

具體實現:

<dependency>
    <groupId>org.eclipse.birt.runtime.3_7_1</groupId>
    <artifactId>com.lowagie.text</artifactId>
    <version>2.1.7</version>
</dependency>
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf</artifactId>
    <version>9.0.8</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.4.2</version>
</dependency>

Java程式碼

ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("/Users/hehe/share/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
OutputStream os = new FileOutputStream("/Users/hehe/Desktop/iTextPDF.pdf");
String htmlstr = HttpHandler.sendGet("http://localhost:10086/test/iTextPDF.html");//HttpHandler.sendGet只是單純獲得指定網頁的html字串內容
renderer.setDocumentFromString(htmlstr);
renderer.layout();
renderer.createPDF(os);

以上只是簡單利用html字串來生成pdf,需要注意的是: 
1、如果頁面中有中文,伺服器端需要下載字型庫simsun.ttc,在後臺進行引用,同時在頁面的樣式中加入對應字型的定義,如:body{font-family: SimSun;},否則中文無法渲染(中文處渲染出來的效果是空白); 
2、頁面中如果有圖片,如果圖片引用是絕對路徑或者base64則不用考慮,如果是相對路徑,需要在後臺用renderer.getSharedContext().setBaseURL("圖片絕對路徑目錄");來指定圖片路徑,否則圖片無法渲染。 
3、要轉化的頁面必須是標準的XHTML頁面,有一處不符合規範就會報錯,小編再試的時候就經常報諸如org.xml.sax.SAXParseException;lineNumber: 24; columnNumber: 6;元素型別 "span" 必須由匹配的結束標記 "</span> 終止"之類的錯誤,所以如果要用iText來大量爬取網路中的頁面的話,還是放棄吧,畢竟網上很多頁面都是不標準的~

public class HtmlToPdfUtils {
    /*** 預設中文字型   */
    private static final String FONT = "C:\\Windows\\Fonts\\simhei.ttf";
    public static void htmlToPdf(String sourcePath,String tagetPath) throws IOException {
        htmlToPdf(sourcePath,tagetPath,FONT);
    }
    public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath) throws IOException {
        htmlToPdf(sourcePath,tagetPath,fontPath,PageSize.TABLOID);
    }
    public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath,PageSize pageSize) throws IOException {
        // 預設source路徑下裝載有css、image、以及html等檔案的資料夾
        htmlToPdf(sourcePath,tagetPath,fontPath,pageSize,FileUtils.GetFilePath(sourcePath));
    }
    public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath,PageSize pageSize,String baseuri) throws IOException {
        PdfWriter writer = new PdfWriter(tagetPath);
        PdfDocument pdf = new PdfDocument(writer);

        pdf.setTagged();
        // 設定pdf頁面大小
        pdf.setDefaultPageSize(pageSize); 
        ConverterProperties properties = new ConverterProperties();
        FontProvider fontProvider = new DefaultFontProvider();
        // 字型
        FontProgram fontProgram = FontProgramFactory.createFont(fontPath);
        fontProvider.addFont(fontProgram);
        properties.setFontProvider(fontProvider); 
        //properties.setBaseUri(html);
        properties.setBaseUri(baseuri); 
        MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
        mediaDeviceDescription.setWidth(pageSize.getWidth());
        properties.setMediaDeviceDescription(mediaDeviceDescription); 
        // 轉化
        convertToPdf(sourcePath,pdf, properties);
    }

    private static void convertToPdf(String sourcePath,PdfDocument pdf,ConverterProperties properties ) throws IOException {
        InputStream inputStream = new FileInputStream(sourcePath);
        // 轉化
//        HtmlConverter.convertToPdf(new FileInputStream(sourcePath), pdf, properties);
        HtmlConverter.convertToPdf(inputStream, pdf, properties);
        inputStream.close();
    }
    public static void main(String[] args) throws IOException {
        htmlToPdf("F:\\pdf\\1.html","F:\\pdf\\est-04.pdf");
    }
}

 

效果:

Converting HTML to PDF _ iText Developers.html

消耗時間:3660

CSS樣式丟失:

 

JAVA 將圖片轉換成pdf檔案 - CSDN部落格.html

消耗時間:7609

樣式同樣丟失問題

itext html轉pdf佈局問題_百度搜索.html

消耗時間:5485

 

4. Flying Sauser(技術老舊,對樣式不支援)

Flying Sauser實現html2pdf,糾錯能力差,支援中文、支援簡單的頁面和樣式,開源

對html程式碼要求很嚴格。極易出現中文亂碼問題

 

優點:

支援多種中文字型(部分樣式不能識別),開源

缺點:

糾錯能力差,對CSS支援不是很好。當頁面內容較長時,處理時間慢

具體實現:

public class Html2Pdf {
    /**
     * HTML程式碼轉PDF文件
     *
     * @param content 待轉換的HTML程式碼
     * @param storagePath 儲存為PDF檔案的路徑
     */
    public static void parsePdf(String content, String storagePath) {
        FileOutputStream os = null;
        try {
            File file = new File(storagePath);
            if(!file.exists()) {
                file.createNewFile();
            }
            os = new FileOutputStream(file);

            ITextRenderer renderer = new ITextRenderer();
//解決中文支援問題
//            ITextFontResolver resolver = renderer.getFontResolver();
//            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            renderer.setDocumentFromString(content);
// 解決圖片的相對路徑問題,圖片路徑必須以file開頭
// renderer.getSharedContext().setBaseURL("file:/");
            renderer.layout();
            renderer.createPDF(os);

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 對Html要求特別嚴格
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String htmlFilePath = "";
        htmlFilePath = "F:/pdf/IText實現對PDF文件屬性的基本設定 - 半畝池光 - 部落格園.html";
        StringBuilder content = new StringBuilder();
        BufferedInputStream in;
        byte[] bys = new byte[1024];
        int len;
        in = new BufferedInputStream(new FileInputStream(htmlFilePath));
        while ((len = in.read(bys)) != -1) {
            content.append(new String(bys, 0, len));
        }
        String html = closeHTML(content.toString());
        html = html.replace("&nbsp;","&#160;");

        parsePdf(html,"F:/pdf/wahaha.pdf");

    }

    public static String closeHTML(String str){
        List arrTags = new ArrayList();
        arrTags.add("br");
        arrTags.add("hr");
        arrTags.add("link");
        arrTags.add("meta");
        arrTags.add("img");
        arrTags.add("input");
        for(int i=0;i<arrTags.size();i++){
            for(int j=0;j<str.length();){
                int tagStart = str.indexOf("<"+arrTags.get(i),j);
                if(tagStart>=0){
                    int tagEnd = str.indexOf(">",tagStart);
                    j = tagEnd;
                    String preCloseTag = str.substring(tagEnd-1,tagEnd);
                    if(!"/".equals(preCloseTag)){
                        String preStr = str.substring(0,tagEnd);
                        String afterStr = str.substring(tagEnd);
                        str = preStr + "/" + afterStr;
                    }
                }else{
                    break;
                }
            }
        }
        return str;
    }

}

 

5. PD4ML(樣式有問題)

PD4ML是純Java的類庫,使用HTMLCSS作為頁面佈局和內容定義格式來生成PDF文件的強大工具,可以簡化終端使用者生成PDF的工作。參考網站:http://www.pd4ml.com

 

優點:

支援中文、對html程式碼不嚴格、速度較快

支援的HTML標籤、CSS屬性較全,轉換失真比較小,可以使用HTML+CSS實現精確的佈局控制。

對網頁檔案標籤、CSS語法錯誤的容錯性比較好。

對不用額外的控制,就支援圖片的轉化輸出。

 

缺點:

存在樣式失真問題,CSS支援較不好。

不開源,最新的demo版本,下載測試以後,發現不支援中文轉換。必須購買商業版本才可以。(這裡很坑,測試亂碼問題通不過,後面發現是本來就不支援)。

破解後的一些舊版本可以解決亂碼問題,但是支援的css樣式沒有新版本的全。

具體實現:

public class HtmlToPDFUtil {
	public static void main(String[] args) throws Exception {
		//HtmlToPDFUtil htmlToPDFUtil = new HtmlToPDFUtil();
		HtmlToPDFUtil.generatePDF_2(new File("F:\\pdf/demo_ch_pd4ml.pdf"),
				"F:\\pdf/flying saucer 使用中的一些問題 (java匯出pdf) - 真的勇士,敢於直面這扯淡的人生 - ITeye部落格.htm");

		//File pdfFile = new File("D:/Test/test3.pdf");
//		String pdfPath = "D:/Test1/mmt";
//
//		File file = new File(pdfPath);
//		if (!file.exists()) {
//			file.mkdirs();
//		}
//		String pdfName = "aa.pdf";
//		File pdfFile = new File(pdfPath+File.separator+pdfName);
//		StringBuffer html = new StringBuffer();
//		html.append("<html>")
//				.append("<head>")
//				.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />")
//				.append("</head>").append("<body>")
//				//.append("<font face='KaiTi_GB2312'>")
//				.append("<font face='KaiTi'>")
//				.append("<font color='red' size=22>顯示中文aaaaaaaaaa</font>")
//				.append("</font>").append("</body></html>");
//		StringReader strReader = new StringReader(html.toString());
//		HtmlToPDFUtil.generatePDF_1(pdfFile, strReader);

	}

	// 手動構造HTML程式碼
	public static void generatePDF_1(File outputPDFFile, StringReader strReader)
			throws Exception {
		FileOutputStream fos = new FileOutputStream(outputPDFFile);
		PD4ML pd4ml = new PD4ML();
		pd4ml.setPageInsets(new Insets(20, 10, 10, 10));
		pd4ml.setHtmlWidth(950);
		pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));
		pd4ml.useTTF("java:fonts", true);		
		//pd4ml.setDefaultTTFs("KaiTi_GB2312", "KaiTi_GB2312", "KaiTi_GB2312");
		pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");
		pd4ml.enableDebugInfo();
		pd4ml.render(strReader, fos);
	}

	// HTML程式碼來自於HTML檔案
	public static void generatePDF_2(File outputPDFFile, String inputHTMLFileName)
			throws Exception {
		FileOutputStream fos = new FileOutputStream(outputPDFFile);
		PD4ML pd4ml = new PD4ML();
		pd4ml.setPageInsets(new Insets(20, 10, 10, 10));
		pd4ml.setHtmlWidth(950);
		pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));

		pd4ml.useTTF("java:fonts", true);
		pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");
		pd4ml.enableDebugInfo();
		pd4ml.render("file:" + inputHTMLFileName, fos);
	}

}

pd4browser和pd4fonts是生成的

亂碼解決方案:
https://blog.csdn.net/u014769730/article/details/54375836

測試結果:

對CSS有一定的要求

部分Html能支援:

 

 

6. Sferyx:(樣式有問題)

官網:https://www.sferyx.com/pdfgenerator/html-to-pdf-java.htm

支援URL、支援檔案。支援中文,對html檔案幾乎無要求。樣式不佳,中文字型支援不佳。

具體實現

引入Java包:PDFGenerator.jar

程式碼:

        PDFGenerator pdfGenerator=new PDFGenerator();
        pdfGenerator.setMarginsForStandardPageFormat (10,10,10,10);
//        pdfGenerator.setCharset ("utf-8");
        pdfGenerator.setCharset("ISO-10646-UCS-2");
//        pdfGenerator.generatePDFFromURL ("https://blog.csdn.net/gisboygogogo/article/details/77601308",
        pdfGenerator.generatePDFFromURL ("F:\\pdf\\1.html",
                "F:\\pdf/pdfgenerator-test1.pdf",
                "A4", "Portrait");

樣式問題:

 

 

7. jPDFWriter(樣式有問題、對html檔案支援不好)

具體實現:

//        URL url = new URL("https://www.baidu.com/");
//        PageFormat pf = new PageFormat();
//        PDFDocument pdfDoc = PDFDocument.loadHTML (url, pf, true);
//        pdfDoc.saveDocument ("F:\\pdf\\output.pdf");
        File f1 = new File ("F:\\pdf\\1.html");
        PDFDocument pdfDoc = PDFDocument.loadHTML(f1.toURI().toURL(), new PageFormat (), false);
        pdfDoc.saveDocument ("F:\\pdf\\output.pdf");

效果:

並不是很好,雖然支援中文

 

其他未知方案。。。。。。。。。。

 

 

線上轉換方案:

僅支援URL,但能很好地轉換,效果較好,速度較快。但收費,且為第三方服務,或有資訊保安性問題。

如果不考慮html檔案安全性的話,可以考慮。

 

以轉CSDN及百度搜索網頁為測試例。

1. restpack

官網:https://restpack.io/                    

能很好保持樣式,且支援中文,速度快。價格相比較優惠。

測試效果:

實現方法:

HttpResponse<String> response = Unirest.post("https://restpack.io/api/html2pdf/v5/convert")
  .header("x-access-token", "TOKEN")
  .body("url=http%3A%2F%2Fgoogle.com&json=true")
  .asString();

 

2. pdfshift

官網:https://pdfshift.io

能很好保持樣式,且支援中文,速度快。價格相比較優惠。

測試效果:

 

實現方法:

String encoding = Base64.getEncoder().encodeToString("YOUR_API_KEY:".getBytes());
HttpPost httppost = new HttpPost("https://api.pdfshift.io/v2/convert/");
httppost.setHeader("Authorization", "Basic " + encoding);
httppost.setHeader("Content-type", "application/json");

HttpEntity postingString = new StringEntity("{\"source\":\"https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=PhantomJS%20html%E8%BD%ACpdf&oq=PhantomJS&rsv_pq=c942451400041f65&rsv_t=3566cYExdLkZv6pJRhDXeda3WgHs37R3GASuPvnEGrOmBl9Lur2EMGyfdF8&rqlang=cn&rsv_enter=1&rsv_sug3=15&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&inputT=6104&rsv_sug4=6105\",\"landscape\":false,\"use_print\":false}");
httppost.setEntity(postingString);

CloseableHttpClient client = HttpClients.createDefault();
try (CloseableHttpResponse response = client.execute(httppost)) {
    HttpEntity entity = response.getEntity();
    // Use the entity
}

 

3.其他(不考慮的方案)

1. pdfmyurl(網站反應慢)

官網:http://pdfmyurl.com/  

轉化效率極低,速度極其慢

 

2. pdflayer(不支援中文)

官網:https://pdflayer.com/

不支援中文。雖然能很好保持樣式。

 

個人總結:

到現在未知併為找到完美的方案。各種方案都有缺點,但是線上轉換的方案轉化效率以及對CSS等支援程度比較好。也不知道他們這些內部是如何實現的。
 

參考連結:

http://blog.csdn.net/ouyhong123/article/details/26401967

http://blog.csdn.net/tengdazhang770960436/article/details/41320079

http://www.cnblogs.com/jasondan/p/4108263.html

http://blog.csdn.net/accountwcx/article/details/46785437

http://blog.csdn.net/zdtwyjp/article/details/5769353