1、使用背景
最近公司需要把html頁面的內容生成pdf並下載,試過很多方法都沒有滿意的效果,后來找到wkhtmltopdf這款軟件,終於解決了這個問題。
wkhtmltopdf是exe文件,需要下載安裝,之后全部文件放到mvc項目,用C#的ProcessStartInfo調用執行。
要導出的html頁面:
2、下載安裝
官網:https://wkhtmltopdf.org/。
主頁download里下載對應系統的版本安裝並把安裝后的文件放到vs里面方便之后調用。
3、使用的參數
wkhtmltopdf的參數有四種: 封面對象、目錄對象、文檔對象和頁面對象。這里需要用到的是文檔對象和頁面對象。
還有很多其他參數,具體的參數列表可以看官方文檔:https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
使用方法:wkhtmltop
df [GLOBAL OPTION]... [OBJECT]... <output file>
從左到右依次是:命令開始、使用灰度模式、禁止智能縮放、設置頁眉為html文件、生成pdf的頁面網址、生成的pdf文件名稱。
上面是在命令提示符使用的方式,在mvc里使用:

1 ProcessStartInfo startInfo = new ProcessStartInfo(); 2 startInfo.FileName = file; 3 startInfo.Arguments = "wkhtmltopdf --grayscale --disable-smart-shrinking --header-html head.html https://www.baidu.com 123.pdf"; 4 startInfo.CreateNoWindow = true; 5 startInfo.WindowStyle = ProcessWindowStyle.Hidden; 6 var cc = Process.Start(startInfo); 7 cc.WaitForExit(); 8 cc.Close();
4、添加水印
公司要求生成的pdf需要添加水印,每頁pdf顯示兩個logo水印圖片。開始是用給每個div設置背景圖片的方式添加水印,讓背景圖片以y軸重復。由於每個div的高度不定,導致一個水印生成在兩個pdf頁面,影響美觀,果斷放棄。后來使用頁眉設置html的方式來顯示水印,這里要注意的是,頁眉會占用html的位置,所以我用before和after偽元素來寫兩個logo水印。
水印效果圖:

1 <!DOCTYPE html>
2 <html>
3 <head>
4 <style>
5 * { margin:0;padding:0;}
6 #divd::before{content:"";width:400px;height:400px;background:url(mark.png);position:absolute;opacity:0.3;left:50%;margin-left:-200px;}
7 #divd::after{content:"";width:400px;height:400px;background:url(mark.png);position:absolute;opacity:0.3;left:50%;margin-left:-200px;top:400px}
8 </style>
9 </head>
10 <body style="border:0; margin: 0;">
11 <div id="divd" style=""></div>
12 </body>
13 </html>
之后只要用--header-html head.html方式調用這個頁面就會每頁pdf生成兩個水印圖片。
5、pdf分頁
默認pdf生成是把內容從上往下寫入,並不好看,導出的pdf效果:
公司要求每個div處需要從新的頁開始,這里給需要分頁的div添加page-break-before:left樣式即可,最終pdf效果:
6、其他
a、如果有td或者th需要隱藏border,需要使用這個樣式border:0。
b、生成的pdf設置間距時用padding不用margin,類似“padding:1px 2px 3px 4px”這種樣式要改成“padding-top:1px;padding-right:2px;padding-bottom:3px;padding-left:4px;”。
c、html里面如果有font-family樣式和h1、h2、h3標簽也會出錯;解決方法是去掉或者替換這些字符串。