最近花了2天多的時間終於把HTML生成PDF弄好了。步驟以下:css
一、首先是技術選型。看了好多都是收費的就不考慮了。html
免費的有:前端
- jsPDF(前端生成,清晰度不高,生成比較慢)
- iText(嚴格要求html標籤。這個好像也是收費的)
- wkhtmltopdf(簡單、配置選項多、生成快、支持跨平臺、也支持HTML生成圖片)
所以選擇wkhtmltopdf。cookie
二、前期準備,首先須要下載wkhtmltopdf.exe(下載地址:https://wkhtmltopdf.org/downloads.html)閱讀配置參數(https://wkhtmltopdf.org/usage/wkhtmltopdf.txt)ui
經常使用參數:url
- -T 0 :設置上下左右margin-top=0(-B 0 -L 0 -R 0 -T 0,上下左右都設置一下)
- -s A4:設置A4紙大小,默認A4
- --disable-smart-shrinking:禁止縮放(不設置這個,生成的pdf會縮放)
- --zoom 1:設置縮放係數,默認爲1。若是--disable-smart-shrinking設置了,--zoom就不用設置了。
- --cookie name value:設置cookie,若是下載的url須要登陸(用cookie),那麼這個參數很重要。
三、設置須要打印的頁面(核心是分頁)spa
A4紙大小:210mm×297mm,所以頁面的每一個div大小也是A4紙大小。code
這裏的頁面設置很重要。另外,設置了分頁的頁碼,示例以下:htm
<style> #view { height: 100%; margin: auto; padding: 0; width: 210mm; } /*設置A4打印頁面*/ /*備註:因爲@是否特殊符號,樣式放在css文件中沒問題,放在cshtml文件就不行了,須要@@。*/ @preview-item { size: A4; margin: 0; } @media print { .preview-item { margin: 0; border: initial; border-radius: initial; width: initial; min-height: initial; box-shadow: initial; background: initial; page-break-after: always; } } .preview-item { width: 100%; height: 297mm; position: relative; } .page-view { position: absolute; width: 100%; text-align: center; height: 60px; line-height: 60px; bottom: 0; } </style> <div id="view"> <div class="preview-item"> <div class="preview-item-body">這是第一頁</div> <div class="page-view">1/3</div> </div> <div class="preview-item"> <div class="preview-item-body">這是第二頁</div> <div class="page-view">2/3</div> </div> <div class="preview-item"> <div class="preview-item-body">這是第三頁</div> <div class="page-view">3/3</div> </div> </div>
四、C#代碼實現(核心是Arguments的設置)blog
/// <summary> /// HTML生成PDF /// </summary> /// <param name="url">url地址(須要包含HTTP://)</param> /// <param name="path">PDF存放路徑(能夠是aaa.pdf,也能夠用路徑,只能是絕對地址,如:D://aaa.pdf)</param> public static bool HtmlToPdf(string url, string path) { path = HttpContext.Current.Server.MapPath(path);string cookie = "cookieKey cookieValue";//改成爲你本身的 string Arguments = "-q -B 0 -L 0 -R 0 -T 0 -s A4 --no-background --disable-smart-shrinking --cookie " + cookie + " " + url + " " + path; //參數能夠根據本身的須要進行修改 try { if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(path)) return false; var p = new Process(); string str = HttpContext.Current.Server.MapPath("/htmlToPDF/wkhtmltopdf.exe"); if (!File.Exists(str)) return false; p.StartInfo.FileName = str; p.StartInfo.Arguments = Arguments; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = false; p.Start(); p.WaitForExit(); System.Threading.Thread.Sleep(1000); return true; } catch (Exception ex) { LogHelper.WriteError(ex); } return false; }
方法的調用:
string url = Request.Url.AbsoluteUri.Replace("DownloadPDF", "Detail");//DownloadPDF是下載頁面,Detail是上面的HTML頁面 string pdfDirectory = "/Data/PDF/"; if (!System.IO.Directory.Exists(HttpContext.Current.Server.MapPath(pdfDirectory))) { System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(pdfDirectory)); } string path = pdfDirectory + Guid.NewGuid() + ".pdf"; HtmlToPdf(url, path); if (!System.IO.File.Exists(Utils.GetMapPath(path)))//若是生成失敗,重試一次 { HtmlToPdfHelper.HtmlToPdf(url, path); } if (!System.IO.File.Exists(Utils.GetMapPath(path)))//若是生成失敗,重試一次 { HtmlToPdfHelper.HtmlToPdf(url, path); }
五、ok,採坑結束~