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-collate"); //不分页 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 }
使用时HTML 可以携带CSS,jS 代码,JS源必须为公网可以访问
使用方式直接调用就好
配置文档 https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
注意一点,在写入HTML文件时 注意是否乱码,编码格式问题,代码中改了为UTF-8
互联网是理性的,怎么用看使用的人,巧妙的借鉴可以事半功倍,以找不出源,如有侵权,请提醒我更改!