使用Razor页面自定义网页模板, 后台根据不同数据动态生成网页内容,利用itext7.pdfhtml导出pdf文件
一、自定义网页模板
这是一个cshtml后缀的文件,通过该文件定义要导出到pdf或者word的内容模板。
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>订单页面模板</title> <style> .byTable { width: 100%; border-collapse: collapse; padding: 2px; } .byTable, .byTable tr th, .byTable tr td { border: 1px solid black; padding: 5px 15px; font-size: 16px; } </style> </head> <body> <p>RazorEngine!</p> <h3>Order Name: @Model.OrderName</h3> <h3>Order #: @Model.OrderNo</h3> @if (Model.OrderName == "order name") { <span>PM: @Model.OrderName</span> } else { <p>PM: @Model.OrderName</p> } <h3>订单详情</h3> <table class="byTable"> <tr> <td>Item name</td> <td>Item #</td> <td>Quantity</td> <td>Price</td> <td>Total</td> </tr> @foreach (var item in Model.Items) { <tr> <td>@item.ItemName</td> <td>@item.ItemNo</td> <td>@item.Quantity</td> <td>@item.Price</td> <td>@item.Total</td> </tr> } </table> </body> </html>
二、通过模板解析器解析自定义的网页模板,动态填充数据
网页模板解析器使用RazorEngine进行解析,通过NuGet添加RazorEngine和itext7.pdfhtml,然后运行RunCompile结合Model填充网页模板。代码如下
using RazorEngine; using RazorEngine.Templating; using System; using System.IO; using System.Text; using System.Web; namespace HY.MvcWeb.Models { public class RazorTemplateParser { public string Parse<T>(string templateContents, T data) { return HttpUtility.HtmlDecode(ParseTemplate(templateContents, data)); } private string ParseTemplate<T>(string templateContents, T data) { try { var templateKey = new NameOnlyTemplateKey(templateContents.GetHashCode().ToString(), ResolveType.Global, null); if (!Engine.Razor.IsTemplateCached(templateKey, data.GetType())) { Engine.Razor.AddTemplate(templateKey, new LoadedTemplateSource(templateContents)); } var templateOutput = new StringBuilder(); using (var sw = new StringWriter(templateOutput)) { Engine.Razor.RunCompile(templateKey, sw, data.GetType(), data); } return templateOutput.ToString(); } catch (Exception ex) { throw new Exception("There was an error parsing this page.", ex); } } } }
通过如下代码,提取网页模板内容,填充数据,并调用导出pdf的代码在目标文件夹生成pdf文件:
public void ExportPdf() { var path = AppDomain.CurrentDomain.BaseDirectory + "Templates\\WebPage1.cshtml"; var template = System.IO.File.ReadAllText(path); var model = new Order { OrderName = "order name", OrderNo = "order no", OrderDate = DateTime.Now, OrderStatus = "in progress", Items = new List<OrderItem> { new OrderItem { ItemName = "item name 1", ItemNo="item no 1", Price = 10, Quantity =20 }, new OrderItem { ItemName = "item name 2", ItemNo="item no 2", Price = 15, Quantity =10 } } }; var razorParsed = new RazorTemplateParser().Parse(template, model); var pdfFilePath = AppDomain.CurrentDomain.BaseDirectory + "Output\\Exported.pdf"; ConvertHtmlStringToPdf(razorParsed, pdfFilePath); } private void ConvertHtmlStringToPdf(string htmlString, string pdfFilePath) { using (FileStream pdfDest = System.IO.File.Open(pdfFilePath, FileMode.OpenOrCreate)) { ConverterProperties converterProperties = new ConverterProperties(); HtmlConverter.ConvertToPdf(htmlString, pdfDest, converterProperties); } }
Order 类的定义如下:
namespace HY.MvcWeb.Models { public class Order { public string OrderName { get; set; } public string OrderNo { get; set; } public DateTime OrderDate { get; set; } public string OrderStatus { get; set; } public List<OrderItem> Items { get; set; } } public class OrderItem { public string ItemName { get; set; } public string ItemNo { get; set; } public double Price { get; set; } public int Quantity { get; set; } public double Total { get { return Quantity * Price; } } } }
如下是生成的pdf内容截图: