65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ASP.NET MVC3 进行 PDF 报告

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (69投票s)

2011年9月26日

CPOL

8分钟阅读

viewsIcon

473200

downloadIcon

30727

使用 ASP.NET MVC3 创建 PDF 报告的描述和解决方案。

ASP_MVC_Reporting/ASP_MVC3_PDF_Reporting_1.jpg

目录

引言

几乎每个 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 应用程序生成实际报告

  1. 创建一个从 PdfViewController 派生的控制器。
  2. 创建一个生成应转换为 PDF 报告的 HTML 的视图。
  3. 在控制器中创建一个调用 PdfViewControllerViewPDF 方法的操作。
  4. 创建一个链接来触发控制器上的操作。

下面将详细介绍这些步骤。

创建一个从 PdfViewController 派生的控制器

创建或重用一个现有的控制器,并让它从 PdfReportGenerator 项目中的 PdfViewController 派生。这使您的控制器能够调用 PDFViewControllerViewPDF 方法,该方法会生成实际的 PDF。在演示项目中,这是 HomeController

创建一个生成 HTML 的视图

创建一个应转换为报告的视图。这可以是一个现有的视图,也可以是一个专门用于报告的新视图。我通常会创建一个新视图,因为它允许我控制报告的 HTML 标记。如前所述,报告生成器并不支持所有 HTML 标记。在演示项目中,这是 PrintDemo 视图。

下面显示了演示项目中的 PrintDemo 视图。正如您所看到的,这只是一个简单的 ASP.NET Razor 视图,带有一个表格和一些行。它使用了强类型模型,但这并非必需。在尝试设计报告时的一个技巧是为您的 tablediv 添加边框。使用这些边框,当查看生成的 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 报告来工作。

6 Classes that make up the PdfReportGenerator project

将 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 报告添加了图片。  
© . All rights reserved.