最近有一个需求,需要将HTML页面转换为PDF文件.
using System; using System.Diagnostics; using System.Text; using System.IO; using System.Web; namespace Codaxy.WkHtmlToPdf { public class PdfConvertException : Exception { public PdfConvertException(String msg) : base(msg) { } } public class PdfConvertTimeoutException : PdfConvertException { public PdfConvertTimeoutException() : base("HTML to PDF conversion process has not finished in the given period.") { } } public class PdfOutput { public String OutputFilePath { get; set; } public Stream OutputStream { get; set; } public Action<PdfDocument, byte[]> OutputCallback { get; set; } } public class PdfDocument { public String Url { get; set; } public String Html { get; set; } public String HeaderUrl { get; set; } public String FooterUrl { get; set; } public object State { get; set; } } public class PdfConvertEnvironment { public String TempFolderPath { get; set; } public String WkHtmlToPdfPath { get; set; } public int Timeout { get; set; } public bool Debug { get; set; } } public class PdfConvert { static PdfConvertEnvironment _e; public static PdfConvertEnvironment Environment { get { if (_e == null) _e = new PdfConvertEnvironment { TempFolderPath = Path.GetTempPath(), WkHtmlToPdfPath = Path.Combine(OSUtil.GetProgramFilesx86Path(), @"wkhtmltopdf\wkhtmltopdf.exe"), Timeout = 60000 }; return _e; } } public static void ConvertHtmlToPdf(PdfDocument document, PdfOutput output) { ConvertHtmlToPdf(document, null, output); } public static void ConvertHtmlToPdf(PdfDocument document, PdfConvertEnvironment environment, PdfOutput woutput) { if (document.Url == "-" && document.Html == null) throw new PdfConvertException( String.Format("You must supply a HTML string, if you have enterd the url: {0}", document.Url) ); if (environment == null) environment = Environment; String outputPdfFilePath; bool delete; if (woutput.OutputFilePath != null) { outputPdfFilePath = woutput.OutputFilePath; delete = false; } else { outputPdfFilePath = Path.Combine(environment.TempFolderPath, String.Format("{0}.pdf", Guid.NewGuid())); delete = true; } if (!File.Exists(environment.WkHtmlToPdfPath)) throw new PdfConvertException(String.Format("File '{0}' not found. Check if wkhtmltopdf application is installed.", environment.WkHtmlToPdfPath)); ProcessStartInfo si; StringBuilder paramsBuilder = new StringBuilder(); paramsBuilder.Append("--page-size A4 "); //paramsBuilder.Append("--redirect-delay 0 "); not available in latest version if (!string.IsNullOrEmpty(document.HeaderUrl)) { paramsBuilder.AppendFormat("--header-html {0} ", document.HeaderUrl); paramsBuilder.Append("--margin-top 25 "); paramsBuilder.Append("--header-spacing 5 "); } if (!string.IsNullOrEmpty(document.FooterUrl)) { paramsBuilder.AppendFormat("--footer-html {0} ", document.FooterUrl); paramsBuilder.Append("--margin-bottom 25 "); paramsBuilder.Append("--footer-spacing 5 "); } paramsBuilder.AppendFormat("\"{0}\" \"{1}\"", document.Url, outputPdfFilePath); si = new ProcessStartInfo(); si.CreateNoWindow = !environment.Debug; si.FileName = environment.WkHtmlToPdfPath; si.Arguments = paramsBuilder.ToString(); si.UseShellExecute = false; si.RedirectStandardError = !environment.Debug; si.RedirectStandardOutput = true; si.RedirectStandardError = true; si.RedirectStandardInput = true; try { using (var process = new Process()) { process.StartInfo = si; process.Start(); if (document.Html != null) using (var stream = process.StandardInput) { byte[] buffer = Encoding.UTF8.GetBytes(document.Html); stream.BaseStream.Write(buffer, 0, buffer.Length); stream.WriteLine(); } if (!process.WaitForExit(environment.Timeout)) throw new PdfConvertTimeoutException(); if (!File.Exists(outputPdfFilePath)) { if (process.ExitCode != 0) { var error = si.RedirectStandardError ? process.StandardError.ReadToEnd() : String.Format("Process exited with code {0}.", process.ExitCode); throw new PdfConvertException(String.Format("Html to PDF conversion of '{0}' failed. Wkhtmltopdf output: \r\n{1}", document.Url, error)); } throw new PdfConvertException(String.Format("Html to PDF conversion of '{0}' failed. Reason: Output file '{1}' not found.", document.Url, outputPdfFilePath)); } if (woutput.OutputStream != null) { using (Stream fs = new FileStream(outputPdfFilePath, FileMode.Open)) { byte[] buffer = new byte[32 * 1024]; int read; while ((read = fs.Read(buffer, 0, buffer.Length)) > 0) woutput.OutputStream.Write(buffer, 0, read); } } if (woutput.OutputCallback != null) { woutput.OutputCallback(document, File.ReadAllBytes(outputPdfFilePath)); } } } finally { if (delete && File.Exists(outputPdfFilePath)) File.Delete(outputPdfFilePath); } } } class OSUtil { public static string GetProgramFilesx86Path() { if (8 == IntPtr.Size || (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432")))) { return Environment.GetEnvironmentVariable("ProgramFiles(x86)"); } return Environment.GetEnvironmentVariable("ProgramFiles"); } } //public static class HttpResponseExtensions //{ // public static void SendFileForDownload(this HttpResponse response, String filename, byte[] content) // { // SetFileDownloadHeaders(response, filename); // response.OutputStream.Write(content, 0, content.Length); // response.Flush(); // } // public static void SendFileForDownload(this HttpResponse response, String filename) // { // SetFileDownloadHeaders(response, filename); // response.TransmitFile(filename); // response.Flush(); // } // public static void SetFileDownloadHeaders(this HttpResponse response, String filename) // { // FileInfo fi = new FileInfo(filename); // response.ContentType = "application/force-download"; // response.AddHeader("Content-Disposition", "attachment; filename=\"" + fi.Name + "\""); // } //} }
using System; using System.Collections.Generic; using System.Text; using System.IO; namespace Codaxy.WkHtmlToPdf.Tests { class Program { static void Main(string[] args) { Console.InputEncoding = Encoding.UTF8; PdfConvert.Environment.Debug = true; PdfConvert.ConvertHtmlToPdf(new PdfDocument { Url = "-", Html = "<html><head><meta http-equiv='content-type' content='text/html;charset=gb2312'><style>.a{color:red;}</style></head><body><span class='a'>测试</span></body></html>" }, new PdfOutput { OutputFilePath = "inline.pdf" }); PdfConvert.ConvertHtmlToPdf(new PdfDocument { Url = "-", Html = "<html><h1>测试</h1></html>" }, new PdfOutput { OutputFilePath = "inline_cht.pdf" }); } } }
这两段代码可以成功的实现我想要的功能 但是这是在DOC窗口里面测试的
我将代码转移到asp.net 在页面中用Button触发上述Main函数中的转换方法后 无效.
也没有报错。调试进去 Doc执行了 但是没有启动.exe文件的转换 是不是我漏掉了什么?
如果你有其他好的解决方案 希望也推荐下。因为我可能不是直接的转换一个HTML的URL
可能是一个Html的拼接字符串。