本篇作為一個備忘,記錄一下html轉pdf中遇到的問題。
沒有具體做這個東西的時候不知道,網絡上能將html轉換成pdf的資源並不太多,使用上有很多都存在一些問題。能完美將一個站點中的頁面(這里說一個站點中的頁面是指非特意制作只包含簡單html元素的網頁)轉換成pdf的很多都是收費的項目。
這里不討論itextsharp,因為我們指明了源是html頁面,itextsharp對html的支持比較雞肋,他的靈活體現在手動繪制pdf上。
我們的系統中原本使用了Pechkin這款開源產品,這款產品使用簡單,而且轉換出來的pdf與原頁面看不出來差別。但Pechkin依賴於很多32位dll,這樣應用程序必須運行在32位進程中。
為了使程序運行在64位進程中,嘗試了很多,最后發現這個項目:https://github.com/vilppu/OpenHtmlToPdf
OpenHtmlToPdf與Pechkin的內部原理一樣,都是封裝了wkHtmlToPdf來實現的轉換。
wkHtmlToPdf內部包含了一個瀏覽器引擎:Webkit,所以它能對html頁面的還原比較真實,官方上看wkHtmlToPdf還曾發布過使用其他瀏覽器引擎的分支項目,有興趣的話也可以去嘗試一下。
OpenHtmlToPdf內部包含了32位和64位wkHtmlToPdf兩個應用程序,使用命令的方式去調用不同的exe,以此來實現在兩種進程中兼容。
其還提供了豐富的調用參數可供使用:http://wkhtmltopdf.org/libwkhtmltox/pagesettings.html
當然,因為wkhtmltopdf本身就是比較老的項目了,這里面有些參數我嘗試后並沒有得到什么效果。
使用示例:
using (WebClient wc = new WebClient()) { wc.Encoding = Encoding.UTF8; string html = wc.DownloadString(url); var document = Pdf.From(html) .OfSize(OpenHtmlToPdf.PaperSize.LetterRotated) .WithGlobalSetting("margin.top", "0.4cm"); if (IntPtr.Size == 4) { document = document.WithObjectSetting("load.zoomFactor", "1.5"); } var result = document.Content(); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=PDF" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".pdf"); HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.BinaryWrite(result); HttpContext.Current.Response.End(); }
這個東西使用中也遇到一些問題。
看代碼可以發現在32位進程的時候,我對文檔做了特殊處理,使用load.zoomFactor做了放大。
因為使用中發現其在32位中生成的pdf比64位中生成的pdf小了一些,我並沒能找到和直接解決這個詭異的問題,最后找了這個放大的參數(這個應該是對瀏覽器引擎操作的參數),使其在兩種環境中生成的pdf尺寸基本一致。。
當然,其實我們一般用不到一個web程序支持兩種cpu進程,這只是為了在開發調試階段使不同的開發者環境呈現的內容一致。