使用 ASP.NET MVC3 进行 PDF 报告






4.83/5 (69投票s)
使用 ASP.NET MVC3 创建 PDF 报告的描述和解决方案。
目录
引言
几乎每个 Web 应用程序(我构建过的)都需要某种形式的报告。很多时候,客户希望生成与他们正在查看的网页相对应的 PDF 报告。使用 iTextSharp,一个免费的 C# PDF 库,这是可能的。本文描述并包含了一个使用 iTextSharp 和 ASP.NET MVC3 创建报告的解决方案。
背景
iTextSharp 是一个免费的 C# PDF 库,它从 Java PDF 库 iText 移植而来。iText 于 2000 年推出,是一个流行的开源 Java 库,用于以编程方式创建和操作 PDF。与许多成功的开源 Java 库一样,它被移植到 C# 并命名为 iTextSharp。iTextSharp 自 2008 年以来一直在开发中,并根据 GNU Affero General Public License version 3 分发。
iTextSharp 的核心是一个用于操作 PDF 创建的 API。对于最近的一个项目,我正在寻找一个解决方案,该方案能够让我从现有的 HTML 文档或 ASP.NET MVC3 项目中使用的视图创建 PDF 文档。对我来说,最优的解决方案是直接向其提供一个现有的 ASP.NET MVC3 视图,并让它生成一个与浏览器渲染的 HTML 完全相同的 PDF。
这里描述的解决方案使用 iTextSharp 中的 HTMLWorker
类,从 HTML 视图生成 PDF。HTMLWorker 是 iTextSharp 的一个类,它能够解析 HTML 文档并使用 iTextSharp 的 SimpleParser
来生成 PDF。请注意 SimpleParser
这个名称,它表明并非所有 HTML 元素和 CSS 样式都受支持。但是,我使用此解决方案获得了不错的结果。
要为您的 ASP.NET MVC3 项目添加报告功能,请先将 PdfReportGenerator 项目添加到您的解决方案中,并将 iTextSharp.dll 二进制文件添加到您的解决方案。PDFReportGenerator 需要对该二进制文件的引用。通过将二进制文件添加到解决方案,您可以直接从源代码管理构建项目。请查看演示源代码以获取示例。
创建报告
请按照以下步骤从您的 Web 应用程序生成实际报告
- 创建一个从
PdfViewController
派生的控制器。 - 创建一个生成应转换为 PDF 报告的 HTML 的视图。
- 在控制器中创建一个调用
PdfViewController
的ViewPDF
方法的操作。 - 创建一个链接来触发控制器上的操作。
下面将详细介绍这些步骤。
创建一个从 PdfViewController 派生的控制器
创建或重用一个现有的控制器,并让它从 PdfReportGenerator 项目中的 PdfViewController
派生。这使您的控制器能够调用 PDFViewController
的 ViewPDF
方法,该方法会生成实际的 PDF。在演示项目中,这是 HomeController
。
创建一个生成 HTML 的视图
创建一个应转换为报告的视图。这可以是一个现有的视图,也可以是一个专门用于报告的新视图。我通常会创建一个新视图,因为它允许我控制报告的 HTML 标记。如前所述,报告生成器并不支持所有 HTML 标记。在演示项目中,这是 PrintDemo
视图。
下面显示了演示项目中的 PrintDemo 视图。正如您所看到的,这只是一个简单的 ASP.NET Razor 视图,带有一个表格和一些行。它使用了强类型模型,但这并非必需。在尝试设计报告时的一个技巧是为您的 table
或 div
添加边框。使用这些边框,当查看生成的 PDF 时,您可以清楚地看到报告区域的开始和结束。
@using MvcReportGeneratorDemo.Models
@model CustomerList
<br />
<table cellpadding="3" cellspacing="3">
<tr border="1" bgcolor="#777777" color="#ffffff">
<td>Name</td>
<td>Address</td>
<td>Place</td>
</tr>
@foreach (Customer customer in Model)
{
<tr border="1">
<td>@customer.Name</td>
<td>@customer.Address</td>
<td>@customer.Place</td>
</tr>
}
</table>
创建一个调用 ViewPDF 方法的操作
您的控制器派生的 PdfViewController
类包含一个 ViewPDF
方法。该方法具有以下签名
protected ActionResult ViewPdf(string pageTitle, string viewName, object model)
参数
pageTitle
- 类型:
System.String
- 报告的标题,显示在页面页眉中。
viewName
- 类型:
System.String
- 应转换为报告的视图的名称。
模型
- 类型:
System.Object
- 由视图渲染的模型。
此方法会生成 HTML 视图,并将其转换为 PDF 报告,然后将此 PDF 作为二进制流发送回客户端。这意味着,当客户端安装了 PDF 插件时,PDF 将在浏览器内显示。
从控制器中的某个操作,应调用此方法来生成报告并将其发送给客户端。演示应用程序中的以下操作会生成 PDF。“Customer report”是报告的标题,“PrintDemo”是视图的名称,模型由 CreateCustomerList()
返回,该方法顾名思义会生成一个虚拟的客户列表。
public ActionResult PrintCustomers()
{
return this.ViewPdf("Customer report", "PrintDemo", CreateCustomerList());
}
最后一步是在页面上创建一个链接,该链接调用此操作以实际打印报告。
触发控制器上的操作
创建一个链接来触发控制器上的操作的一个简单方法是使用 ActionLink
。此链接调用我们在控制器中定义的操作。
@Html.ActionLink("Print customers", "PrintCustomers", null, new { target = "_blank" })
这些是您需要能够从 ASP.NET MVC3 项目创建 PDF 报告的步骤。如果您对 PdfReportGenerator 如何将 ASP.NET MVC3 视图转换为报告的详细信息感兴趣,请阅读文章的下一部分。
详细的报告项目概述
PdfReportGenerator 项目由六个类组成,如下面的图像所示。PdfReportGenerator 程序集通过将 ASP.NET MVC3 视图渲染为字符串,然后使用 iTextSharp 将此 HTML 字符串转换为 PDF 报告来工作。
将 ASP.NET MVC3 视图渲染为字符串
HtmlViewRenderer
类负责将 ASP.NET 视图渲染为字符串。RenderViewToString
方法具有以下签名。
public string RenderViewToString(Controller controller, string viewName, object viewData)
第一个参数是 viewName
,这是应渲染为 string
的视图的名称,包括视图所需的模型 viewData
。控制器对于使用 ASP.NET MVC 的视图引擎渲染视图是必需的。
将 HTML 字符串转换为 PDF 字节数组
一旦我们有了 HTML 字符串,StandardPdfRenderer
就会将 HTML 字符串转换为 PDF 字节数组。StandardPdfRenderer
类有一个名为 Render
的方法,其签名如下。
public byte[] Render(string htmlText, string reportTitle)
htmlText
是由 HtmlViewRender
生成的已渲染视图字符串;pageTitle
如其名称所示,是报告的标题。
将字节数组作为流发送回客户端
最后一步是将字节数组转换为 BinaryContentResult
类的实例。BinaryContentResult
类从 ASP.NET MVC 的 ActionResult
派生。它重写了 ExecuteResult
并将内容作为二进制流返回。
PdfViewController
类组合了这些类。ViewPdf
方法使用前面提到的所有三个类来生成 PDF,如下面的代码所示。
protected ActionResult ViewPdf(string pageTitle, string viewName, object model)
{
// Render the view html to a string.
string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model);
// Let the html be rendered into a PDF document through iTextSharp.
byte[] buffer = standardPdfRenderer.Render(htmlText, pageTitle);
// Return the PDF as a binary stream to the client.
return new BinaryContentResult(buffer, "application/pdf");
}
值得关注的点
颜色
iTextsharp 开箱即用地支持颜色;在演示应用程序中,行背景色通过使用不同的颜色进行交替。这些颜色在报告中可见。
新页支持
我的项目需要但 iTextSharp 的 HTML 转换不支持的一项功能是强制分页。大多数情况下,在报告中,您需要能够强制分页,例如,如果您希望图表始终在新页面上开始。我解决这个问题的方法是为 iTextSharp 添加支持。由于它是开源的,您可以为其添加新功能。我添加了对一个不存在的 HTML 标签 <np />
的支持,该标签会强制 iTextSharp 创建一个新页面。我创建了一个补丁,以便它可以提交到 iTextSharp 项目。我不知道它是否会被包含在项目的主干中,因为发明新的 HTML 标签只是为了支持分页似乎有些奇怪。但如果您需要它,您可以使用该补丁来编译支持新页面的 iTextSharp。
图片
可以使用 <img src="" />
标签将图片添加到报告中。我未能成功处理动态生成的图片。因此,我在操作转换过程发生之前生成了我需要的图片。报告中可以看到一张静态图片。
ASP.NET 支持
使用旧版本的 ASP.NET MVC 应该可以使用相同的解决方案。但是,我没有尝试过。
历史
- 26/09/2011
- First version.
- 06/08/2012
- 向 PDF 报告添加了图片。