C# html 转 pdf

场景:平台返回的面单文件流转html 时不规范,便于保存面单使得下次不用请求平台接口,或者订单状态改变导致不能请求接口问题

经历 2 天的查找 和 验证得到方案

1. 使用 iTextSharp.text,这种方案也有两个方法

①直接将HTML 转 PDF,但是你会发现这里会验证你HTML的完整性,很多情况使用不了

②将HTML 转图片 后 塞进 PDF 中,这种方法可以尝试

2.Spire.Pdf 需要收费,破解版难找,免费版有水印,(拿刀来,搞了好久最终放弃,设置尺寸时单位不知,不是mm)

3.使用 wkhtmltopdf.exe 【最终使用,原因有使用方便,应用范围广等特点】

下载地址 http://wkhtmltopdf.org/downloads.html

原理 将Html 字符转为html文件后 使用 wkhtmltopdf.exe 插件生成pdf 文件

使用方法

将Down 好的zip解压后有个 wkhtmltopdf.exe

将其放入 生成后的相对根目录下,比如Bebug

帮助类

  1 namespace Common
  2 {
  3     public class HtmlToPdf
  4     {
  5         /// <summary>
  6         /// HTML文本内容转换为PDF
  7         /// </summary>
  8         /// <param name="strHtml">HTML文本内容</param>
  9         /// <param name="savePath">PDF文件保存的路径</param>
 10         /// <returns></returns>
 11         public bool HtmlTextConvertToPdf(string strHtml, string savePath)
 12         {
 13             bool flag = false;
 14             try
 15             {
 16                 string htmlPath = HtmlTextConvertFile(strHtml);
 17 
 18                 flag = HtmlConvertToPdf(htmlPath, savePath);
 19                 File.Delete(htmlPath);
 20             }
 21             catch
 22             {
 23                 flag = false;
 24             }
 25             return flag;
 26         }
 27 
 28         /// <summary>
 29         /// HTML转换为PDF
 30         /// </summary>
 31         /// <param name="htmlPath">可以是本地路径,也可以是网络地址</param>
 32         /// <param name="savePath">PDF文件保存的路径</param>
 33         /// <returns></returns>
 34         public bool HtmlConvertToPdf(string htmlPath, string savePath)
 35         {
 36             bool flag = false;
 37             CheckFilePath(savePath);
 38 
 39             ///这个路径为程序集的目录,因为我把应用程序 wkhtmltopdf.exe 放在了程序集同一个目录下
 40             string exePath = AppDomain.CurrentDomain.BaseDirectory.ToString() + "wkhtmltopdf.exe";
 41             if (!File.Exists(exePath))
 42             {
 43                 throw new Exception("No application wkhtmltopdf.exe was found.");
 44             }
 45 
 46             try
 47             {
 48                 ProcessStartInfo processStartInfo = new ProcessStartInfo();
 49                 processStartInfo.FileName = exePath;
 50                 processStartInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
 51                 processStartInfo.UseShellExecute = false;
 52                 processStartInfo.CreateNoWindow = true;
 53                 processStartInfo.RedirectStandardInput = true;
 54                 processStartInfo.RedirectStandardOutput = true;
 55                 processStartInfo.RedirectStandardError = true;
 56                 processStartInfo.Arguments = GetArguments(htmlPath, savePath);
 57 
 58                 Process process = new Process();
 59                 process.StartInfo = processStartInfo;
 60                 process.Start();
 61                 process.WaitForExit();
 62 
 63                 ///用于查看是否返回错误信息
 64                 //StreamReader srone = process.StandardError;
 65                 //StreamReader srtwo = process.StandardOutput;
 66                 //string ss1 = srone.ReadToEnd();
 67                 //string ss2 = srtwo.ReadToEnd();
 68                 //srone.Close();
 69                 //srone.Dispose();
 70                 //srtwo.Close();
 71                 //srtwo.Dispose();
 72 
 73                 process.Close();
 74                 process.Dispose();
 75 
 76                 flag = true;
 77             }
 78             catch
 79             {
 80                 flag = false;
 81             }
 82             return flag;
 83         }
 84 
 85         /// <summary>
 86         /// 获取命令行参数
 87         /// </summary>
 88         /// <param name="htmlPath"></param>
 89         /// <param name="savePath"></param>
 90         /// <returns></returns>
 91         private string GetArguments(string htmlPath, string savePath)
 92         {
 93             if (string.IsNullOrEmpty(htmlPath))
 94             {
 95                 throw new Exception("HTML local path or network address can not be empty.");
 96             }
 97 
 98             if (string.IsNullOrEmpty(savePath))
 99             {
100                 throw new Exception("The path saved by the PDF document can not be empty.");
101             }
102 
103             StringBuilder stringBuilder = new StringBuilder();
104             stringBuilder.Append(" --page-height 150 ");        //页面高度100mm
105             stringBuilder.Append(" --page-width 100 ");         //页面宽度100mm
106             //stringBuilder.Append(" --header-center 我是页眉 ");  //设置居中显示页眉
107             //stringBuilder.Append(" --header-line ");         //页眉和内容之间显示一条直线
108             //stringBuilder.Append(" --footer-center \"Page [page] of [topage]\" ");    //设置居中显示页脚
109             //stringBuilder.Append(" --footer-line ");       //页脚和内容之间显示一条直线
110 
111             stringBuilder.Append(" --margin-left 1");    //左边距
112             stringBuilder.Append(" --margin-right 1");       //右边距
113             stringBuilder.Append(" --margin-bottom 1");    //左边距
114             stringBuilder.Append(" --margin-top 1");       //右边距
115             //stringBuilder.Append(" --no-collat​​e");       //不分页
116 
117             stringBuilder.Append(" " + htmlPath + " ");       //本地 HTML 的文件路径或网页 HTML 的URL地址
118             stringBuilder.Append(" " + savePath + " ");       //生成的 PDF 文档的保存路径
119             return stringBuilder.ToString();
120         }
121 
122         /// <summary>
123         /// 验证保存路径
124         /// </summary>
125         /// <param name="savePath"></param>
126         private void CheckFilePath(string savePath)
127         {
128             string ext = string.Empty;
129             string path = string.Empty;
130             string fileName = string.Empty;
131 
132             ext = Path.GetExtension(savePath);
133             if (string.IsNullOrEmpty(ext) || ext.ToLower() != ".pdf")
134             {
135                 throw new Exception("Extension error:This method is used to generate PDF files.");
136             }
137 
138             fileName = Path.GetFileName(savePath);
139             if (string.IsNullOrEmpty(fileName))
140             {
141                 throw new Exception("File name is empty.");
142             }
143 
144             try
145             {
146                 path = savePath.Substring(0, savePath.IndexOf(fileName));
147                 if (!Directory.Exists(path))
148                 {
149                     Directory.CreateDirectory(path);
150                 }
151             }
152             catch
153             {
154                 throw new Exception("The file path does not exist.");
155             }
156         }
157 
158         /// <summary>
159         /// HTML文本内容转HTML文件
160         /// </summary>
161         /// <param name="strHtml">HTML文本内容</param>
162         /// <returns>HTML文件的路径</returns>
163         public string HtmlTextConvertFile(string strHtml)
164         {
165             if (string.IsNullOrEmpty(strHtml))
166             {
167                 throw new Exception("HTML text content cannot be empty.");
168             }
169 
170             try
171             {
172                 string path = AppDomain.CurrentDomain.BaseDirectory.ToString() + @"html\";
173                 if (!Directory.Exists(path))
174                 {
175                     Directory.CreateDirectory(path);
176                 }
177                 string fileName = path + DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(1000, 10000) + ".html";
178                 FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
179                 StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8);
180                 streamWriter.Write(strHtml);
181                 streamWriter.Flush();
182 
183                 streamWriter.Close();
184                 streamWriter.Dispose();
185                 fileStream.Close();
186                 fileStream.Dispose();
187                 return fileName;
188             }
189             catch
190             {
191                 throw new Exception("HTML text content error.");
192             }
193         }
194     }
195 }
View Code

使用时HTML 可以携带CSS,jS 代码,JS源必须为公网可以访问

使用方式直接调用就好

配置文档  https://wkhtmltopdf.org/usage/wkhtmltopdf.txt

注意一点,在写入HTML文件时 注意是否乱码,编码格式问题,代码中改了为UTF-8

互联网是理性的,怎么用看使用的人,巧妙的借鉴可以事半功倍,以找不出源,如有侵权,请提醒我更改!

 

posted @ 2021-03-01 18:01  魔方の成长  阅读(527)  评论(0编辑  收藏  举报