首页 > 代码库 > 怎么将网页Html转化为PDF
怎么将网页Html转化为PDF
前言
之前做了有个项目要求将Html转成PDF,网上搜索答案大部分都是使用itextsharp组件进行转换,在实际使用过程中发现不是很好使用。现在本人推荐使用wkhtmltox.exe这个应用进行PDF转换。
wkhtmltox.exe开发步骤
1、安装wkhtmltox.exe,安装完后在安装路径会有:\wkhtmltopdf\bin\wkhtmltopdf.exe,这个事我们用来转化PDF的工具。下载地址为:https://sourceforge.net/projects/wkhtmltopdf/
2、编写代码调用需要转换为PDF
2.1 主要生产PDF的PDFConverter类,里面主要的方法为:ConvertHtmlToPDF
其中有两重载的方法:void ConvertHtmlToPdf(PdfDocument document, PdfOutput output) 和 void ConvertHtmlToPdf(PdfDocument document, PdfConvertEnvironment environment, PdfOutput woutput)
PDFConverter的代码为:
using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace PDFApplication{ 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 String HeaderLeft { get; set; } public String HeaderCenter { get; set; } public String HeaderRight { get; set; } public String FooterLeft { get; set; } public String FooterCenter { get; set; } public String FooterRight { get; set; } public object State { get; set; } public Dictionary<String, String> Cookies { get; set; } public Dictionary<String, String> ExtraParams { 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 PDFConverter { private static PdfConvertEnvironment _e; public static PdfConvertEnvironment Environment { get { if (_e == null) _e = new PdfConvertEnvironment { TempFolderPath = Path.GetTempPath() + @"\pdf\", WkHtmlToPdfPath = GetWkhtmlToPdfExeLocation(), Timeout = 60000 }; return _e; } } private static string GetWkhtmlToPdfExeLocation() { string programFilesPath = @"C:\Program Files"; string filePath = Path.Combine(programFilesPath, @"wkhtmltopdf\wkhtmltopdf.exe"); if (File.Exists(filePath)) return filePath; string programFilesx86Path = System.Environment.GetEnvironmentVariable("ProgramFiles"); filePath = Path.Combine(programFilesx86Path, @"wkhtmltopdf\wkhtmltopdf.exe"); if (File.Exists(filePath)) return filePath; filePath = Path.Combine(programFilesPath, @"wkhtmltopdf\bin\wkhtmltopdf.exe"); if (File.Exists(filePath)) return filePath; return Path.Combine(programFilesx86Path, @"wkhtmltopdf\bin\wkhtmltopdf.exe"); } 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)); StringBuilder paramsBuilder = new StringBuilder(); paramsBuilder.Append("--page-size A4 "); 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 "); } if (!string.IsNullOrEmpty(document.HeaderLeft)) paramsBuilder.AppendFormat("--header-left \"{0}\" ", document.HeaderLeft); if (!string.IsNullOrEmpty(document.FooterCenter)) paramsBuilder.AppendFormat("--header-center \"{0}\" ", document.HeaderCenter); if (!string.IsNullOrEmpty(document.FooterCenter)) paramsBuilder.AppendFormat("--header-right \"{0}\" ", document.HeaderRight); if (!string.IsNullOrEmpty(document.FooterLeft)) paramsBuilder.AppendFormat("--footer-left \"{0}\" ", document.FooterLeft); if (!string.IsNullOrEmpty(document.FooterCenter)) paramsBuilder.AppendFormat("--footer-center \"{0}\" ", document.FooterCenter); if (!string.IsNullOrEmpty(document.FooterCenter)) paramsBuilder.AppendFormat("--footer-right \"{0}\" ", document.FooterRight); if (document.ExtraParams != null) foreach (var extraParam in document.ExtraParams) paramsBuilder.AppendFormat("--{0} {1} ", extraParam.Key, extraParam.Value); if (document.Cookies != null) foreach (var cookie in document.Cookies) paramsBuilder.AppendFormat("--cookie {0} {1} ", cookie.Key, cookie.Value); paramsBuilder.AppendFormat("\"{0}\" \"{1}\"", document.Url, outputPdfFilePath); try { StringBuilder output = new StringBuilder(); StringBuilder error = new StringBuilder(); using (Process process = new Process()) { process.StartInfo.FileName = environment.WkHtmlToPdfPath; process.StartInfo.Arguments = paramsBuilder.ToString(); process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardInput = true; using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false)) using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false)) { DataReceivedEventHandler outputHandler = (sender, e) => { if (e.Data =http://www.mamicode.com/= null) { outputWaitHandle.Set(); } else { output.AppendLine(e.Data); } }; DataReceivedEventHandler errorHandler = (sender, e) => { if (e.Data =http://www.mamicode.com/= null) { errorWaitHandle.Set(); } else { error.AppendLine(e.Data); } }; process.OutputDataReceived += outputHandler; process.ErrorDataReceived += errorHandler; try { process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); 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) && outputWaitHandle.WaitOne(environment.Timeout) && errorWaitHandle.WaitOne(environment.Timeout)) { if (process.ExitCode != 0 && !File.Exists(outputPdfFilePath)) { throw new PdfConvertException(String.Format("Html to PDF conversion of ‘{0}‘ failed. Wkhtmltopdf output: \r\n{1}", document.Url, error)); } } else { if (!process.HasExited) process.Kill(); throw new PdfConvertTimeoutException(); } } finally { process.OutputDataReceived -= outputHandler; process.ErrorDataReceived -= errorHandler; } } } 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) { byte[] pdfFileBytes = File.ReadAllBytes(outputPdfFilePath); woutput.OutputCallback(document, pdfFileBytes); } } finally { if (delete && File.Exists(outputPdfFilePath)) File.Delete(outputPdfFilePath); } } }} 2、在程序集中调用该方法 using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading.Tasks;namespace PDFApplication{ class Program { static void Main(string[] args) { PDFConverter.ConvertHtmlToPdf(new PdfDocument { Url = "http://www.cnblogs.com/", HeaderLeft = "[title]", //HeaderRight = "[date] [time]", // FooterCenter = "Page [page] of [topage]" }, new PdfOutput { OutputFilePath = "博客园.pdf", OutputCallback = (p,q) => { FileStream fileStream = null; try { string fileName = AppDomain.CurrentDomain.BaseDirectory + "/PDF/" + Guid.NewGuid() + ".pdf"; if(Directory.Exists(fileName) ) { Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "/PDF/"); } fileStream = new FileStream(fileName, FileMode.OpenOrCreate); fileStream.Write(q, 0, q.Length); } catch(Exception ex) { } finally { if (fileStream != null) { fileStream.Close(); } } } }); } }}
3、本人试验转化的PDF为
4、结论
生产PDF的步骤为:
1、安装wkhtmltox.exe;
2、根据自己的情况调整PDFConverter的参数
3、调用PDFConverter生成PDF
怎么将网页Html转化为PDF
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。