通过wkhtmltopdf免费组件,完成Html向PDF转换
最近需要完成批量将文件服务器上的html转换为PDF的工作。本来希望通过PDFCreator将htm页面打印为PDF文件,但因其调用了IE的打印功能,不可避免的弹出对话框,而我的任务是制作后台服务,这就比较麻烦了。
于是去查找一些转换组件,但大都是要收费的,之后无意中发现了wkhtmltopdf,该组件确实可以解决大问题。
该组件的下载地址:http://code.google.com/p/wkhtmltopdf/
该组件既可以通过如下方式,直接将网页内容转换为PDF:
wkhtmltopdf "http://www.verycd.com/", "verycd.pdf"
也可以直接将本地的HTML文件转换为PDF文件:
wkhtmltopdf.exe
[本地Html的Uri](您可以用Uri url = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "501033.htm"));将其转换为可识别的uri字符串)
"D:\Blade\MorningStar.Demo\MorningStar.Blade.HtmlToPDFDemo\MorningStar.Blade.HtmlToPDFDemo\bin\Debug\501033.pdf"
需要注意的是:使用wkhtmltopdf时,PDF保存的文件夹不能有非Ansi字符,如中文、日文等,且转换gb2312、韩文charset、日文charset等非utf-8\ansi等网页时,会出现乱码
HtmlToPDF
1using System;
2using System.Diagnostics;
3using System.IO;
4using Common.Logging;
5using System.Threading;
6
7namespace MorningStar.HtmlToPDFLibrary
8{
9 public class HtmlToPDF
10 {
11 private static ILog _log = LogManager.GetLogger(typeof(HtmlToPDF));
12
13 /**//// <summary>
14 /// HTML Convert to PDF
15 /// </summary>
16 /// <param name="url">URL</param>
17 /// <param name="path">PDF File Path</param>
18 public static bool HtmlToPdf(string url, string path)
19 {
20 try
21 {
22 if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(path))
23 {
24 return false;
25 }
26 using (Process p = new Process())
27 {
28 string str = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf.exe");
29 if (!File.Exists(str))
30 {
31 return false;
32 }
33 KillWKHtmltoPDF();
34
35 p.StartInfo.FileName = str;
36 p.StartInfo.Arguments = String.Format("\"{0}\" \"{1}\"", url, path);
37 p.StartInfo.UseShellExecute = false;
38 p.StartInfo.RedirectStandardInput = true;
39 p.StartInfo.RedirectStandardOutput = true;
40 p.StartInfo.RedirectStandardError = true;
41 p.StartInfo.CreateNoWindow = true;
42 p.Start();
43 _log.Info("HtmlToPdf:Convert Begin");
44 return ConfirmConvertSuccess(path);
45 }
46 }
47 catch (Exception ex)
48 {
49 _log.Warn(ex.Message,ex);
50 }
51 return false;
52 }
53
54 private static bool ConfirmConvertSuccess(string path)
55 {
56 int count = 0;
57 bool isSuccessful = true;
58
59 while (true)
60 {
61 if (File.Exists(path))
62 {
63 _log.Info("HtmlToPdf:Waiting For Converting Completion ..");
64 WaitWKHtmltoPDFClose();
65 _log.Info("HtmlToPdf:Convert Successfully!");
66 break;
67 }
68 Thread.Sleep(1000);
69 count++;
70 if (count >= 300)
71 {
72 _log.Warn("HtmlToPdf:Convert Time Out,Convert Fail!");
73 isSuccessful = false;
74 break;
75 }
76 }
77
78 return isSuccessful;
79 }
80
81 private static void WaitWKHtmltoPDFClose()
82 {
83 while (true)
84 {
85 Process[] procs = Process.GetProcessesByName("wkhtmltopdf");
86 if (procs.Length > 0)
87 {
88 Thread.Sleep(5000);
89 }
90 else
91 {
92 break;
93 }
94 }
95 }
96
97 /**//// <summary>
98 /// Kill WKHTMLTOPDF exe
99 /// </summary>
100 private static void KillWKHtmltoPDF()
101 {
102 try
103 {
104 Process[] procs = Process.GetProcessesByName("wkhtmltopdf");
105 Array.ForEach(procs,
106 delegate(Process proc)
107 {
108 proc.Kill();
109 });
110 }
111 catch (Exception ex)
112 {
113 _log.Warn(ex.Message, ex);
114 }
115 }
116 }
117}
118