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

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (20投票s)

2007 年 3 月 23 日

CPOL

14分钟阅读

viewsIcon

490870

downloadIcon

18045

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

Screenshot - iTextSharpPdfTables.png

引言

使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 文件的教程提供了关于您可以创建的各种 PDF 文件的见解。本文的重点是 iTextSharp 中相对较小但非常有趣的一个子集;即创建数据以表格形式呈现的 PDF 文件的能力,就像图片中所示的那样。

复杂性

即使是创建 PDF 表格这个狭窄的目标,也面临着三个挑战。

1:PDF 规范

创建 PDF(任何类型,不仅仅是表格数据)的挑战之一是理解其众多选项。这些选项在其详细描述中,位于 PDF 格式所有者 Adobe 提供的免费文档中。(最新版本超过 1300 页!)下图显示了一些更常见的选项。

    Application Screen Shot - Selection

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,也来自同一个项目。
没有为其他类型的 XML 文件提供支持。大多数纯 XML可能无需新代码即可运行。但很可能,您将无法在不修改代码以适应其他 XML 文件类型的情况下创建 PDF。

Watermark.jpg 文件来自 iTextSharp 教程网站。

使用应用程序

在执行任何操作之前,请务必阅读上面的免责声明。

主窗口

该解决方案包含一个带三个选项卡的tabControl控件

  • 信息显示
    • 根据帮助菜单请求显示的网页和 PDF 文件
    • 通过“选择”选项卡使用的 XmlStore 文件,成功生成了 PDF 表格
  • 选择显示用于选择从中生成 PDF 的XmlStore(或纯 XML)文件的按钮。它还显示了上图中显示的所有选项。这些选项将在下面介绍。
  • 生成的 PDF 显示根据您的选择创建的 PDF。

“选择”选项卡

“选择”选项卡包含了从 XML 文件创建所需 PDF 的功能。下面简要介绍。

XmlStore 文件...按钮

使用此按钮选择一个XmlStore纯 XML 文件,如上所示。PDF 文件会立即生成,基于您选择的选项(参见下图)。

    Application Screen Shot - Selection

选项将在下面非常简要地描述。(有关更详细的信息,您需要阅读 Adobe 和 iTextSharp 提供的文档,通过“帮助”菜单或上面的某些链接,或者由 iText 的创建者最近出版的书籍。)

PDF 文档摘要

您在这些四个文本框中提供的信息会嵌入到 PDF 中
  • 标题
  • 主题
  • 作者
  • 关键词
这些信息会与其他的文档属性一起显示在 Adobe PDF Reader 中。

默认按钮

它使用说明性默认值填充各种选项。

显示...选项

这些选项仅适用于解决方案如何生成 PDF 表格。
  • 标题(如果选中)会在每个 PDF 页面的顶部边距显示标题(来自上面的 PDF 文档摘要)
  • 页码(如果选中)会在每个 PDF 页面的底部边距显示页码
  • 水印(如果选中)会在每页的中间显示一个水印
    • 文本将以 45 度角显示任何单词或短语(例如“保密”)
    • 文件将显示您指定的文件
  • 横向(如果选中)将以横向模式显示所有页面
  • 纸张大小决定每页的大小。此解决方案仅支持三种尺寸,即在美国最常用的LetterLegal纸张尺寸,以及在世界大部分地区广泛使用的 ISO A4 尺寸。
  • 缩放因子:列宽(默认值 = “1.0”)是一个乘数,它简单地缩放列的widths。默认情况下,所有列都跨越页面宽度(留有页边距空间)。表格始终在每页上水平居中。因此,如果您将缩放因子设置为“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 之前,务必查阅 Adobe 和 iTextSharp 的文档以了解详细信息。

帮助菜单

“帮助”菜单包含指向两个重要信息来源的链接
  • iTextSharp 教程主页
  • Adobe PDF 规范(各种版本)

    尝试一下。您会明白为什么它们非常重要,特别是如果您决心创建自己的 PDF。

    使用代码

    在执行任何操作之前,请务必阅读上面的免责声明。

    先决条件

    此解决方案是使用 Visual Studio 2005 创建的,在生成解决方案之前,您需要使用 VS2005 的项目 > 添加引用菜单命令为iTextSharp.DLL版本 4.x 提供一个Reference。如果您没有,可以通过以下指向 SourceForge.net 的链接下载仅 DLL 或源代码(并自行构建)。

    构建解决方案

    如果您有 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。)

    最后,感谢您

    我从像您一样匿名且免费地分享经验的人那里学到了很多东西。也许您贡献了一点,但我学到了很多。如果这个工具对哪怕一个人有帮助,那将使我的一天变得美好,并给我一个机会回馈社区。所以,谢谢您!

    其他近期贡献

  • “使用 C# (.NET 2.0) 和 iTextSharp 创建 PDF 文件的教程”。2007 年 3 月 16 日
  • “一个用于读取、编辑、加密、解密、写入 XmlStore 文件的实用程序”。2007 年 3 月 12 日
  • “XmlStore 第二部分:打印 DataGridView 内容”。2007 年 3 月 18 日
  • “一个简单的实用程序,用于快速创建图像文件的反射版本(*.GIF, *.PNG 等)”。2007 年 3 月 6 日
  • “一个简单的实用程序,用于快速创建不透明或透明的图像文件(*.GIF, *.PNG 等)”。2007 年 3 月 5 日
  • 如果这些中的任何一个对您有帮助……

    请考虑向我最喜欢的某个事业捐款:Year Up 或世界范围内任何类似的非政府组织,这些组织无私地做好事并帮助有需要的人。少献一点,多收获!

    © . All rights reserved.