使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 表格
使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 表格

引言
使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 文件的教程提供了关于您可以创建的各种 PDF 文件的见解。本文的重点是 iTextSharp 中相对较小但非常有趣的一个子集;即创建数据以表格形式呈现的 PDF 文件的能力,就像图片中所示的那样。复杂性
即使是创建 PDF 表格这个狭窄的目标,也面临着三个挑战。1:PDF 规范
创建 PDF(任何类型,不仅仅是表格数据)的挑战之一是理解其众多选项。这些选项在其详细描述中,位于 PDF 格式所有者 Adobe 提供的免费文档中。(最新版本超过 1300 页!)下图显示了一些更常见的选项。

2:iTextSharp 文档
iTextSharp 在使用 C# (.NET 2.0) 创建 PDF 方面提供了极大的便利。它在很大程度上消除了理解 PDF 规范所有细微之处的必要。然而,尽管有许多可用示例,使用 iTextSharp 创建非平凡 PDF 仍然可能是一个陡峭的学习曲线。由作者撰写的一本最近出版的书籍《iText in Action》的篇幅是 Adobe 最新规范文档的一半。如果您打算认真依赖 iTextSharp,这本书将是无价的,但您仍然需要做一些繁重的工作。您不仅需要理解 Adobe PDF 规范的底层概念,还需要弄清楚 iTextSharp 是如何组织来解决这些问题的。例如,为页面编号这个简单的练习需要您创建一个事件处理程序,然后确保您在正确的画布/图层上构造和编写适当的字符串。
一些额外的有用链接
3:数据和表格的多样性
表格数据存储在各种数据库(SQL Server、Oracle、Access、MySQL 等)、专有二进制文件、电子表格、文本文件(制表符分隔、XML)等中。因此,没有任何单一的解决方案,至少不像我的那样简单,可以适用于所有情况。换句话说,直到有聪明人出现拯救我们,我们才需要为我们想要解决的每种变体(数据源和 PDF 布局)构建自己的解决方案。
因此...
这些复杂性的最终结果是——拥有满足几个简单目标的可用代码可能很有用
- 使用一个简单但常用的数据源
- 拥有一个简单的用户界面,可以轻松地试验创建 PDF 时可以选择的许多组合(参见上图)
- 包含演示如何利用 iTextSharp 的一种方法的代码(认识到您需要编写大量代码来处理数据源和 PDF 布局的各种特定组合)
本文试图做到这一点。
警告
一旦您掌握了 iTextSharp,创建简单的 PDF 就很容易了。但是,创建有用、实用、外观良好的 PDF 可能比乍看之下要困难。
解决方案
在其基本形式中,表格数据看起来像这样发行日期 | 跟踪 | 标题 | Artist | 专辑 |
---|---|---|---|---|
11/22/1968 | 29 | Revolution 9 | Beatles | The Beatles [White Album] |
1960 | 6 | Fools Rush In | Frank Sinatra | Nice 'N' Easy |
11/11/1971 | 1 | One of These Days | Pink Floyd | Meddle |
1988 | 7 | Where Is My Mind? | Pixies | Surfer Rosa |
5/1981 | 9 | Can't Find My Mind | Cramps | Psychedelic Jungle |
6/10/2003 | 13 | Scatterbrain. (As Dead As Leaves.) | Radiohead | Hail to the Thief |
6/30/1992 | 3 | Dress | P J Harvey | Dry |
这样的表格可以来自数据库、电子表格、DataGridView、DataGrid、GridView 等。它仅仅是记录行和字段列的集合。
由于 XML 被广泛理解且不需要特殊数据库,本文使用两种简单的 XML 数据源来表示上图所示的数据表。纯 XML
在下面的 XML 中,每一行(记录)都表示在一个名为 song
的单一节点中,而每一列(字段)则表示为该节点的属性。
请注意,根节点下方只有一个级别的节点,即它们没有任何子节点。.
<?xml version="1.0" encoding="utf-8"?>
<root>
<song ReleaseDate="11/22/1968" Track="29" Title="Revolution 9"
Artist="Beatles" Album="The Beatles [White Album]" />
<song ReleaseDate="1960" Track="6" Title="Fools Rush In"
Artist="Frank Sinatra" Album="Nice 'N' Easy" />
<song ReleaseDate="11/11/1971" Track="1" Title="One of These Days"
Artist="Pink Floyd" Album="Meddle" />
<song ReleaseDate="1988" Track="7" Title="Where Is My Mind?"
Artist="Pixies" Album="Surfer Rosa" />
<song ReleaseDate="5/1981" Track="9" Title="Can't Find My Mind"
Artist="Cramps" Album="Psychedelic Jungle" />
<song ReleaseDate="6/10/2003" Track="13" Title="Scatterbrain. (As Dead As Leaves.)"
Artist="Radiohead" Album="Hail to the Thief" />
<song ReleaseDate="6/30/1992" Track="3" Title="Dress"
Artist="P J Harvey" Album="Dry" />
</root>
XmlStore
下面的 XmlStore 文件包含与上面的纯 XML 完全相同的数据,但有一些不同之处
root
被命名为xmlStore
- 它有一个名为
schema
的附加节点 schema
为数据行(记录)的每个属性(例如song
)有一个field
节点- 每个
field
节点包含有关以下信息:- 数据行(记录)属性的
name
- 在列标题中显示的
title
- 显示列的相对
width
- 数据行(记录)属性的
<?xml version="1.0" encoding="utf-8"?> <xmlStore version="1.0"> <schema datanodename="song"> <field name="ReleaseDate" title="Release Date" width="9"/> <field name="Track" title="Track" width="5"/> <field name="Title" title="Title" width="40"/> <field name="Artist" title="Artist" width="15"/> <field name="Album" title="Album" width="25"/> </schema> <song ReleaseDate="11/22/1968" Track="29" Title="Revolution 9" Artist="Beatles" Album="The Beatles [White Album]" /> <song ReleaseDate="1960" Track="6" Title="Fools Rush In" Artist="Frank Sinatra" Album="Nice 'N' Easy" /> <song ReleaseDate="11/11/1971" Track="1" Title="One of These Days" Artist="Pink Floyd" Album="Meddle" /> <song ReleaseDate="1988" Track="7" Title="Where Is My Mind?" Artist="Pixies" Album="Surfer Rosa" /> <song ReleaseDate="5/1981" Track="9" Title="Can't Find My Mind" Artist="Cramps" Album="Psychedelic Jungle" /> <song ReleaseDate="6/10/2003" Track="13" Title="Scatterbrain. (As Dead As Leaves.)" Artist="Radiohead" Album="Hail to the Thief" /> <song ReleaseDate="6/30/1992" Track="3" Title="Dress" Artist="P J Harvey" Album="Dry" /> </xmlStore>
有关 XmlStore 的更多信息,请参阅一个用于读取、编辑、加密、解密、写入 XmlStore 文件的实用程序。
免责声明
我进行此项目是为了学习 Visual Studio 2005、C#、XML、DataGridView、PDF 等方面的知识。免责声明:没有任何内容经过适当或充分的测试。更重要的是,您或其他人很可能做得更好。因此,如果您使用此代码但无法获得预期结果,我可能帮不了您太多。但好的一面是,您拥有源代码和来自 Adobe 以及 iTextSharp 的所有您需要的技术参考资料。
此解决方案包含来自iTextSharp 教程网站的三个示例,其中两个示例未包含在我使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 文件的教程中。
此解决方案还包含反映了我对 C#、iTextSharp 和 PDF 有限理解的代码。它仅仅是一个学习工具,不具有其他任何目的。
重要提示:项目中 Data 文件夹中的 XML 文件是实际测试代码的唯一文件。它们是:
- BogusData.xml——这是 iTextSharp 教程第 5 章示例 18 的数据在 XML 中的版本Chap 5 Example 18。
- Passwords_NoSchema.xml——来自另一个XmlStore 项目。
- PlayList_Small.xml 和 PlayList.xml,也来自同一个项目。
Watermark.jpg 文件来自 iTextSharp 教程网站。
使用应用程序
在执行任何操作之前,请务必阅读上面的免责声明。主窗口
该解决方案包含一个带三个选项卡的tabControl控件
- 信息显示
- 根据帮助菜单请求显示的网页和 PDF 文件
- 通过“选择”选项卡使用的 XmlStore 文件,成功生成了 PDF 表格
- 选择显示用于选择从中生成 PDF 的XmlStore(或纯 XML)文件的按钮。它还显示了上图中显示的所有选项。这些选项将在下面介绍。
- 生成的 PDF 显示根据您的选择创建的 PDF。
“选择”选项卡
“选择”选项卡包含了从 XML 文件创建所需 PDF 的功能。下面简要介绍。XmlStore 文件...按钮
使用此按钮选择一个XmlStore 或纯 XML 文件,如上所示。PDF 文件会立即生成,基于您选择的选项(参见下图)。

选项将在下面非常简要地描述。(有关更详细的信息,您需要阅读 Adobe 和 iTextSharp 提供的文档,通过“帮助”菜单或上面的某些链接,或者由 iText 的创建者最近出版的书籍。)
PDF 文档摘要
您在这些四个文本框中提供的信息会嵌入到 PDF 中- 标题
- 主题
- 作者
- 关键词
默认按钮
它使用说明性默认值填充各种选项。显示...选项
这些选项仅适用于此解决方案如何生成 PDF 表格。- 标题(如果选中)会在每个 PDF 页面的顶部边距显示标题(来自上面的 PDF 文档摘要)
- 页码(如果选中)会在每个 PDF 页面的底部边距显示页码
- 水印(如果选中)会在每页的中间显示一个水印
- 文本将以 45 度角显示任何单词或短语(例如“保密”)
- 文件将显示您指定的文件
- 横向(如果选中)将以横向模式显示所有页面
- 纸张大小决定每页的大小。此解决方案仅支持三种尺寸,即在美国最常用的Letter和Legal纸张尺寸,以及在世界大部分地区广泛使用的 ISO A4 尺寸。
- 缩放因子:列宽(默认值 = “1.0”)是一个乘数,它简单地缩放列的
width
s。默认情况下,所有列都跨越页面宽度(留有页边距空间)。表格始终在每页上水平居中。因此,如果您将缩放因子设置为“0.8”,则生成的表格将窄 20%,因为每列的width
按比例减小。将缩放因子设置为“1.05”,则表格和每列将拓宽 5%。(注意:如果 XML 文件不包含列width
值,则每列默认为相同宽度。)
字体选项
这些选项仅适用于此解决方案如何生成 PDF 表格。它们决定了用于正文数据字段和表格中每个列标题的字体。- 字体名称确定使用的字体名称
- 字号确定字体的大小(以磅为单位)
- 字体样式确定字体是普通、粗体、斜体,还是两者兼有。
视图...选项
这些选项仅适用于此解决方案如何生成 PDF 表格。它们指定您的“查看偏好”,即当文件首次打开时,您希望 Adobe Reader 如何显示 PDF。- 2 页布局(如果选中)使用
PdfWriter.PageLayoutTwoColumnLeft
,否则使用默认值PdfWriter.PageLayoutSinglePage
(有关详细信息,请参见 iTextSharp) - 工具栏决定 Adobe Reader 是否显示其工具栏
- 菜单栏决定 Adobe Reader 是否显示其菜单栏
- 窗口 UI 决定 Adobe Reader 是否显示滚动条、导航控件等。
- 调整大小以适应窗口决定 Adobe Reader 是否应将初始页面“适合”其窗口显示
- 居中显示正是如此,但仅当 Adobe Reader 在独立浏览器中运行时;在此解决方案中无效
- 加密请参见下一节
加密...选项
这些选项仅适用于此解决方案如何生成 PDF 表格。它们决定了生成的 PDF 文件是否需要加密以及/或是否包含对用户在 Adobe PDF Reader 中查看 PDF 时可以执行的操作的嵌入式限制。- 所有者密码(如果提供)将加密文件
- 用户密码(如果提供)将要求用户输入密码才能打开查看 PDF 的内容
- 打印(如果未选中)将阻止用户打印内容
- 打印降级版(如果未选中)将阻止用户打印 PDF 的降级版本(有关详细信息,请参见 Adobe 的文档)
- 修改内容(如果未选中)将阻止用户修改 PDF 的内容(有关详细信息,请参见 Adobe 的文档)
- 复制(如果未选中)将阻止用户复制 PDF(有关详细信息,请参见 Adobe 的文档)
- 修改注释请参见 Adobe 和/或 iTextSharp 的文档了解详细信息
- 填充表单请参见 Adobe 和/或 iTextSharp 的文档了解详细信息
- 屏幕阅读请参见 Adobe 和/或 iTextSharp 的文档了解详细信息
- 组合请参见 Adobe 和/或 iTextSharp 的文档了解详细信息
- 强加密(如果未选中)使用 40 位加密,如果选中,则使用 128 位加密。两者都使用上述密码
帮助菜单
“帮助”菜单包含指向两个重要信息来源的链接尝试一下。您会明白为什么它们非常重要,特别是如果您决心创建自己的 PDF。
使用代码
在执行任何操作之前,请务必阅读上面的免责声明。先决条件
此解决方案是使用 Visual Studio 2005 创建的,在生成解决方案之前,您需要使用 VS2005 的项目 > 添加引用菜单命令为iTextSharp.DLL版本 4.x 提供一个Reference
。如果您没有,可以通过以下指向 SourceForge.net 的链接下载仅 DLL 或源代码(并自行构建)。
- 下载 iTextSharp DLL(约 1 MB)
- 下载 iTextSharp 源代码(约 3 MB)
构建解决方案
如果您有 Visual Studio 2005,那么您应该可以直接使用项目源代码——只需构建并运行。代码本身并非高深莫测。它有合理的文档记录。更重要的是,您可以通过“帮助”菜单中的宝贵链接,获得大量关于代码功能的信息。如果您没有 Visual Studio 2005,您将不得不请一位更有经验的朋友帮忙。(不要问我,因为我是新手!我对 VB.NET 也一无所知!)
代码模块
代码对新手(像我一样)的好处:该项目包含一些模块,其中包含有合理文档记录且自明的代码。如果运气好的话,它们可能有助于您学习所用子系统的某些功能。(其中许多在末尾列出的文章中都有描述。)这里只关注那些与使用 C# 创建 PDF 相关的。VVX_PDF.cs
VVX.PDF
是一个包装类,用于转换上面描述的用户界面选项并调用相应的 iTextSharp 功能。它包含以下内容(每个都分组在 #region
...#endregion
标签中):
- Enums
- 成员变量
- 用于设置/获取成员变量值的属性
- 私有的辅助方法
- XmlStore 方法包含三个重要方法,它们代表了此解决方案的“核心”:
-
DoCreateFromXmlStore(...)
这个相对精简的方法只是遵循 iTextSharp 的步骤 1 到 5。对于步骤 4,它将求助于 DoLoadDocument(...) 方法从 XML 文件中提取数据。 -
DoLoadDocument(...)
这是 iTextSharp 教程第 0518 章和第 1202 章中 LoadDocument 方法的增强和定制版本。尽管代码有合理的文档记录,但您最好访问 iTextShart 教程网站(也许通过此解决方案的“帮助”菜单)阅读更多关于代码的内容。 -
DoConfigPageEventHandler(...)
这是一个辅助方法,它初始化您必须编写的自定义“新页面”事件处理程序,以实现显示...选项,即标题、页码和水印,以及为列标题绘制“灰色”背景。
-
VVX_PDF_TableEvents.cs
VVX.PDF_TableEvents
基本上包含一个包含 iTextSharp 所需事件处理程序的单一类。它在 iTextSharp 完成 PDF 表格的每个页面的合成后被调用。在此类中,您
- 跟踪页码
- 在顶部边距绘制标题
- 在底部边距绘制页码
- ……或者以您希望的任何方式“装饰”您的页面和/或表格。
iText
如果您想了解更多关于 iText(iTextSharp 的基础)的信息,请单击此处。
有替代方案
如果 iTextSharp 太难,您可以考虑使用一些商业 PDF 解决方案,其中一些价格相当便宜。但是,我并没有在它们身上取得太大成功。(我发现唯一可以轻松创建 PDF 的地方是我的 iMac;从任何应用程序创建 PDF 都毫不费力!而且您还可以获得漂亮的 PDF。)
最后,感谢您
我从像您一样匿名且免费地分享经验的人那里学到了很多东西。也许您贡献了一点,但我学到了很多。如果这个工具对哪怕一个人有帮助,那将使我的一天变得美好,并给我一个机会回馈社区。所以,谢谢您!
其他近期贡献
如果这些中的任何一个对您有帮助……
请考虑向我最喜欢的某个事业捐款:Year Up 或世界范围内任何类似的非政府组织,这些组织无私地做好事并帮助有需要的人。少献一点,多收获!