Fork me on GitHub

Html导出Pdf

最近领导给了一个新的需求:给了我一个html页面,让我导出Pdf页面

由于以前没有搞过这方面的需求,所以查百度找资料,找了一大堆的好东西,像ItextSharp和wkhtmltopdf

废话不说,进入正题

ItextSharp对Html5的canvas和css,js等支持不是很好,只适用于简单的页面导出。故放弃

导出方法一:使用wkhtmltopdf

这个需要安装wkhtmltopdf: https://wkhtmltopdf.org/downloads.html 下面的变量就是wkhtmltopdf的安装目录

 1 public ActionResult ExportSocialPDF(int testerid)
 2         {
 3             try
 4             {
 5                 var tester = _testerBll.Details(testerid);
 6                 string folder = string.Format("~/Temp/{0}", DateTime.Now.ToString("yyyyMMdd"));
 7                 if (!System.IO.Directory.Exists(Server.MapPath(folder)))
 8                 {
 9                     System.IO.Directory.CreateDirectory(Server.MapPath(folder));
10                 }
11                 string fileName = string.Format("{0}-社会综合素质测试{1}", tester.name, DateTime.Now.ToString("yyyyMMddHHmmss"));
12                 string pdfpath = fileName + ".pdf";
13                 ExportSocialPDFCore(tester, folder, pdfpath);
14                 string filePath = Server.MapPath(folder) + "/" + pdfpath;
15                 new System.Threading.Thread(DeleteOldFileFolder).Start();
16                 return File(filePath, "application/octet-stream", System.IO.Path.GetFileName(filePath));
17             }
18             catch (Exception ex)
19             {
20                 log.Error(ex);
21                 return View(ex);
22             }
23         }
 1 public void ExportSocialPDFCore(HqftTestPaper.Entity.t_testerEntity tester, string folder, string pdfpath)
 2         {
 3             string pdf = @"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe";
 4             //string url = "http://localhost/TestManage/WordTemplate/index.html";
 5             string url = Url.Action("ExportPreview", "ExportPDF", new { testerid = tester.id });
 6 
 7             url = string.Format("http://{0}:{1}{2}",Request.Url.Host, Request.Url.Port, url);
 8 
 9             string add = url + " \"" + Server.MapPath(folder + "/" + pdfpath) + "\"";
10             Process p = System.Diagnostics.Process.Start(pdf, add);
11             p.WaitForExit();
12         }
 1 public void DeleteOldFileFolder()
 2         {
 3             string strPath = Server.MapPath("~/Temp/");
 4             string[] fileNames = System.IO.Directory.GetDirectories(strPath);
 5             foreach (string fileName in fileNames)
 6             {
 7                 string name = fileName.Substring(strPath.Length);
 8                 if (string.Compare(DateTime.Now.ToString("yyyyMMdd"), name) > 0)
 9                 {
10                     System.IO.Directory.Delete(fileName, true);
11                 }
12             }
13         }

 

注释:

1、t_testerEntity是个需要导出的测试者的类,大家可以自行脑补,只要一个id获取数据就可以了 

2、此方法是现在本地生成一个Pdf,然后把路径传到View让浏览器下载,所以需要一个删除旧文件的方法

3、根据cshtml下载的页面,必须能够无限制的访问,就是直接把路径贴在浏览器中可以直接访问。

如果为了系统安全性,加了访问限制的,需要新建一个不受限制的Controller

导出方法二:页面先截图,然后生成Pdf

这个用的是Winform的WebBrowser控件,有限制:你的IE和你的WebBrowser内核可能不是一个版本的。Css支持率极低。个人认为不好用

  1 using iTextSharp.text;
  2 using iTextSharp.text.pdf;
  3 using System;
  4 using System.Drawing;
  5 using System.IO;
  6 using System.Threading;
  7 using System.Windows.Forms;
  8 
  9 namespace ExportPDF.Common
 10 {
 11     public class HtmlToPdf
 12     {
 13         WebBrowser webBrowser;
 14 
 15         public void ConvertToImage(object url)
 16         {
 17             //string strUrl = "http://echarts.baidu.com/demo.html#pie-legend";
 18             webBrowser = new WebBrowser();
 19             //改变webBrowser内核版本
 20             WebBrowserOper.BrowserEmulationSet();
 21             webBrowser.AllowNavigation = true;
 22             webBrowser.Url = new Uri(url.ToString());
 23             webBrowser.ScrollBarsEnabled = true;
 24             DateTime dtime = DateTime.Now;
 25             double timespan = 0;
 26             while (timespan < 10 || webBrowser.ReadyState != WebBrowserReadyState.Complete)
 27             {
 28                 Application.DoEvents();
 29                 DateTime time2 = DateTime.Now;
 30                 timespan = (time2 - dtime).TotalSeconds;
 31             }
 32 
 33             if (webBrowser.ReadyState == WebBrowserReadyState.Complete)
 34             {
 35                 //htmlstr = webBrowser.DocumentText;
 36                 webBrowser_DocumentCompleted();
 37             }
 38             //string html = "";
 39             
 40             //webBrowser.DocumentText = html;
 41         }
 42 
 43         /// <summary>  
 44         /// 在单线程中启用浏览器  
 45         /// </summary>  
 46         public void RunWithSingleThread()
 47         {
 48             string url = "http://localhost/Export/template/index.html";
 49             ParameterizedThreadStart ps = new ParameterizedThreadStart(ConvertToImage);
 50             Thread t = new Thread(ps);
 51             t.IsBackground = true;
 52             t.SetApartmentState(ApartmentState.STA);
 53             t.Start(url);
 54         }
 55 
 56         private void webBrowser_DocumentCompleted()
 57         {
 58             //获取解析后HTML的大小
 59             System.Drawing.Rectangle rectangle = webBrowser.Document.Body.ScrollRectangle;
 60             int width = rectangle.Width;
 61             int height = rectangle.Height;
 62 
 63             //设置解析后HTML的可视区域
 64             webBrowser.Width = width;
 65             webBrowser.Height = height;
 66 
 67             Bitmap bitmap = new System.Drawing.Bitmap(width, height);
 68             webBrowser.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, width, height));
 69 
 70             //设置图片文件保存路径和图片格式,格式可以自定义
 71             string filePath = AppDomain.CurrentDomain.BaseDirectory + "/SaveFile/" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".png";
 72             bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
 73 
 74             //创建PDF
 75             FileStream fileStream = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "/SaveFile/" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".pdf", FileMode.Create);
 76 
 77             byte[] result = CreatePDF(bitmap, width, height);
 78 
 79             fileStream.Write(result, 0, result.Length);
 80 
 81             fileStream.Close();
 82             fileStream.Dispose();
 83         }
 84 
 85         private byte[] CreatePDF(Bitmap bitmap, int width, int height)
 86         {
 87             using (MemoryStream ms = new MemoryStream())
 88             {
 89                 Document doc = new Document(new iTextSharp.text.Rectangle(0, 0, width, height), 3, 3, 3, 3);    // 左右上下
 90 
 91                 PdfWriter writer = PdfWriter.GetInstance(doc, ms);
 92 
 93                 writer.CloseStream = false;
 94 
 95                 doc.Open();
 96 
 97                 iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(bitmap, System.Drawing.Imaging.ImageFormat.Png);
 98 
 99                 img.ScalePercent(100);      // 放缩比例
100 
101                 doc.Add(img);       // 添加图片对像
102                 doc.Close();
103 
104                 return ms.ToArray();
105             }
106         }
107     }
108 }
  1 using Microsoft.Win32;
  2 using System;
  3 using System.Diagnostics;
  4 
  5 namespace ExportPDF.Common
  6 {
  7     public static class WebBrowserOper
  8     {
  9         public static void WebBrowserVersionEmulation()
 10         {
 11             const string BROWSER_EMULATION_KEY = @"SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION";
 12             //const string BROWSER_EMULATION_KEY = @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
 13             
 14             // app.exe and app.vshost.exe
 15             RegistryKey browserEmulationKey = Registry.LocalMachine.OpenSubKey(BROWSER_EMULATION_KEY,RegistryKeyPermissionCheck.ReadWriteSubTree) ?? Registry.LocalMachine.CreateSubKey(BROWSER_EMULATION_KEY);
 16             //RegistryKey browserEmulationKey = Registry.CurrentUser.OpenSubKey(BROWSER_EMULATION_KEY,RegistryKeyPermissionCheck.ReadWriteSubTree) ?? Registry.LocalMachine.CreateSubKey(BROWSER_EMULATION_KEY);
 17             if (browserEmulationKey != null)
 18             {
 19                 String appname = Process.GetCurrentProcess().ProcessName + ".exe";
 20                 //Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.
 21                 const int browserEmulationMode = 10000;
 22 
 23                 if ((int)browserEmulationKey.GetValue(appname) != 1000)
 24                 { 
 25                     browserEmulationKey.SetValue(appname, browserEmulationMode, RegistryValueKind.DWord);
 26                 }
 27                 browserEmulationKey.Close();
 28             }
 29         }
 30 
 31 
 32 
 33         /// <summary>
 34         /// IE WebBrowser内核设置
 35         /// </summary>
 36         public static void BrowserEmulationSet()
 37         {
 38             //当前程序名称
 39             var exeName = Process.GetCurrentProcess().ProcessName + ".exe";
 40             //系统注册表信息
 41             var mreg = Registry.LocalMachine;
 42             //IE注册表信息
 43             var ie = mreg.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree);
 44             if (ie != null)
 45             {
 46                 try
 47                 {
 48                     var val = ieVersionEmulation(ieVersion());
 49                     if (val != 0)
 50                     {
 51                         ie.SetValue(exeName, val);
 52                     }
 53                     mreg.Close();
 54                 }
 55                 catch (Exception ex)
 56                 {
 57                     Console.Write(ex.Message);
 58                 }
 59             }
 60         }
 61  
 62         /// <summary>
 63         /// IE版本号
 64         /// </summary>
 65         /// <returns></returns>
 66         static int ieVersion()
 67         {
 68             //IE版本号
 69             RegistryKey mreg = Registry.LocalMachine;
 70             mreg = mreg.CreateSubKey("SOFTWARE\\Microsoft\\Internet Explorer");
 71  
 72             //更新版本
 73             var svcVersion = mreg.GetValue("svcVersion");
 74             if (svcVersion != null)
 75             {
 76                 mreg.Close();
 77                 var v = svcVersion.ToString().Split('.')[0];
 78                 return int.Parse(v);
 79             }
 80             else
 81             {
 82                 //默认版本
 83                 var ieVersion = mreg.GetValue("Version");
 84                 mreg.Close();
 85                 if (ieVersion != null)
 86                 {
 87                     var v = ieVersion.ToString().Split('.')[0];
 88                     return int.Parse(v);
 89                 }
 90             }
 91             return 0;
 92         }
 93  
 94         /// <summary>
 95         /// 根据IE版本号 返回Emulation值
 96         /// </summary>
 97         /// <param name="ieVersion"></param>
 98         /// <returns></returns>
 99         static int ieVersionEmulation(int ieVersion)
100         {
101             //IE7 7000 (0x1B58)
102             if (ieVersion < 8)
103             {
104                 return 0;
105             }
106             if (ieVersion == 8)
107             {
108                 return 0x1F40;//8000 (0x1F40)、8888 (0x22B8)
109             }
110             if (ieVersion == 9)
111             {
112                 return 0x2328;//9000 (0x2328)、9999 (0x270F)
113             }
114             else if (ieVersion == 10)
115             {
116                 return 0x02710;//10000 (0x02710)、10001 (0x2711)
117             }
118             else if (ieVersion == 11)
119             {
120                 return 0x2AF8;//11000 (0x2AF8)、11001 (0x2AF9
121             }
122             return 0;
123         }
124     }
125 }

另外还有一个导出Html的

 1 using System.IO;
 2 using System.Text;
 3 using System.Web;
 4 
 5 namespace ExportPDF.Common
 6 {
 7     public class ExportHtml
 8     {
 9         public void TemplateExport()
10         { 
11             string templatePath = HttpContext.Current.Server.MapPath("~/Template/") + "index.html";
12             string template = "";
13             using (StreamReader sr = new StreamReader(templatePath))
14             {
15                 template=sr.ReadToEnd();
16             }
17             //新的内容
18             StringBuilder context = new StringBuilder();
19             /*
20             foreach (Student stu in stulist)
21             {
22                 context.Append("<tr>");
23                 context.Append("<td>" + stu.XueHao + "</td><td>" + stu.XingMing + "</td>");
24                 context.Append("</tr>");
25             }
26             string newContext = template.Replace("$student$", context.ToString());
27             */
28             //把newContext写入报表中
29             string path = HttpContext.Current.Server.MapPath("~/SaveFile/") + "report.html";
30             using (StreamWriter sw = new StreamWriter(path, false))
31             {
32                 sw.WriteLine(template);
33             }
34         }
35     }
36 }

言尽于此

posted @ 2017-10-16 13:04  雪山玉龙  阅读(1690)  评论(0编辑  收藏  举报