jQGrid PDF 导出





5.00/5 (2投票s)
使用 iTextSharp,可以更轻松地将 jQGrid 的内容导出为 PDF 格式。
引言
本文旨在解决客户端网格框架的 PDF 导出问题。解决方案使用 ASP.NET MVC 4 和 Visual Studio 2012 中的 iTextSharp 实现。 jQGrid 是基于 jQuery 框架构建的客户端网格框架之一。它有助于构建具有分页、排序和导出选项的美观网格。还有其他功能作为扩展插件可用,开发人员也可以根据需要自行编写。如果在 DLL 引用时遇到问题,请在运行演示代码之前先更新 nuget。我已经启用了 nuget 还原,因此在构建过程中会下载并更新引用。
背景
本文假定开发人员对 ASP.NET MVC 和 C# 有一定的了解。
使用的工具
- Visual Studio 2012
- ASP.NET MVC 4
- Nuget 包管理器
开发人员可以在 https://jqueryjs.cn/ 了解 jQuery 和 jQueryUI。
jQgrid 相关维基可以在以下链接中找到:
- http://www.trirand.net/examples/grid/exporting/pdf/default.aspx
- http://www.trirand.com/jqgridwiki/doku.php
iTextSharp 教程可以在以下链接中找到:
使用代码
您可以在 jQGrid 主页或通过 NUget 包下载 jQgrid。我在下方提供了通过包管理器控制台下载 jQGrid 的命令。从“工具”菜单中选择“库包管理器”,然后选择“程序包管理器控制台”。我在下方提供了截图。
此命令将下载最新的 JQGrid 包并将其添加到脚本文件夹中。
下载脚本并将其引用到项目中后,更新 bundleconfig 文件以将脚本引用添加到页面中。Bundleconfig 可以在项目结构中的 _App_Start_ 文件夹中找到。
bundles.Add(new StyleBundle("~/Content/jqgrid").Include("~/Content/ui.jqgrid.css"));
bundles.Add(new ScriptBundle("~/bundles/jquerygrid").Include(
"~/Scripts/jqGrid/jquery.jqGrid*"));
添加配置后,将这些包引用到 _Views/Shared/LayoutPage.cshtml_。将以下行添加到页面的 head 部分。
@Styles.Render("~/Content/jqgrid")
在 html 关闭标签之前,将以下行添加到页面末尾。
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")
@Scripts.Render("~/bundles/jquerygrid")
从视图的角度来说,就这些了。完成这些步骤后,开发人员就可以开始编写 JQGrid 的代码了。在本例中,我们将修改 HomeController 以用于演示。index 操作将是默认操作。我们将为此 index 操作添加一个参数。让它成为一个可空布尔值。这只是为了标记 PDF 请求。在 _Index.cshtml_ 中,我们将添加一个 id 为“gridTable
”的 table 标签。我们将使用此 table 来创建网格。由于 jQGrid 是 jQuery 的一个扩展,我们将在页面的脚本部分初始化网格设置。此脚本部分位于页面底部,以提高性能。脚本部分放置在 jQuery 和 jQueryUI 的包引用正下方。这是雅虎提供的“为什么慢”中的一个改进因素。
<table id="gridTable" class="scroll"></table>
<input type="button" value="Export PDF" onclick="exportPDF();" />
@section scripts
{
<script type="text/javascript">
$(document).ready(
function ()
{
$("#gridTable").jqGrid(
{
datatype: "json",
url: '@Url.Action("GetCustomerDetails")'">
'@Url.Action("GetCustomerDetails")'</a />,
mtype: 'GET',
colNames: ["CustomerID", "CustomerName",
"Location", "PrimaryBusiness"],
colModel: [
{name:"CustomerID",width:40,index:"CustomerID",align:"center"},
{ name: "CustomerName", width: 40, index: "CustomerName", align: "center" },
{ name: "Location", width: 40, index: "Location", align: "center" },
{ name: "PrimaryBusiness", width: 40, index: "PrimaryBusiness", align: "center" },
],
height: 250,
autowidth: true,
sortorder: "asc",
rowNum: 10,
rowList: [5, 10, 15, 20],
sortname: "CustomerID",
sortorder: "desc",
viewrecords:true
}
);
}
);function exportPDF() {
document.location='@Url.Action("Index")?pdf=true'>;
}
</script>}
exportPDF
方法只是将文档位置设置为 Index 操作方法,并将 PDF 布尔值设置为 true,以便标记下载 PDF。内存中的列表集合用于演示目的。GetCustomerDetails
方法是提供 JSON 列表数据的服务器端操作方法。我们将在下面看到该方法的说明。
[HttpGet]
public JsonResult GetCustomerDetails()
{
Var result = new
{
total = 1,
page = 1,
records = customerList.Count(),
rows =(
customerList.Select(e=>
new {id=e.CustomerID,cell=new string[]{
e.CustomerID.ToString(),e.CustomerName,e.Location,e.PrimaryBusiness}})
).ToArray()
};
return Json(result, JsonRequestBehavior.AllowGet);
}
jQGrid 可以理解服务器以特定格式发送的响应数据。上面的服务器方法负责格式化响应,以便 JQGrid 正确理解数据。响应数据应包含总页数、当前页数、总记录数、包含 ID 的行以及其他列,作为字符串数组。响应是使用匿名对象构建的,并将作为 MVC JsonResult 发送。由于我们使用 HttpGet,最好将属性标记为 HttpGet,并将 JSON 请求行为设置为 AllowGet
。内存列表在 HomeController 构造函数中初始化以供引用。
public class HomeController : Controller
{
private readonly IList<CustomerViewModel> customerList;
public HomeController()
{
customerList =new List<CustomerViewModel>() {
new CustomerViewModel{CustomerID=100,
CustomerName="Sundar",Location="Chennai",PrimaryBusiness="Teacing"},
new CustomerViewModel{CustomerID=101,
CustomerName="Sudhagar",Location="Chennai",PrimaryBusiness="Software"},
new CustomerViewModel{CustomerID=102,
CustomerName="Thivagar",Location="China",PrimaryBusiness="SAP"},
};
}
public ActionResult Index(bool? pdf)
{
if (!pdf.HasValue)
{
return View(customerList);
}
else
{
string filePath = Server.MapPath("Content") + "Sample.pdf";
ExportPDF(customerList, new string[] { "CustomerID",
"CustomerName", "Location", "PrimaryBusiness" }, filePath);
return File(filePath, "application/pdf","list.pdf");
}
}
}
index 操作方法有一个名为 pdf
的布尔参数。它用于指示 PDF 下载。当应用程序启动时,此方法首先被调用以进行初始页面请求。对于 PDF 操作,会生成一个文件名,然后将其发送到 ExportPDF
方法,该方法将负责从数据源生成 PDF。ExportPDF
方法列在下面。这是一个泛型方法,可以处理任何数据源。由于列名作为参数传递,因此无需担心属性名称。
private static void ExportPDF<TSource>(IList<TSource> customerList,string[] columns, string filePath)
{
Font headerFont = FontFactory.GetFont("Verdana", 10, Color.WHITE);
Font rowfont = FontFactory.GetFont("Verdana", 10, Color.BLUE);
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(document,
new FileStream(filePath, FileMode.OpenOrCreate));
document.Open();
PdfPTable table = new PdfPTable(columns.Length);
foreach (var column in columns)
{
PdfPCell cell = new PdfPCell(new Phrase(column, headerFont));
cell.BackgroundColor = Color.BLACK;
table.AddCell(cell);
}
foreach (var item in customerList)
{
foreach (var column in columns)
{
string value = item.GetType().GetProperty(column).GetValue(item).ToString();
PdfPCell cell5 = new PdfPCell(new Phrase(value, rowfont));
table.AddCell(cell5);
}
}
document.Add(table);
document.Close();
}
iTextSharp 是 PDF 导出的先驱之一。它是一个开源库,可以轻松通过 NUget 库获得。
此命令将下载最新可用库。我使用的是版本 4.1.2.0。最新版本可能已更改。此库中有三个主要部分。
- Document:这是 Document 类,负责以特定大小创建文档页面。我们使用了 A4 尺寸。还可以选择定义矩形大小。此文档实例将在后续方法中作为引用使用。
- PdfWriter:PdfWriter 以文件名和文档作为引用。此类使 Document 类能够生成 PDF 内容并将其保存到文件中。
- Font:使用 FONT 类,开发人员可以控制字体特征。由于我需要一个漂亮的字体,我使用了 Verdana 字体。
在此之后,使用 PdfPTable
和 PdfPCell
来生成标准的表格布局。我们为页眉和页脚创建了两组字体。
Font headerFont = FontFactory.GetFont("Verdana", 10, Color.WHITE);
Font rowfont = FontFactory.GetFont("Verdana", 10, Color.BLUE);
我们以字符串数组的形式获取页眉列。循环遍历 Columns 参数数组并生成页眉。我们为此目的使用了 headerfont。
PdfWriter writer =
PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.OpenOrCreate));
document.Open();
PdfPTable table = new PdfPTable(columns.Length);
foreach (var column in columns)
{
PdfPCell cell = new PdfPCell(new Phrase(column, headerFont));
cell.BackgroundColor = Color.BLACK;
table.AddCell(cell);
}
然后使用反射生成逐行详细信息并形成网格。
foreach (var item in customerList)
{
foreach (var column in columns)
{
string value = item.GetType().GetProperty(column).GetValue(item).ToString();
PdfPCell cell5 = new PdfPCell(new Phrase(value, rowfont));
table.AddCell(cell5);
}
}
document.Add(table);
document.Close();
过程完成后,将 PDF 表添加到文档中,然后关闭文档以将所有更改写入指定的文件路径。然后控制权将移交给控制器,控制器将负责将响应作为 JSON 结果发送,并附带文件名。如果未提供文件名,PDF 将在同一页面上打开;否则,将弹出窗口询问您是保存文件还是打开文件。
return File(filePath, "application/pdf","list.pdf");
最终结果屏幕如下所示。
PDF 文件已打开,如下所示,以展示输出。
结论
这就是 JQGrid 的 PDF 导出过程。本文解决的问题区域是客户端网格框架不支持 PDF 导出。在这种情况下,最好能够精细地控制数据和生成的 PDF。 iTextSharp 帮助我们实现了目标。