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

PDF 文件写入器 C# 类库 (版本 2.0.0)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (652投票s)

2013 年 4 月 1 日

CPOL

50分钟阅读

viewsIcon

3814690

downloadIcon

190035

PDF 文件写入器是一款 C# .NET 类库,允许应用程序创建 PDF 文件。该代码是为 VS 2022 和 .NET6 开发的。最新更新是一个重大升级。

引言

PDF 文件写入器 II C# 类库允许您直接从 .net 应用程序创建 PDF 文件。该库为您屏蔽了 PDF 文件结构的详细信息。此版本的 PDF 文件写入器库是使用 Visual Studio 2022 开发的,目标框架为 .NET 6.0,目标操作系统为 Windows,并且已勾选启用 Windows 窗体。

新功能

  • 交互式表单,也称为 AcroForm。您将能够定义文本字段、按钮、组合框、列表框、复选框和单选按钮。
  • 重写所有与注释相关的类,以包含作为注释家族一部分的新交互式表单。
  • 简化文本行绘制的调用序列。所有输入参数都由一个类 PdfDrawTextCtrl 处理。
  • 简化常用图形对象(矩形、圆角矩形、倒圆角矩形和椭圆)的调用序列。图形对象可以有可选边框。背景可以是纯色、图像、填充和图案。所有输入参数都由一个类 PdfDrawCtrl 处理。
  • 简化一维条形码的调用序列。所有输入参数都由一个类 PdfDrawBarcodeCtrl 处理。
  • 支持 Type-1 字体,即 Adobe Acrobat Reader 内置的 14 种标准字体。此支持主要针对交互式表单。
  • 支持将单个字符绘制为图形。请参阅 PdfSymbol
  • 已重命名部分类和方法,以提供一致的外观。

PdfFileWriter 1.28.0 中未包含的功能

  • WPF 图形。它不受 .NET 6.0 支持。
  • 图表不受 .NET 6.0 支持。如果您需要此功能,请在您的应用程序中将图表转换为图像并绘制该图像。
  • .CHM 帮助文件。生成帮助文件的 Sandcastle 软件不支持 .NET 6.0。

注意:使用 PDF File Writer 1.28.0 及更早版本的开发人员。升级到新版本 2.0.0 需要修改您的源代码。有关更多详细信息,请参阅下面的 升级部分

要将该库集成到您的应用程序中,您需要将 PdfFileWriter.dll 添加为项目的依赖项。在解决方案资源管理器中点击您的项目依赖项,然后添加对附加的 PdfFileWriter.dll 类库文件的引用。在每个使用该库的源文件中添加 using PdfFileWriter 语句,并将 PdfFileWriter.dll 与您的发行版一起包含。有关更多详细信息,请转至 安装

PDF 文件写入器 II C# 类库支持以下 PDF 文档功能

创建 PDF 是一个六步过程。

  • 步骤 1:创建一个文档对象 PdfDocument
  • 步骤 2:创建常用资源,如字体或图像(例如 PdfFontPdfImage)。
  • 步骤 3:创建一个页面对象 PdfPage
  • 步骤 4:创建一个内容对象 PdfContents
  • 步骤 5:向内容对象添加文本和图形(使用 PdfContents 方法)。
  • 对额外的页面重复步骤 3、4 和 5。
  • 步骤 6:通过调用 PdfDocumentCreateFile 方法来创建您的 PDF 文档文件。

步骤 5 是您大部分编程工作将花费的地方。通过调用 PdfContents 类的各种方法来渲染图形和文本,可以实现内容的添加。内容类拥有一个丰富的集合(约 100 个)方法,用于向您的文档添加文本和图形。

PdfDocument 实现 IDisposable 接口以释放非托管资源。CreateFile 方法在 PDF 文件创建后调用 Document.Dispose()。但是,为了确保资源得到释放,您应该将 PdfDocument 的创建和最终的 CreateFile 包装在 using 语句或 try/catch 块中。

本文附加的演示程序是一系列测试程序。这些程序旨在测试和调试该库。TestPdfFileWriter 在主屏幕底部有按钮。按下这些按钮将生成 PDF 文件示例。最右边的按钮将显示您计算机上可用的所有字体。第一个按钮“文章示例”会创建本文顶部显示的 PDF 文件。这些演示程序中的每个程序源代码都用注释进行了充分的文档化。这些模块应该是您获取如何与该库接口的第一个信息来源。

如前所述,PdfFileWriter C# 类库为您屏蔽了 PDF 文件结构的复杂性。但是,充分理解 PDF 文件始终是有益的。Adobe PDF 文件规范文档可从 Adobe 网站获取:“PDF 参考,第六版,Adobe 可移植文档格式版本 1.7,2006 年 11 月”。这是一份长达 1310 页的令人望而生畏的文档。我强烈建议阅读第 4 章“图形”和第 5 章“文本”的第 5.2 和 5.3 节。

如果您想分析此项目创建的 PDF 文件,或者想了解 PDF 文件结构,您可以使用我文章 “使用 C# 解析类分析 PDF 文件” 中附带的演示程序。本文提供了 PDF 规范的简洁概述。

Hello PDF File Writer 程序

一个非常简单的创建 PDF 文档的示例,包含一行文本和一个图像。

// create PDF document
public void CreatePdfDocument()
  {
  // Create empty document
  using(PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, "HelloPdfDocument.pdf"))
    {
    // Add new page
    PdfPage Page = new PdfPage(Document);

    // Add contents to page
    PdfContents Contents = new PdfContents(Page);

    // create font
    PdfFont ArialNormal = PdfFont.CreatePdfFont(Document, "Arial", FontStyle.Regular, true);
    PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, 18.0);
				
    // draw text
    TextCtrl.Justify = TextJustify.Center;
    Contents.DrawText(TextCtrl, 4.5, 7, "Hello PDF Document");

    // load image
    PdfImage Image = new PdfImage(Document);
    Image.LoadImage("..\\..\\..\\HappyFace.jpg");

    // draw image
    PdfDrawCtrl DrawCtrl = new PdfDrawCtrl();
    DrawCtrl.Paint = DrawPaint.Fill;
    DrawCtrl.BackgroundTexture = Image;
    Contents.DrawGraphics(DrawCtrl, new PdfRectangle(3.5, 4.8, 5.5, 6.8));

    // create pdf file
    Document.CreateFile();
    }

  // start default PDF reader and display the file
  Process Proc = new Process();
  Proc.StartInfo = new ProcessStartInfo("HelloPdfDocument.pdf") { UseShellExecute = true };
  Proc.Start();
  }

PDF 文件写入器库功能

坐标系统和度量单位

PDF 坐标系统的原点位于页面左下角。X 轴指向右方。Y 轴指向上方。

PDF 的度量单位是点。一英寸有 72 点。PDF 文件写入器允许您选择自己的度量单位。代表位置、宽度或高度的所有方法参数都必须以您的度量单位表示。有两个例外:字体大小和分辨率。字体大小始终以点为单位。分辨率始终以每英寸像素为单位。PDF 文件写入器会将所有输入参数转换为点。所有内部测量值和计算均使用双精度进行。在创建 PDF 文件时,值将被转换为文本字符串。转换精度为六位数字。使用的转换公式为

// Dimension value is double
if(Math.Abs(Value) < 0.0001) Value = 0.0;
String Result = ((Single) Value).ToString();

小数分隔符

PDF 阅读器(如 Adobe Acrobat)期望实数使用句点作为小数分隔符。世界上的一些地区使用其他小数分隔符,如逗号。自 PDF 文件写入器库 1.1 版本以来,它将使用句点作为小数分隔符,而不管您计算机的区域设置如何。

语言支持、字体和字符集

PDF 文件写入器库支持您计算机上安装的大部分字体。唯一的例外是设备字体。支持的字体遵循 OpenType 字体规范。有关更多信息,请访问 Microsoft Typography - OpenType Specification。要绘制的文本存储在由 Unicode 字符组成的 string 中。该库接受任何字符(0 到 65536),但控制代码 0 到 31 和 128 到 159 除外。每个字符都转换为一个字形。字形按照字符串中的存储顺序从左到右绘制在页面上。大多数字体文件只支持所有可能的 Unicode 字符的一个子集。换句话说,您必须选择支持您的项目语言或您要显示的符号的字体。如果输入字符串包含不受支持的字形,PDF 阅读器将显示“未定义字形”。通常是一个小矩形。本文附加的测试程序有一个“字体系列”按钮。如果单击它,您可以看到计算机上所有可用的字体,并且在每种字体中可以看到所有可用的字符。如果您的项目语言是从左到右的语言,并且每个字符都转换为一个字形,并且该字形在字体中定义,则结果应该符合您的预期。如果结果不符合您的预期,这里有一些补充说明:

Unicode 控制字符。Unicode 控制字符用于控制文本的解释或显示,但这些字符本身没有视觉或空间表示。PDF 文件写入器不识别这些字符。该库假定每个字符都是显示字符。它们将被显示为未定义字符。

从右到左的语言。通常,文本字符串中的字符顺序是人阅读它们的顺序。由于该库是从左到右绘制的,因此文本将向后写入。PdfContents.ReverseString 方法可以反转字符顺序。如果文本仅由从右到左的字符组成,这将解决问题。如果文本混合了从右到左、从左到右、数字和一些字符(如括号 ()[]<>{}),则不会产生预期结果。另一个限制是 TextBox 类无法将从右到左的长文本拆分成行。

连字。在某些语言中,两个或多个字符的序列组合在一起显示一个字形。您的软件可以识别这些序列并将它们替换为适当的字形。

圆点圆圈。如果您查看“字形度量”屏幕的“字形”列,您会看到某些字形带有一个小圆点(例如,字符代码 2364 和 2367)。这些字符是字符序列的一部分。圆点圆圈不会显示。如果前进宽度为零且边界框位于 Y 轴的左侧,则此字形将正常绘制。它将显示在上一个字符的上方。如果前进宽度不为零,则此字形应显示在上一个字符之前。您的软件可以通过反转这两个字符来实现。

绘制图形

PDF 内容流中使用的图形运算符描述了要在栅格输出设备上复制的页面的外观。PdfContent 类定义了所有基本的图形方法。OtherExample.cs 和相关的 OtherExample.pdf 文件有许多绘制图形的示例。请查看此项目中附带的 PDF 示例文件,找到最符合您要求的示例,然后查看源代码以了解如何操作。

绘制矩形、圆角矩形、倒圆角矩形和椭圆的最佳方法是使用 PdfContents.DrawGraphics 方法。此方法使用 PdfDrawCtrl 类来设置所有参数。

带边框和背景色的矩形示例。

// draw graphics example
PdfRectangle Rect = new PdfRectangle(Left, Bottom, Left + Width, Bottom + Height);
PdfDrawCtrl RectCtrl = new PdfDrawCtrl();
RectCtrl.Paint = DrawPaint.BorderAndFill;
RectCtrl.BorderWidth = 0.02;
RectCtrl.BorderColor = Color.DarkBlue;
RectCtrl.BackgroundTexture = Color.Turquoise;
Contents.DrawGraphics(RectCtrl, Rect);

在椭圆区域内绘制图像的示例。

// define image resource
PdfImage Image = new PdfImage(Document);
Image.LoadImage("TestImage.jpg");

// adjust image size and preserve aspect ratio
PdfRectangle ImageArea = new PdfRectangle(Left, Bottom, Right, Top);
PdfRectangle NewArea = PdfImageSizePos.ImageArea(Image, ImageArea, ContentAlignment.MiddleCenter);

// clipping path
PdfDrawCtrl DrawCtrl = new PdfDrawCtrl();
DrawCtrl.Shape = DrawShape.Oval;
DrawCtrl.Paint = DrawPaint.Border;
DrawCtrl.BorderWidth = 0.04;
DrawCtrl.BorderColor = Color.DarkBlue;
DrawCtrl.BackgroundTexture = Image;

// draw image
Contents.DrawGraphics(DrawCtrl, NewArea);

绘制单行文本

要绘制单行文本(如标题),您需要一个字体资源,需要创建一个绘图控件对象,并需要调用 PdfContents.DrawText 方法。下面提供了一个简单的示例。OtherExample.cs 源代码中有许多示例。请参阅第 5 页。绘图控件类提供了许多选项来控制文本的显示。

 

// draw single line of text
// define font resource
PdfFont ArialNormal = PdfFont.CreatePdfFont(Document, "Arial", FontStyle.Regular);

// create draw text control
PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, FontSize);

// set text attributes as required
// see PdfDrawTextCtrl.cs source code

// draw the text
Contents.DrawText(TextCtrl, PosX, PosY, "Arial normal ABCD abcd 1234");

绘制文本框

绘制长文本字符串使用 PdfTextBox 类。

  • 创建一个文本框对象并定义框的宽度。
  • 添加文本片段。可以执行一次或多次。对于每个文本片段,您可以使用相同的 PdfDrawTextCtrl 或不同的。您可以拥有具有不同颜色、字体和大小的文本。
  • 在一页或多页上绘制文本框。

下面是一个将在多页上打印的文本框示例。

// Create empty document
// Arguments: page width: 8.5", page height: 11", Unit of measure: inches
// Return value: PdfDocument main class
PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, FileName);

// Add new page
PdfPage Page = new PdfPage(Document);

// Add contents to page
PdfContents Contents = new PdfContents(Page);

// define text box with width of 6.5"
PdfTextBox Box = new TextBox(6.5);

// define font
PdfFont ArialNormal = new PdfFont(Document, "Arial", FontStyle.Regular);

// create draw text control
PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, FontSize);

// add very long text
Box.AddText(TextCtrl, TextBlock);

// draw as many pages as needed
double PosX = 1.0;
double PosY;
int LineNo = 0;
for(;;)
    {
    PosY = 10;
    LineNo = Contents.DrawText(PosX, ref PosY, 1.0, LineNo, Box);
    if(LineNo >= Box.LineCount) break;
    Page = new PdfPage(Document);
    Contents = new PdfContents(Page);
    }
// on loop's exit PosY is the next position on the page

// create pdf file
Document.CreateFile();

图像支持

在 PDF 文档中显示图像由 PdfImage 类处理。图像大小和纵横比的控制由 PdfImageSizePos 完成。实际绘制由 PdfContents.DrawGraphics 方法完成。此方法接受两个参数:PdfDrawCtrlPdfRectanglePdfImage 类是 PDF 资源。图像来源可以是

  • 图像文件
  • .NET Image 派生类,如 Bitmap
  • 像素的布尔数组,黑白相间
  • 由 QREncoder 类表示的 QRCode 条形码
  • 由 Pdf417Encoder 类表示的 PDF 417 条形码
  • PdfPrintDocument 在内部使用 PdfImage 来捕获打印页面

图像以以下格式之一保存到 PDF 文件中

  • Jpeg 格式(有损压缩)
  • 索引位图(无损压缩)
  • 灰度位图(无损压缩)
  • 黑白位图(无损压缩)

彩色图片应保存为 Jpeg 格式。要控制图像大小,您可以降低分辨率或更改图像质量。彩色图片可以保存为灰度。数据大小减少三分之一,但您会丢失颜色。如果图像是程序生成的,并且颜色数量少于 256 种,则该图像可以保存为索引位图。每种颜色用一个字节(或更少)表示,而不是 3 个字节。这可能导致文件大小显著减小。如果图像是黑白的(如 PdfPrintDocument 中的文本图像),则图像可以保存为 BWImage。在 PrintExample.pdf 的情况下,Jpeg 文件为 1795KB,而黑白版本为 66KB。

将图像添加到您的 PDF 文件

创建一个空的 PdfImage 类。

PdfImage MyImage = new PdfImage(Document);

根据需要设置可选参数。所有参数都有默认值。可选参数必须在加载图像之前设置。

设置内部图像格式。Jpeg、IndexedImage、GrayImage、BWImage。默认为 Jpeg。

MyImage.SaveAs = SaveImageAs.Jpeg;

CropRectangle 是要裁剪的图像区域。默认为无裁剪,绘制整个图像。原点位于左上角,Y 轴向下。尺寸以像素为单位。CropRectangle 必须包含在图像内。

MyImage.CropRec = new Rectangle(x, y, width, height);

CropPercentRectangle 是要裁剪的图像区域。默认为无裁剪(空矩形)。原点位于左上角,Y 轴向下。尺寸以图像百分比表示。CropRectangle 必须包含在图像内。

MyImage.CropPercent = new RectangleF(x, y, width, height);

ImageQuality 是一个 0 到 100 范围内的整数。表示从差到最好的图像质量。默认值 (-1) 是以 Bitmap 默认质量保存图像。供您参考,Bitmap 类的默认图像质量为 75。较低的图像质量意味着 PDF 文件更小。

MyImage.ImageQuality = PdfImage.DefaultQuality;

ImageResolution 设置图像分辨率,前提是它小于源图像的分辨率。默认值 0,保留原始图像分辨率。分辨率以每英寸像素为单位。降低分辨率意味着 PDF 文件更小。

MyImage.Resolution = 0;

灰度转换到黑白的截止值。范围是 1 到 99。默认值为 50。如果灰度低于截止值,结果为黑色。如果灰度高于截止值,结果为白色。

MyImage.GrayToBWCutoff = 50;

反转黑白。默认值为 false。在灰度和 BW 图像中,颜色会反转。

MyImage.ReverseBW = false;

附加到图层控件。图像的可见性将由查看器应用程序控制。

MyImage.LayerControl = PdfLayer;

将图像加载到 PdfImage 对象中。注意:加载方法会将图像保存到 PDF 输出文件中。完成此步骤后,图像将无法更改。

使用五种方法之一来加载图像。图像源可以是文件、Bitmap、BW 布尔数组、QRCode 或 PDF417 条形码。

MyImage.LoadImage(image_source);

将图像绘制到 PDF 文档中。图像将被拉伸以填充矩形区域。

PdfRectangle ImageRect = PdfRectangle(PosX, PosY, Width, Height);
Contents.DrawImage(MyImage, ImageRect);

第二个选择是通过指定宽度而不指定高度来绘制图像。高度将计算以保持正确的纵横比。

Contents.DrawImage(MyImage, PosX, PosY, Width);

如果您希望图像保持正确的纵横比,请使用 PdfImageSizePos.ImageSize 来计算宽度和高度。如果宽度和高度的比例与图像不同,图像将在一个方向上看起来被拉伸。请参阅 OtherExample 2e。

SizeD PdfImageSizePos.ImageSize(MyImage, DrawingArea);
// Or
SizeD PdfImageSizePos.ImageSize(MyImage, DrawingArea, ContentAlignment.MiddleCenter);

条形码支持

下面的代码说明了如何在 PDF 文档中包含 EAN13 条形码。

// create barcode object
PdfBarcodeEAN13 Barcode1 = new PdfBarcodeEAN13("1234567890128");

// create draw barcode control object
PdfDrawBarcodeCtrl BarcodeCtrl = new PdfDrawBarcodeCtrl();
BarcodeCtrl.NarrowBarWidth = 0.012;
BarcodeCtrl.Height = 0.75;

// create draw text control for the text below the barcode
BarcodeCtrl.TextCtrl = new PdfDrawTextCtrl(ArialNormal, 8.0);

// draw the barcode
Contents.DrawBarcode(BarcodeCtrl, PosX, PosY, Barcode1);

PDF 文件写入器库包含一个基类 Barcode。对于每种支持的条形码,都需要一个派生类。该类库包含四个派生类:Barcode128Barcode39BarcodeInterleaved2of5BarcodeEAN13BarcodeEAN13 在输入字符串为 13 位数时生成 EAN-13 条形码,在输入字符串为 12 位数时生成 UPC-A。前导零为 13 位数字的输入字符串被视为 UPC-A。

DrawBarcode 方法有几个重载。您指定条形码左下角的坐标、窄条的宽度、条形码的高度以及派生的条形码类。有可选参数:对齐方式(左、中、右)、颜色和显示文本的字体。条形码周围的空白区域由您负责。可选文本显示在条形码下方。如果您选择黑色以外的颜色,应确保与背景形成显著对比。用法示例在 绘制条形码ArticleExample.csOtherExample.cs 中给出。

如果您想为其他条形码创建派生类,请使用这三个包含类的源代码作为示例。

QR 码支持

PDF 文件写入器库提供 QR 码支持。它基于文章 “用 C# 编写的 QR 码编码器和解码器类库”。该程序支持三种字符集:数字、字母数字和八位字节。该程序不支持 Kanji 字符。该程序将扫描数据字符串输入并选择最有效的字符集。如果您的数据可以分成仅包含数字或仅包含字母数字字符的段,您可以创建一个包含数据字符串数组的 QR 码对象。

将 QRCode 添加到您的 PDF 文档必须遵循以下步骤。

  • 创建 QREncoder 对象。
  • 设置编码选项。所有编码选项都有默认值。
  • 编码数据字符串或数据字节数组。
  • 创建 PdfImage
  • 使用 PdfContent.DrawImage 绘制条形码图像

QR 码示例

// create QRCode barcode
PdfQREncoder QREncoder = new PdfQREncoder();

// set error correction code
QREncoder.ErrorCorrection = ErrorCorrection.M;

// set module size in pixels
QREncoder.ModuleSize = 1;

// set quiet zone in pixels
QREncoder.QuietZone = 4;

// encode your text or byte array
QREncoder.Encode(YourText);

// convert QRCode to black and white image
PdfImage BarcodeImage = new PdfImage(Document);
BarcodeImage.LoadImage(QREncoder);

// draw image (height is the same as width for QRCode)
Contents.DrawImage(BarcodeImage, OrigX, OrigY, Width);

PDF417 条形码

PDF417 条形码支持软件基于文章 “PDF417 条形码编码器类库和演示应用程序”。PDF417 条形码的文档和规范可以在以下网站找到。Wikipedia 提供了对 PDF417 的良好介绍。点击此处访问该页面。 PDF417 标准可以从 ISO 组织购买,在此网站上。早期版本的规范可以从此网站免费下载。如果您想完全理解编码选项,我强烈建议您下载该文档。

PDF417 条形码将字节数组编码为黑白条纹图像。编码 Unicode 文本需要将 Unicode 字符转换为字节。解码器必须执行反向过程才能恢复文本。字节被转换为代码字。此转换过程将字节压缩成代码字。编码器添加纠错代码字以进行错误检测和恢复。一旦已知数据代码字和纠错代码字的总数,编码器就会将代码字分成数据行和数据列。最后一步是创建黑白图像。

将 PDF417 条形码添加到您的 PDF 文档必须遵循以下步骤。

  • 创建 Pdf417Encoder 对象。
  • 设置编码选项。所有编码选项都有默认值。
  • 编码数据字符串或数据字节数组。
  • 检查图像宽度和高度或数据列数和数据行数,以确保图像尺寸适合您的应用程序。如果不合适,请调整布局。
  • 创建 PdfImage
  • 使用 PdfContent.DrawImage 绘制条形码图像

PDF417 条形码绘制示例

public void DrawPdf417Barcode()
{
string ArticleLink = 
    "https://codeproject.org.cn/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version";

// create PDF417 barcode
Pdf417Encoder Pdf417 = new Pdf417Encoder();
Pdf417.DefaultDataColumns = 3;
Pdf417.Encode(ArticleLink);
Pdf417.WidthToHeightRatio(2.5);

// convert Pdf417 to black and white image
PdfImage BarcodeImage = new PdfImage(Document);
BarcodeImage.LoadImage(Pdf417);

// draw image
Contents.DrawImage(BarcodeImage, 1.1, 5.2, 2.5);
return;
}

PDF417 条形码对象

创建 PDF417 条形码对象。此对象可以重复使用以生成多个条形码。

// create PDF417 barcode
Pdf417Encoder Pdf417 = new Pdf417Encoder();

设置可选参数以控制编码过程。

编码控制

PDF417 编码器将输入字节编码为代码字。有三种代码字类型:字节、文本和数字。程序有一个算法来将数据输入分成这三种类型以压缩数据。默认是自动(Auto)。但是,您可以将编码限制为仅字节或仅文本和字节。

Pdf417.EncodingControl = Pdf417EncodingControl.Auto;
// or
Pdf417.EncodingControl = Pdf417EncodingControl.ByteOnly;
// or
Pdf417.EncodingControl = Pdf417EncodingControl.TextAndByte;

纠错级别

PDF417 添加纠错代码字来检测和纠正错误。更多的纠错代码字可以提高条形码的可靠性。但是,它会使条形码变大。纠错级别允许您控制条形码的质量。ErrorCorrectionLevel 枚举有两种类型的值。固定级别从 0 到 8。以及基于数据代码字数量的推荐级别。默认值为 ErrorCorrectionLevel.AutoNormal。有关更多详细信息,请参阅 PDF417 规范中的表 6 和表 7。

Pdf417.ErrorCorrection = ErrorCorrectionLevel.Level_0; // up to Level_8
// or
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoNormal;
// or
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoLow; // one less than normal
// or
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoMedium; // one more than normal
// or
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoHigh; // two more than normal

窄条宽度

条形码窄条的像素宽度。默认为 2。如果更改此值,程序将确保 RowHeight 至少是该值的 3 倍。并且 QuietZone 至少是该值的 2 倍。

Pdf417.NarrowBarWidth = value;

行高

一行的高度(以像素为单位)。此值必须大于或等于 NarrowBarWidth 值的 3 倍。默认值为 6。

Pdf417.RowHeight = value;

空白区域

条形码周围空白区域的宽度。空白区域是白色的。此值必须大于或等于 NarrowBarWidth 值的 2 倍。默认值为 4。

Pdf417.QuietZone = value;

默认数据列

默认数据列值。该值必须在 1 到 30 之间。默认为 3。输入数据编码后,软件将数据列数设置为默认数据列数,并计算数据行数。如果数据行数超过允许的最大值(90),软件会将行数设置为最大允许值并重新计算数据列数。如果结果大于允许的最大列数,则会抛出异常。

Pdf417.DefaultDataColumns = value;

全局标签 ID 字符集

将全局标签 ID 字符集设置为 ISO 8859 标准。n 可以是 1 到 9 或 13 或 15。如果字符串为 null,则使用默认的 ISO-8859-1。语言支持在此定义:在此定义。

Pdf417.GlobalLabelIDCharacterSet = "ISO-8859-n";

全局标签 ID 用户定义

设置全局标签 ID 用户定义值。默认值为空。我没有找到任何解释该值用法的参考。用户定义值必须在 810900 和 811799 之间。

Pdf417.GlobalLabelIDUserDefined = UserDefinedValue;

全局标签 ID 通用目的

设置全局标签 ID 通用目的值。默认值为空。我没有找到任何解释该值用法的参考。用户定义值必须在 900 和 810899 之间。

Pdf417.GlobalLabelIDGeneralPurpose = UserDefinedValue;

编码数据

有两种编码方法。一种接受文本字符串作为输入,另一种接受字节数组作为输入。

Pdf417.Encode(string StringData);
// or
Pdf417.Encode(byte[] BinaryData);

条形码是为二进制数据设计的。因此,第一种方法必须将字符串从 16 位字符编码为字节数组。具有字符串输入的 encode 方法具有以下转换逻辑。Global Label ID Character Set 属性控制转换。它分两步进行。第一步是字符串到 UTF8,第二步是 UTF8 到 ISO-8859-n。如果要编码希伯来语,应将字符集设置为 ISO-8859-8。

public void Encode(string StringData)
{
// convert string to UTF8 byte array
byte[] UtfBytes = Encoding.UTF8.GetBytes(StringData);

// convert UTF8 byte array to ISO-8859-n byte array
Encoding ISO = Encoding.GetEncoding(_GlobalLabelIDCharacterSet ?? "ISO-8859-1");
byte[] IsoBytes = Encoding.Convert(Encoding.UTF8, ISO, UtfBytes);

// call the encode binary data method
Encode(IsoBytes);
Return;
}

最终条形码布局

数据编码后,您可以检查条形码的布局,方法是检查以下值:ImageWidthImageHeightDataColumnsDataRows。如果要重新调整条形码的宽度和高度,可以使用以下方法之一。此外,您可以重新调整可选参数:NarrowBarWidthRowHeightQuietZone 的值。

宽度与高度比

此方法将计算数据行数和数据列数以实现期望的宽度与高度比。该比例包括空白区域。检查返回值以确定是否成功。

Bool Pdf417.WidthToHeightRatio(double Ratio);

设置数据列

此方法将根据所需的数据列数计算数据行数。检查返回值以确定是否成功。

Bool Pdf417.SetDataColumns(int Columns);

设置数据行

此方法将根据所需的数据行数计算数据列数。检查返回值以确定是否成功。

Bool Pdf417.SetDataRows(int Rows);

创建 PDF 文档图像资源

在此步骤中,我们从 PDF417 条形码创建 PDF 文档图像资源。

PdfImage BarcodeImage = new PdfImage(Document, Pdf417);

绘制条形码

最后一步是将条形码添加到 PDF 文档页面内容的末尾。

// PosX and PosY are the page coordinates in user units.
// Width is the width of the barcode in user units.
// The height of the barcode is calculated to preserve aspect ratio.
// Height = Width * BarcodeImage.ImageHeight / BarcodeImage.ImageWidth
Contents.DrawImage(BarcodeImage, PosX, PosY, Width);

Web 链接支持

PDF 文件写入器库提供 Web 链接支持。此功能是 PDF 参考手册第 8 章交互式功能中描述的 PDF 交互式功能之一。它是注释和操作的组合。注释将 Web 链接与页面上的一个区域相关联。当用户单击该区域时,PDF 阅读器将激活默认的 Web 浏览器,导航到所需的网页。

注释区域是一个矩形区域,由相对于页面左下角的绝对坐标定义。首先,您创建一个注释 Web 链接对象,该对象将链接 URL 绑定到页面。然后,您在页面上以绝对坐标定义注释矩形。

// create weblink annotation object
PdfAnnotWebLink WebLink = new PdfAnnotWebLink(Document, ArticleLink);
WebLink.AnnotRect = new PdfRectangle(Left, Bottom, Right, Top);

注释不是页面内容的一部分。为了让用户知道在页面上单击何处,您需要在页面上的相同区域显示适当的文本或图形。换句话说,您需要创建一个附加到特定页面的 PdfAnnotWebLink 对象并提供 Web 链接。创建 Web 链接时,软件将其与当前页面关联。同时,在该页面上显示图形对象,如图像或文本。由于 AddWebLink 需要相对于页面左下角的坐标,因此您的图形对象的坐标必须相同。换句话说,不要使用平移、缩放或旋转。如果这样做,您需要确保两个区域会重叠。

TextBox 中绘制 Web 链接是一个两步过程。首先,您使用 TextBox 类的 AddText 方法将文本和 Web 链接字符串添加到框中。Web 链接包含在 PdfDrawTextCtrl 参数中。其次,您使用 PdfContentsDrawText 方法将 TextBox 绘制到页面内容中。最后一个参数必须是当前页面。

将 Web 链接添加到 TextBox。文本将显示为下划线和蓝色。

// create text box
PdfTextBox Box = new PdfTextBox(BoxWidth);

将 Web 链接添加到 TextBox。文本属性由 DrawStyleFontColor 定义。

// add weblink to text segment
PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, 11);
TextCtrl.Annotation = new PdfAnnotWebLink(Document, ArticleLink);
Box.AddText(TextCtrl, ArticleDescription);

// draw box contents
// note: PosYTop is by reference.
// On exit from the method the PosYTop 
// will have the next Y position
Contents.DrawText(BoxPosX, ref BoxPosY, BoxBottomPosY, 0, 0, 0, TextBoxJustify.Left, Box);

有关编码示例,请参阅 ArticleExample.cs 和 OtherExample.cs 源代码。

PDF 表单支持

交互式表单,有时也称为 AcroForm,是一组用于与用户进行交互式信息收集的字段。PDF 文档可以包含任意数量的字段,这些字段出现在任何页面组合上,所有这些字段共同构成一个跨越整个文档的单一、全局的交互式表单。

文档中每个字段的交互式表单都定义为一个派生自 PdfWidgetField 的类。该库支持以下字段。

  • 按钮字段 PdfAcroButtonField
  • 复选框字段 PdfCheckBoxField
  • 组合框字段 PdfComboBoxField
  • 列表框字段 PdfListBoxField
  • 文本框字段 PdfTextBoxField
  • 单选按钮组和单选按钮字段 PdfRadioButtonGroup PdfRadioButton

所有字段共享一个父级 PdfAcroForm

每个字段都有一个唯一的名称。该名称由两部分组成:页码和该页面的唯一名称。“Page#/name”。页码(#)不是文档页码,而是具有字段的页面的顺序页码。名称是创建类时指定的字段名称。名称在页面上必须是唯一的。

用于文本字段和组合框编辑字段的字体必须使用 Unicode 范围或范围进行定义。该库保存每个字体和每个字形定义。该库无法知道用户将在文本字段中输入哪些字符。为了解决这个问题,必须定义一个或一组范围。对于英语,ASCII 范围就足够了。对于其他语言,您必须定义适当的范围。

// data entry font
PdfFont FieldTextFont = PdfFont.CreatePdfFont(Document, "Arial", FontStyle.Regular);
PdfDrawTextCtrl FieldTextCtrl = new PdfDrawTextCtrl(FieldTextFont, 12);

// set all ascii range is included
FieldTextFont.SetCharRangeActive(' ', '~');

有关更多信息,请参阅 FormExample.cs 源代码。

下面是一个绘制文本字段的方法。它摘自上面的表单示例。

// Add text field
private PdfAcroTextField AddTextField
    (
    double OrigX, // left origin
    double OrigY, // top origin
    out double Width, // returned overall width
    out double Height, // returned overall height
    string FieldDescription, // field description
    string FieldName, // field name
    string FieldValue, // field initial value
    int TextMaxLength // field maximum length
    )
{
// constants
const double VertGap = 0.12;
const double FrameToField = 0.04;

// adjust PosY to the bottom of field description
double PosY = OrigY;
PosY -= FixedTextCtrl.LineSpacing;

// field description
double DescriptionWidth = Contents.DrawText(FixedTextCtrl, OrigX + FieldMargin, PosY + FixedTextCtrl.TextDescent, FieldDescription);

// adjust top to the bottom of field frame
PosY -= FieldTextCtrl.LineSpacing + VertGap;

// field width
double FieldWidth = TextMaxLength * FieldTextCtrl.CharWidth('0');
double FieldHeight = FieldTextCtrl.LineSpacing;

// frame margin
double FrameMargin = DrawFrame.BorderWidth + FrameToField;

// frame rectangle
PdfRectangle FrameRect = new PdfRectangle(OrigX, PosY, OrigX + FieldWidth + 2 * FrameMargin, PosY + FieldHeight + 2 * FrameMargin);

// draw frame
Contents.DrawGraphics(DrawFrame, FrameRect);

// data entry field rectangle
PdfRectangle FieldRect = FrameRect.AddMargin(-FrameMargin);

// text field
PdfAcroTextField TextField = new PdfAcroTextField(AcroForm, FieldName);
TextField.AnnotRect = FieldRect;
TextField.TextCtrl = FieldTextCtrl;
TextField.TextMaxLength = TextMaxLength;
TextField.BackgroundColor = Color.FromArgb(240, 240, 255);
if(!string.IsNullOrWhiteSpace(FieldValue)) TextField.FieldValue = FieldValue;

// text field appearance
TextField.DrawTextField();

Width = Math.Max(FrameRect.Width, DescriptionWidth);
Height = OrigY - FrameRect.Bottom;

// return
return TextField;
}

单选按钮成组出现。一次只能激活一个按钮。每个组都有一个唯一的名称。所有具有相同组名的单选按钮都是该组的成员。PdfAcroRadioButtonGroup 类由库自动创建。您必须定义 PdfAcroRadioButton 类。请查看 FormExample 中的 AddRadioButtonGroup 方法。

书签支持

PDF 规范(第 8.2.2 节文档大纲)将书签描述如下:“PDF 文档可以选择在屏幕上显示文档大纲,允许用户在文档的不同部分之间进行交互式导航。大纲由一个树状结构的项目(有时称为书签)组成,它们作为视觉目录显示文档的结构。用户可以通过鼠标单击来交互式地打开和关闭各个项目。”

OtherExample.cs 源代码中有一个书签的示例。在一个位置有三个级别的层次结构。您可以在 OtherExample.pdf 文件中看到结果。

在您的应用程序中添加书签的第一步是

// set the program to display bookmarks
// and get the bookmark root object
PdfBookmark BookmarkRoot = Document.GetBookmarksRoot();

此步骤激活文档中的书签并返回根节点。

添加书签就像向 Windows 窗体添加控件一样。第一级书签被添加到根目录。后续级别被添加到现有书签。至少您必须定义一个标题、页面、页面上的垂直位置和一个打开条目标志。Page 是要转到的 PdfPage 对象。YPos 是相对于页面左下角的垂直位置。如果下级书签可见,则打开条目标志为 true;如果下级隐藏,则为 false。第一级默认始终可见。

// hierarchy example
PdfBookmark FirstLevel_1 = BookmarkRoot.AddBookmark("Chapter 1", Page, YPos, false);
PdfBookmark SecondLevel_11 = FirstLevel_1.AddBookmark("Section 1.1", Page, YPos, false);
PdfBookmark SecondLevel_12 = FirstLevel_1.AddBookmark("Section 1.2", Page, YPos, false);
PdfBookmark ThirdLevel_121 = SecondLevel_12.AddBookmark("Section 1.2.1", Page, YPos, false);
PdfBookmark ThirdLevel_122 = SecondLevel_12.AddBookmark("Section 1.2.2", Page, YPos, false);
PdfBookmark SecondLevel_13 = FirstLevel_1.AddBookmark("Section 1.3", Page, YPos, false);
PdfBookmark FirstLevel_2 = BookmarkRoot.AddBookmark("Chapter 2", Page, YPos, false);
PdfBookmark SecondLevel_21 = FirstLevel_2.AddBookmark("Section 2.1", Page, YPos, false);
PdfBookmark SecondLevel_22 = FirstLevel_2.AddBookmark("Section 2.2", Page, YPos, false);

AddBookmark() 方法有四种重载变体。

// create bookmark control object
PdfBookmarkCtrl BookmarkCtrl = new PdfBookmarkCtrl();
BookmarkCtrl.Color = Color.Red;
BookmarkCtrl.TextStyle = BookmarkTextStyle.Bold;

// add bookmark
PdfBookmark Bookmark = BookmarkRoot.AddBookmark(BookmarkCtrl, BookmarkText, Page, PosX, PosY);

PdfBookmark 类公开了另一个方法 GetChild。您可以通过调用 GetChild 并带有一个或多个整数参数来获取任何书签。每个参数是级别中子项的零基参数。例如,GetChild(2) 是第一级的第三个项目。GetChild(2, 3) 是第三个第一级项目(即,第一个第一级项目)的第四个第二级项目。

打印文档支持

打印文档支持允许您以与打印到打印机相同的方式打印报告并生成 PDF 文档。此方法生成 PDF 文件与使用 PdfContents 生成 PDF 文件之间的区别在于栅格图形与矢量图形的区别。打印文档支持为每页创建一个 JPEG 图像。PrintExample.cs 包含一个创建三页文档的示例。

通常,每页都是页面的完整图像。如果您的页面是信纸大小,分辨率为每英寸 300 像素,则每个像素为 3 字节,页面的位图将长达 25.245MB。PrintPdfDocument 有一个 CropRect 方法,可以显著减小位图的大小。假设使用一英寸边距,位图的活动大小将减少到 15.795 MB。这意味着减少了 37.4%。

// main program
// Create empty document
Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch);

// create PrintPdfDocument producing an image with 300 pixels per inch
PdfImageControl ImageControl = new PdfImageControl();
ImageControl.Resolution = 300.0;
PrintPdfDocument Print = new PrintPdfDocument(Document, ImageControl);

// PrintPage in the delegate method PrintPageEventHandler
// This method will print one page at a time to PrintDocument 
Print.PrintPage += PrintPage;

// set margins in user units (Left, top, right, bottom)
// note the margins order are per .net standard and not PDF standard
Print.SetMargins(1.0, 1.0, 1.0, 1.0);

// crop the page image result to reduce PDF file size
// the crop rectangle is per .net standard.
// The origin is top left.
Print.CropRect = new RectangleF(0.95F, 0.95F, 6.6F, 9.1F);

// initiate the printing process (calling the PrintPage method)
// after the document is printed, add each page as an image to PDF file.
Print.AddPagesToPdfDocument();

// dispose of the PrintDocument object
Print.Dispose();

// create the PDF file
Document.CreateFile(FileName);

PrintPage 方法示例

// Print each page of the document to PrintDocument class
// You can use standard PrintDocument.PrintPage(...) method.
// NOTE: The graphics origin is top left and Y axis is pointing down.
// In other words, this is not PdfContents printing.
public void PrintPage(object sender, PrintPageEventArgs e)
{
// graphics object short cut
Graphics G = e.Graphics;

// Set everything to high quality
G.SmoothingMode = SmoothingMode.HighQuality;
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
G.PixelOffsetMode = PixelOffsetMode.HighQuality;
G.CompositingQuality = CompositingQuality.HighQuality;

// print area within margins
Rectangle PrintArea = e.MarginBounds;

// draw rectangle around print area
G.DrawRectangle(Pens.DarkBlue, PrintArea);

// line height
int LineHeight = DefaultFont.Height + 8;
Rectangle TextRect = new Rectangle(PrintArea.X + 4, PrintArea.Y + 4, PrintArea.Width - 8, LineHeight);

// display page bounds
// DefaultFont is defined somewhere else
String text = String.Format("Page Bounds: Left {0}, Top {1}, Right {2}, Bottom {3}",
    e.PageBounds.Left, e.PageBounds.Top, e.PageBounds.Right, e.PageBounds.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;

// display print area
text = String.Format("Page Margins: Left {0}, Top {1}, Right {2}, Bottom {3}",
    PrintArea.Left, PrintArea.Top, PrintArea.Right, PrintArea.Bottom);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;

// print some lines
for(int LineNo = 1;;LineNo++)
    {
    text = String.Format("Page {0}, Line {1}", PageNo, LineNo);
    G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
    TextRect.Y += LineHeight;
    if(TextRect.Bottom > PrintArea.Bottom) break;
    }
        
// move on to next page
PageNo++;
e.HasMorePages = PageNo <= 3;
return;
}

数据表支持

数据表类允许您在 PDF 文档中显示数据表。PdfTable 是控制单个表显示的类。一个表由一个标题行和数据行组成。每行分为单元格。PdfTableCell 控制一个标题单元格或数据单元格的显示。如果使用了标题,它将在表格顶部显示。可选地,它将在每个附加页的顶部显示。要显示单元格中的数据,请将数据加载到 PdfTableCellValue 属性中。数据可以是文本字符串、基本数值、bool、Char、TextBox、图像、QR 码或条形码。无论数据如何,您都可以用文档链接、Web 链接、视频、音频或嵌入文件填充单元格。单击单元格区域内的任何位置都会导致 PDF 阅读器激活文档链接、Web 链接、视频、音频或嵌入文件。数据的显示由 PdfTableStyle 类控制。PdfTable 类包含默认单元格样式和默认标题样式。您可以使用 PdfTableCell 内的私有样式来覆盖默认样式。要显示表格,请创建一个 PdfTable 对象。接下来,初始化表格、标题单元格、数据单元格和样式对象。最后,设置一个循环并加载一行单元格值,然后绘制该行。此循环继续,直到所有数据都显示出来。下面是生成表格所需的步骤序列。

调用 DrawRow 方法时,软件会计算所需的行高。行高是最高单元格的高度。如果表格中有足够的空间,表格将被绘制。当底部可用空间不足时,将调用新页面,并在表格顶部显示可选标题和当前行。如果所需的行高很大,以至于无法完全放入空白表格中,则会引发异常。为了适应长的多行字符串或 TextBoxes,软件可以灵活地处理这些情况。多行字符串由 PdfTable 转换为 TextBoxPdfTableStyle 类有一个 TextBoxPageBreakLines 属性。如果此属性设置为零(默认值),则 TextBox 被视为其他数据值。TextBox 高度必须适合页面。如果 TextBoxPageBreakLines 设置为正整数,系统将计算单元格的高度为 TextBox 高度或由 TextBoxPageBreakLines 指定的前几行的总高度。系统将绘制该行,其中包含适合页面的行数。将创建新页面,并将剩余的行绘制出来。换句话说,长 TextBox 的第一块行将至少包含 TextBoxPageBreakLines 行。TableExample.cs 源包含一个长 TextBox 单元格的示例。

创建一个 PdfTable 对象。

// create table
PdfTable Table = new PdfTable(Page, Contents, DrawTextCtrl);

Page 是当前 PdfPage。Contents 是当前 PdfContents。DrawTextCtrl 包含要使用的默认字体和字体大小。

在页面上定义表格区域。

// table's area on the page
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);

// first page starting vertical position
Table.RowTopPosition = StartingTopPosition;

四个参数是从左下角开始的表格的四个边,单位是用户单位。如果在第一页表格顶部的位置不在页面顶部,则将 RowTopPosition 设置为起始顶部位置。在后续页面上,表格将始终从顶部开始。如果未指定 TableArea,则库将其设置为默认页面大小减去一英寸的边距。

将表格宽度划分为列。

// divide table area width into columns
StockTable.SetColumnWidth(Width1, Width2, Width3, ...);

参数的数量是列的数量。表格宽度减去总边框线将按这些参数的比例进行划分。

一旦使用 SetColumnWidth 方法设置了列数,库就会创建两个 PdfTableCell 数组。一个数组用于标题单元格,一个数组用于数据单元格。

数据表的行和列可以用边框线分隔。边框线属性由 PdfTableBorderPdfTableBorderStyle 定义。有四条水平边框线:TopBorderBottomBorder、标题行和第一个数据行之间的 HeaderHorBorder 以及数据行之间 CellHorBorder。有两组垂直边框线:标题行内的垂直边框线的 HeaderVertBorder 数组,以及数据部分中列之间的垂直边框线的 CellVertBorder 数组。数组大小是列数加一。数组元素零是表格的左边框。数组元素 Columns 是表格的右边框。所有其他元素是分隔列的线条。这些线条中的每一条都可以单独定义。有方法可以一次性定义所有边框线,或单独定义每条边框线。

定义所有边框线的方法

// clear all border lines
Table.Borders.ClearAllBorders();

// set all border lines to default values (no need to call)
// All frame lines are one point (1/72") wide
// All grid lines are 0.2 of one point wide
// All borders are black
Table.Borders.SetDefaultBorders();

// set all borders to same width and black color
Table.Borders.SetAllBorders(double Width);

// set all borders to same width and a specified color
Table.Borders.SetAllBorders(double Width, Color LineColor);

// set all borders to one width and all grid lines to another width all lines are black
Table.Borders.SetAllBorders(double FrameWidth, double GridWidth);

// set all borders to one width and color and all grid lines to another width and color
Table.Borders.SetAllBorders(double FrameWidth, Color FrameColor, double GridWidth, Color GridColor);

// set all frame borders to same width and black color and clear all grid lines
Table.Borders.SetFrame(double Width);

// set all frame borders to same width and a specified color and clear all grid lines
Table.Borders.SetFrame(double Width, Color LineColor);

可以清除或设置每条水平边框线。示例是顶部边框线。

// clear border
Table.Borders.ClearTopBorder();

// set border with default color set to black
// Zero width means one pixel of the output device.
Table.Borders.SetTopBorder(double LineWidth);

// set border
Table.Borders.SetTopBorder(double LineWidth, Color LineColor);

可以清除或设置每条垂直边框线。示例是单元格的垂直边框线。

// clear border
Table.Borders.ClearCellVertBorder(int Index);

// set border with default color set to black
Table.Borders.SetCellVertBorder(int Index, double LineWidth);

// set border
Table.Borders.SetCellVertBorder(int Index, double LineWidth, Color LineColor);

设置其他可选的表格属性。下面示例中的值是默认值。

// header on each page
HeaderOnEachPage = true;

// minimum row height
MinRowHeight = 0.0;

表格信息是逐行处理的。每行由单元格组成。每列一个单元格。单元格信息的显示由 PdfTableStyle 类控制。大约有 20 个样式属性。其中一些样式特定于要显示的信息类型。这是一个例子。

// make some changes to default header style
Table.DefaultHeaderStyle.Alignment = ContentAlignment.BottomRight;

// create private style for header first column
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft;

// load header value
Table.Header[0].Value = "Date";

// make some changes to default cell style
Table.DefaultCellStyle.Alignment = ContentAlignment.MiddleRight;
Table.DefaultCellStyle.Format = "#,##0.00";

// create private style for date column
Table.Cell[0].Style = StockTable.CellStyle;
Table.Cell[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Cell[0].Style.Format = null;

初始化完成后,就可以显示数据了。下面的示例来自 TableExample.cs。这是一个股票价格表。有 6 列。

// open stock daily price
StreamReader Reader = new StreamReader("SP500.csv");

// ignore header
Reader.ReadLine();

// read all daily prices
for(;;)
    {
    String TextLine = Reader.ReadLine();
    if(TextLine == null) break;

    String[] Fld = TextLine.Split(new Char[] {','});

    Table.Cell[ColDate].Value = Fld[ColDate];
    Table.Cell[ColOpen].Value = double.Parse(Fld[ColOpen], NFI.PeriodDecSep);
    Table.Cell[ColHigh].Value = double.Parse(Fld[ColHigh], NFI.PeriodDecSep);
    Table.Cell[ColLow].Value = double.Parse(Fld[ColLow], NFI.PeriodDecSep);
    Table.Cell[ColClose].Value = double.Parse(Fld[ColClose], NFI.PeriodDecSep);
    Table.Cell[ColVolume].Value = int.Parse(Fld[ColVolume]);
    StockTable.DrawRow();
    }
StockTable.Close();

DrawRow(NewPage) 方法有一个可选参数 bool NewPage = false。默认值为 false。如果您希望下一行打印在新页面的顶部,请将参数设置为 true

交互式功能示例。

// set cell number 6 with web link
BookList.Cell[6].WebLink = WebLinkString;

// another way to set any annotation
// any of the annotation derived classes
BookList.Cell[6].Annotation = new PdfAnnotWebLink(Document, WebLinkString);

有关数据表的更多源代码示例,请查看 ArticleExample.csTableExample.cs

播放视频文件

PdfFileWriter 支持在 PDF 文档中嵌入视频文件。播放视频文件的完整示例在 OtherExample.cs 的第 7 页给出。添加视频文件需要使用三个类。首先,您需要将视频文件嵌入 PDF 文档中。

其次,您需要定义视频的播放方式。PdfDisplayMedia 类有多种方法来控制视频显示。请参阅类的源代码。例如:RepeatCountScaleMedia。如果您想在浮动窗口中播放视频,则必须使用 SetMediaWindow 方法。

第三,您需要定义 PDF 页面上的区域,用户必须单击该区域才能激活视频。如果您想在注释区域可见时激活视频,请使用 ActivateActionWhenPageIsVisible

// load the video into embedded file object
PdfEmbeddedFile Video = PdfEmbeddedFile.CreateEmbeddedFile(Document, "Omega.mp4");

// create display media annotation object
DisplayMedia = new PdfAnnotDisplayMedia(Document, Video);

// activate display controls
DisplayMedia.DisplayControls = true;

// display the video in floating window
DisplayMedia.MediaWindowType = MediaWindow.Floating;

// title bar text
DisplayMedia.FloatingWindowTitleText = "Floating Window Example";

// Text control
PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, 12);
TextCtrl.Justify = TextJustify.Center;
double LineSpacing = TextCtrl.LineSpacing;

// draw text on the page (first line)
double TextPosX = PosX + 0.5 * AreaWidth;
double TextPosY = PosY + 0.5 * AreaHeight + LineSpacing;
double TextWidth = Contents.DrawText(TextCtrl, TextPosX, TextPosY, "Click this text to play the video");

// draw text on the page (second line)
TextPosY -= LineSpacing;
Contents.DrawText(TextCtrl, TextPosX, TextPosY, "in a floating window");

// create annotation rectangle over the two lines of text
DisplayMedia.AnnotRect = new PdfRectangle(TextPosX - 0.5 * TextWidth, TextPosY - TextCtrl.TextDescent,
	TextPosX + 0.5 * TextWidth, TextPosY + TextCtrl.TextAscent + LineSpacing);

// activate the video when the page becomes visible (option)
// DisplayMedia.ActivateActionWhenPageIsVisible(true);

播放音频文件

PdfFileWriter 支持在 PDF 文档中嵌入音频文件。播放音频文件的完整示例在 OtherExample.cs 的第 7 页给出。嵌入音频文件与视频文件基本相同。唯一明显区别是没有任何内容显示。

// text control
PdfDrawTextCtrl RedTextCtrl = new PdfDrawTextCtrl(ArialNormal, 12);
RedTextCtrl.Justify = TextJustify.Center;
RedTextCtrl.TextColor = Color.Red;

// display text area to activate the sound
double TextPosX = PosX + 0.5 * AreaWidth;
double TextPosY = PosY + 0.7 * AreaHeight + RedTextCtrl.LineSpacing;
double TextWidth = Contents.DrawText(RedTextCtrl, TextPosX, TextPosY, "Click this text to play");

// second line of ringing sound
TextPosY -= RedTextCtrl.LineSpacing;
Contents.DrawText(RedTextCtrl, TextPosX, TextPosY, "Ringing sound");

// rectangle around the two lines of text
PdfRectangle TextRect = new PdfRectangle(TextPosX - 0.5 * TextWidth, TextPosY - RedTextCtrl.TextDescent,
	TextPosX + 0.5 * TextWidth, TextPosY + RedTextCtrl.LineSpacing + RedTextCtrl.TextAscent);

// create embedded media file
PdfEmbeddedFile RingSoundFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, "Ring01.wav");
PdfAnnotDisplayMedia RingSound = new PdfAnnotDisplayMedia(Document, RingSoundFile);
RingSound.MediaWindowType = MediaWindow.Hidden;
RingSound.AnnotRect = TextRect;

// activate ring sound when page is visible (option)
RingSound.ActivateWhenPageIsVisible();

附加数据文件

PdfFileWriter 支持在 PDF 文档中嵌入数据文件。嵌入文件的完整示例在 OtherExample.cs 的第 7 页给出。用户可以保存文件或显示文件。

// embedded file
// text control
PdfDrawTextCtrl TextCtrl = new PdfDrawTextCtrl(ArialNormal, 12);
TextCtrl.Justify = TextJustify.Center;

// load embedded file
PdfEmbeddedFile EmbeddedFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, "BookList.txt");

// create annotation object for file attachment
TextCtrl.Annotation = new PdfAnnotFileAttachment(Document, EmbeddedFile);

// display area for the user to click on
TextCtrl.TextColor = Color.DarkViolet;
Contents.DrawText(TextCtrl, PosX + 0.5 * AreaWidth, PosY + 0.4 * AreaHeight, "Right click to open or save the attached file,");

重新排序页面

PdfFileWriter 将新页面追加到页面列表的末尾。如果要将页面从当前位置移动到新位置,请使用以下方法。

// Source and destination index are zero based.
// Source must be 0 to PageCount - 1.
// Destination must be 0 to PageCount.
// If destination index is PageCount, the page will be the last page
// PageCount is a property of PdfDocument.
Document.MovePage(int SourceIndex, int DestinationIndex);

PDF 文档输出

PdfFileWriter 创建 PDF 文档。主类 PdfDocument 构造函数为您提供了保存文档的两种选择。第一种选择是将 PDF 文件保存到磁盘文件。在这种情况下,您为构造函数提供一个文件名。在文件创建结束时,您调用 PdfDocument.CreateFile。此方法将 PDF 写入文件并关闭文件。

// create main class
PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, FileName);

// terminate
Document.CreateFile();

第二种选择是流。您创建一个流,可以是内存流或文件流,并将该流作为参数传递给 PdfDocument 构造函数。CreateFile 方法执行后,您的流将包含 PDF 文档。根据您的应用程序的需要从流中提取文档。您必须在应用程序中关闭流。

// create memory stream
MemoryStream PdfStream = new MemoryStream();

// create main class
PdfDocument Document = new PdfDocument(PaperType.Letter, false, UnitOfMeasure.Inch, PdfStream);

// terminate
Document.CreateFile();

// save the memory stream to a file
FileStream FS = new FileStream(FileName, FileMode.Create);
PdfStream.WriteTo(FS);
PdfStream.Close();
FS.Close();

文档信息字典

PDF 文档信息字典由 PDF 阅读器在文档属性的“描述”选项卡中显示。信息包括标题、作者、主题、关键字、创建日期和时间、修改日期和时间、生成文件的应用程序、PDF 生产者。在应用程序中包含文档信息如下操作:

// Document information example
PdfInfo Info = new PdfInfo(Document);
Info.Title("Article Example");
Info.Author("Uzi Granot");
Info.Keywords("PDF, .NET, C#, Library, Document Creator");
Info.Subject("PDF File Writer II C# Class Library");

创建 PdfInfo 对象时,会在字典中添加四个附加字段。您可以在代码中覆盖所有这些字段。

// set creation and modify dates
DateTime LocalTime = DateTime.Now;
Info.CreationDate(LocalTime);
Info.ModDate(LocalTime);

// set creator and producer
Info.Creator("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber);
Info.Producer("PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber);

内存控制

在构建文档时,PDF 文件写入器会累积创建 PDF 文件所需的所有信息。信息保存在内存中,图像和嵌入文件除外。图像和嵌入文件在声明时会自动写入输出文件。对于非常大的文档,使用的内存会不断增长。该库提供方法(CommitToPdfFile)将内容信息写入输出文件并调用垃圾回收器以释放未使用内存。GC.Collect 方法需要一些时间来执行。如果执行时间是个问题,请每隔几页设置一次 GCCollect 参数。换句话说,CommitToPdfFile 必须对每一页都运行,但清理是每隔几页进行一次。一旦执行了提交,就无法再添加额外信息。PdfTable 在下一行无法适应当前页面底部时自动开始新页面。PdfTable 类有两个成员 CommitToPdfFileCommitGCCollectFreq 来控制表格构建过程中的内存使用。PdfChart 类从 .NET Chart 类生成图像。PdfContentsDrawChart 方法将执行提交。或者,您可以调用 PdfChartCommitToPdfFile 方法。

// PdfContents, PdfXObject and PdfTilingPattern
// Commit the contents to output file.
// Once committed, this PdfContents cannot be used.
// The argument is GCCollect
Contents.CommitToPdfFile(true);

透明度、不透明度、Alpha 颜色分量和混合

默认情况下,PDF 图像模型将对象(形状、线条、文本和图像)不透明地绘制在页面上。每个新对象都会完全遮挡其下方的图像。PDF 有两种机制可以改变这种行为:不透明度和混合。图形状态字典为描边(笔)和非描边(画笔)操作设置了不透明度值。完全不透明的不透明度值为 1.0,完全透明的值为 0.0。不透明度值对应于颜色结构的 alpha 分量,其中 1.0 为 255 alpha,0.0 为 0 alpha。如果该不透明度值为 0.5,则绘制在页面上的新对象将是 50% 透明的。要设置不透明度,请调用 SetAlphaStroking 方法(用于线条)或 SetAlphaNonStroking 方法(用于形状)。混合是结合页面颜色和正在绘制的新项颜色的过程。要设置混合模式,请调用 PdfContentsSetBlendMode 方法。参数是 BlendMode 枚举。有关完整描述,请参阅 PDF 规范文档的第 7.2.4 节“混合模式”。有关示例,请参阅 OtherExample.cs 第 8 页。

文档链接和命名目标

文档链接允许 PDF 文档用户单击链接并跳转到文档的另一部分。添加文档链接分两部分完成。目标定义为一个位置标记。位置标记必须具有唯一的名称、范围(LocalDestNamedDest)以及文档位置(页面和位置)。NamedDest 范围可用于文档链接、命名目标或两者兼可。第二部分是链接位置。这两部分可以按任意顺序定义。它们通过名称绑定在一起。名称区分大小写。许多链接可以指向同一个位置标记。

命名目标是 PDF 文档中的目标。它们以与文档链接相同的方式使用位置标记定义。范围必须设置为 NamedDest。当 PDF 阅读器(如 Adobe Acrobat)打开 PDF 文档时,它可以打开该文档并在查看窗口中显示目标。

要嵌入位置标记,请调用 PdfPageAddLocationMarker 方法。注意:名称区分大小写。

// Add location marker to the document (PdfPage method)
public void AddLocationMarker
  (
  string LocMarkerName,   // unique destination name (case sensitive)
  LocMarkerScope Scope,   // eigther LocalDest or NamedDest
  DestFit FitArg,         // fit argument (see below)
  params double[] SideArg // 0, 1 or 4 side dimension argument (see below)
  )

要添加链接位置,请调用 PdfPage 的 AddLinkLocation 方法。

public PdfAnnotation AddLinkAction
  (
  string LocMarkerName,    // location marker name
  PdfRectangle AnnotRect   // rectangle area on the page to activate the jump
  )

有关命名目标的更多信息,请参阅 Adobe PDF 文件规范 “PDF 参考,第六版,Adobe 可移植文档格式版本 1.7,2006 年 11 月”。第 582 页的表 8.2。

  • DestFit.Fit(无参数):显示页面,其内容放大到足以将整个页面同时在水平和垂直方向上适应窗口。
  • DestFit.FitH(1 个参数 Top):显示页面,将垂直坐标 Top 定位在窗口的顶部边缘,并放大页面内容,直到整个页面宽度适应窗口。
  • DestFit.FitV(1 个参数 Left):显示页面,将水平坐标 Left 定位在窗口的左边缘,并放大页面内容,直到整个页面高度适应窗口。
  • DestFit.FitR(4 个参数 Left Bottom Right Top):显示页面,其内容放大到足以将由坐标 Left、Bottom、Right 和 Top 指定的矩形同时在水平和垂直方向上完全适应窗口。
  • DestFit.FitB(无参数):显示页面,其内容放大到足以将其边界框同时在水平和垂直方向上完全适应窗口。
  • DestFit.FitBH(1 个参数 Top):显示页面,将垂直坐标 Top 定位在窗口的顶部边缘,并放大页面内容,直到其整个边界框宽度适应窗口。
  • DestFit.FitBV(1 个参数 Left):显示页面,将水平坐标 Left 定位在窗口的左边缘,并放大页面内容,直到其整个边界框高度适应窗口。

PDF 阅读器的调用参数在 “Adobe 打开 PDF 文件的参数” 中定义。如果 PDF 在台式计算机上打开,则调用行必须是

"path\AcroRd32.exe" /A "nameddest=ChapterXX" "path\Document.pdf"

如果 PDF 文档由网页中的链接指向,则目标将附加到链接中

<a href="http://example.org/Document.pdf#ChapterXX">目标描述</a>

或:<a href="http://example.org/Document.pdf#namedsest=ChapterXX">目标描述</a>

加密支持

PDF 文件写入器库提供对 AES 128 和 Standard 128 (RC4) 加密的加密支持。有关更多信息,请参阅 PDF 参考第六版(版本 1.7)第 3.5 节加密。PDF 文件写入器支持两种类型的加密过滤器:AES-128 和 Standard 128。Standard 128 是 RC4 加密。它被认为不安全。新项目不要使用它。它不支持公钥安全来编码收件人列表。

要加密您的 PDF 文档,请调用 PdfDocument 类中定义的四个 SetEncryption 方法之一。

在不带参数的情况下设置加密。

PDF 文件写入器库将使用 AES-128 加密来加密 PDF 文档。PDF 阅读器将在不请求密码的情况下打开文档。权限标志设置为允许所有操作。

Document.SetEncryption();

用一个参数设置加密。

PDF 文件写入器库将使用 AES-128 加密来加密 PDF 文档。参数是权限。权限标志如下定义。您可以对多个权限执行 OR 操作。PDF 参考手册对权限有完整描述。PDF 阅读器将在不请求密码的情况下打开文档。

Document.SetEncryption(Permission Permissions);

用两个参数设置加密。

PDF 文件写入器库将使用 AES-128 加密来加密 PDF 文档。两个参数是用户密码和权限。PDF 阅读器将使用用户密码打开文档。权限将按照参数进行设置。

Document.SetEncryption(String UserPassword, Permission Permissions);

用四个参数设置加密。

PDF 文件写入器库将使用 EncryptionType.Aes128 加密或 EncryptionType.Standard128 加密来加密 PDF 文档。四个参数是用户密码、所有者密码、权限和加密类型。如果用户密码为 null,将使用默认密码。如果所有者密码为 null,软件将生成随机数密码。Standard128 加密被认为是不安全的。不应在新项目中使用。

PDF 阅读器(如 Acrobat)将接受用户密码或所有者密码。如果使用所有者密码打开文档,PDF 阅读器将以所有权限都设置为允许操作的方式打开它。

Document.SetEncryption(String UserPassword, String OwnerPassword,
    Permission Permissions, EncryptionType Type);

权限标志如下

// Full description is given in
// PDF Reference Version 1.7 Table 3.20
public enum Permission
    {
    None = 0,
    LowQalityPrint = 4, // bit 3
    ModifyContents = 8, // bit 4
    ExtractContents = 0x10, // bit 5
    Annotation = 0x20, // bit 6
    Interactive = 0x100, // bit 9
    Accessibility = 0x200, // bit 10
    AssembleDoc = 0x400, // bit 11
    Print = 0x804, // bit 12 + bit 3
    All = 0xf3c, // bits 3, 4, 5, 6, 9, 10, 11, 12
    }

便笺或文本注释。

PDF 参考文档在第 8.4 节第 621 页中定义了便笺或文本注释。“文本注释代表一个附加到 PDF 文档某点的‘便笺’。关闭时,注释显示为一个图标;打开时,它会显示一个弹出窗口,其中包含注释文本,字体和大小由查看器应用程序选择。文本注释不会随页面缩放和旋转;它们就像始终设置了 NoZoom 和 NoRotate 注释标志(参见第 608 页的表 8.16)。表 8.23 显示了此类型注释特有的注释字典条目。”

将便笺添加到您的文档非常简单。您只需添加一行代码。便笺被添加到 PdfPage 对象。它不是页面内容的一部分。便笺的位置是相对于页面左下角的绝对页面位置,测量到便笺图标的左上角。文本字符串是弹出窗口的内容。便笺参数是以下枚举项之一。

// sticky note text annotation
Page.AddStickyNote(PageAbsPosX, PageAbsPosY,
    "My first sticky note", StickyNoteIcon.Note);
// Sticky note icon
public enum StickyNoteIcon
    {
    // Comment (note: no icon)
    Comment,

    // Key
    Key,
   
    // Note (default)
    Note,
        
    // Help
    Help,
        
    // New paragraph
    NewParagraph,
        
    // Paragraph
    Paragraph,
        
    // Insert
    Insert,
    }

图层或可选内容。

PDF 规范文档(第 4.10 节)将可选内容定义为:“可选内容(PDF 1.5)是指 PDF 文档中可以由文档作者或消费者选择性查看或隐藏的内容部分。此功能对于 CAD 图纸、分层艺术品、地图和多语言文档等项目非常有用。”

Adobe Acrobat 查看器在屏幕左侧有导航面板。其中一个是图层面板。如果 PDF 文档使用图层,图层控件开关将显示在此面板中。用户可以显示或隐藏已附加到这些图层控件的项目。

将图层添加到您的 PDF 文档。完整示例在 LayersExample.cs 中给出。此外,OtherExample.cs 包含使用图层控制图像和注释的示例。

创建主图层控件对象。每个文档一个。

// create a layers control object and give it a name.
// only one object like that is allowed.
// The name will be displayed in the layer panel.
PdfLayers Layers = new PdfLayers(Document, "PDF layers group");

设置列表模式选项。默认是所有页面。

// List mode
Layers.ListMode = ListMode.AllPages; // default

// or
Layers.ListMode = ListMode.VisiblePages;

创建一个或多个图层对象。每个图层对应图层面板上的一个复选框。每个图层可以控制一个或多个显示项。

// create one or more layer objects
PdfLayer LayerName = new PdfLayer(Layers, "Layer name");

几个图层可以组合成单选按钮组。一个单选按钮组可以全部关闭,或者只有一个图层打开。

// Optionally combine three layers into
// one group of radio buttons
LayerName1.RadioButton = "Group1";
LayerName2.RadioButton = "Group1";

设置图层面板中图层的顺序。如果未使用 DisplayOrder 方法,程序将在同一主级别列出上面指定的所有图层。如果使用了 DisplayOrder 方法,则必须包含所有图层。

图层列表可以带有可选名称的子组。

// display order
Layers.DisplayOrder(LayerName1);
Layers.DisplayOrder(LayerName2);
Layers.DisplayOrder(LayerName3);
Layers.DisplayOrderStartGroup("Sub Group");
Layers.DisplayOrder(LayerName4);
Layers.DisplayOrder(LayerName5);
Layers.DisplayOrder(LayerName6);
Layers.DisplayOrderEndGroup();

在内容流中定义一个由图层控制的区域。

// contents stream start layer marker
Contents.LayerStart(LayerName1);

// your contents methods to be
// controlled by LayerName1

// end of LayerName1 area
Contents.LayerEnd();

直接控制图像或注释。图像可以在文档中的任何位置。

// image or annotation control
QREncoder QREncoder = new QREncoder();
QREncoder.ErrorCorrection = ErrorCorrection.M;
QREncoder.Encode("Some data");
PdfImage QRImage = new PdfImage(Document);
QRImage.LayerControl = LayerName1;
QRImage.LoadImage(QREncoder);

初始文档显示。

初始文档显示控制 PDF 查看器(Acrobat)显示文档时的外观。它控制屏幕的左侧面板。

例如,打开书签面板。

Document.InitialDocDisplay = InitialDocDisplay.UseBookmarks;
// initial document display enumeration
public enum InitialDocDisplay
{
// keep the left pane closed
UseNone,

// open the bookmarks pane
UseBookmarks,

// open the page thumbnails
UseThumbs,

// full screen mode
FullScreen,

// open layers
UseLayers,

// open attachments
UseAttachments,
}

XMP 元数据。

XMP 文件或字节数组嵌入在 PDF 对象中的元数据流中。XMP 必须编码为 UTF-8。PdfFileWriter 包含用户提供的输入文件或输入字节数组。用户必须确保 XMP 输入是有效的元文件。XMP 流未压缩或加密。这允许阅读器通过少量编程获取元数据信息。您应该在创建 PdfDocument 后不久,在加载任何图像之前包含 XMP 元数据。这样,元数据将位于文件开头,并且可以被简单的文本编辑器读取。

// adding metadata
new PdfMetadata(Document, FileName);

// or
new PdfMetadata(Document, ByteArray);

调试模式

测试/演示/调试程序 TestPdfFileWriter 程序是对您自己应用程序的模拟。当您按下“文章示例”按钮时,程序将执行 ArticleExample.cs 源文件中的代码。文章开头的图像显示了生成的 PDF 文件。通过这个例子,您应该对这个过程有很好的理解。其他示例按钮会生成各种 PDF 文档。总而言之,几乎该库的每一项功能都通过这些示例得到了演示。

如果勾选了 Debug 复选框,则会创建一个 PDF 文件,该文件可以用文本编辑器查看,但不能加载到 PDF 阅读器或查看器中。生成的文件未压缩,图像和字体文件被替换为文本占位符。Debug 复选框仅用于调试。

安装

PdfFileWriter 集成到您的应用程序需要以下步骤。将附加的 PdfFileWriter.dll 文件安装在您的开发区域。启动 Visual C# 程序并打开您的应用程序。转到解决方案资源管理器,右键单击“引用”并选择“添加引用”。选择“浏览”选项卡,然后导航到 PdfFileWriter.dll 的位置。发布应用程序时,必须包含 PdfFileWriter.dll

如果您想访问 PdfFileWriter 项目的源代码,请在您的开发区域安装 PdfFileWriter 项目。PdfFileWriter.dll 将位于 PdfFileWriter\bin\Release 目录中。

将以下语句添加到使用此库的所有源模块中。

using PdfFileWriter;

升级

PdfFileWriter 1.28.0 及更早版本的项目与 PdfFileWriter 2.0.0 不兼容,但它们足够接近,可以通过一些努力进行转换。以下列表显示了大部分主要更改。

  • 所有类名都以 Pdf 开头。
  • 所有与绘制文本字符串相关的函数都由 PdfDrawTextCtrl 控制。
  • 所有与绘制条形码相关的函数都由 PdfDrawBarcodeCtrl 控制。
  • 所有与绘制矩形、圆角矩形、倒圆角矩形和椭圆相关的函数都由 PdfDrawCtrl 控制。
  • 图像资源的创建从多个构造函数更改为一个构造函数并设置字段和方法。
  • 所有注释派生类都已重写。

参考文献

历史

  • 2013/04/01:版本 1.0 原始版本。
  • 2013/04/09:版本 1.1 支持小数分隔符不是句点以外的国家。
  • 2013/07/21:版本 1.2 原始版本仅支持 JPEG 文件格式的图像资源。版本 1.2 支持 Bitmap 类可接受的所有图像文件。请参阅 ImageFormat 类。程序已测试:Bmp、Gif、Icon、Jpeg、Png 和 Tiff。请参阅上面第 2.3 节和第 3.8 节。
  • 2014/02/07:版本 1.3 修复了 PdfContents.DrawBezierNoP2(PointD P1, PointD P3) 中的错误。
  • 2014/03/01:版本 1.4 改进了字符替换支持。改进了图像包含支持。与 PdfXObject 相关的一些修复。
  • 2014/05/05:版本 1.5 无需字体即可支持条形码。包含四种条形码:Code-128、Code-39、UPC-A 和 EAN-13。参见第 2.5 节和第 3.7 节。
  • 2014/07/09:版本 1.6 (1) CreateFile 方法在文件创建后将 PdfDocument 重置为初始状态。(2) PdfFont 对象正确释放非托管代码资源。
  • 2014/08/25:版本 1.7 支持文档加密、Web 链接和 QR 码。
  • 2014/09/12:版本 1.8 支持书签。
  • 2014/10/06: Version 1.9 支持图表、PrintDocument 和图像 Metafile。
  • 2014/10/12: Version 1.9.1 ChartExample 的修复。解析小数点分隔符不是句点的区域中的数值字段。
  • 2014/12/02: Version 1.10.0 支持数据表。添加源代码文档。增加每个文档的最大图像数量。
  • 2015/01/12: Version 1.11.0 支持视频、音频和附件文件。添加对 Interleave 2 of 5 条形码的支持。
  • 2015/04/13: Version 1.12.0 支持重新排序页面和增强数据表边框线支持。
  • 2015/05/05: Version 1.13.0 PDF 文档输出到流。PDF 表插入分页符。图像质量增强。支持 Standard-128 (RC4) 加密。
  • 2015/06/08: Version 1.14.0 支持 PDF 表内的长文本块或 TextBox。
  • 2015/06/09: Version 1.14.1 PdfTableStyle 类的 Copy 方法进行了一行更改。
  • 2015/06/17: Version 1.15.0 文档信息字典。PdfImage 重写。额外的图像保存选项。
  • 2015/06/18: Version 1.15.1 从解决方案资源管理器中删除未使用的源。
  • 2015/07/27: Version 1.16.0 Unicode 支持。Commit page 方法。
  • 2015/08/07: Version 1.16.1 修复了将微小(<0.0001)的实数转换为字符串的问题。
  • 2015/09/01: Version 1.16.2 修复了未定义字符的问题。选定的字体不支持使用的字符。
  • 2015/09/22: Version 1.16.3 PdfTable 构造函数使用当前页面大小来计算默认表区域矩形。当 PdfTable 开始新页面时,页面类型和方向取自前一页。
  • 2015/09/30: Version 1.16.4 一致使用 IDisposable 接口来释放非托管资源。
  • 2016/01/26: Version 1.17.0 WPF 图形、透明度、颜色混合、椭圆弧和二次贝塞尔曲线。
  • 2016/02/29: Version 1.17.1 当第一列标题是 TextBox 时,PdfTable 将正确显示标题。
  • 2016/03/22: Version 1.17.2 PdfInfo PDF 文档属性将正确显示。
  • 2016/04/14: Version 1.17.3 修复了小数点分隔符非句点(逗号)区域中非整数字体大小的问题。
  • 2016/05/24: Version 1.18.0 命名目标和 PdfFont 资源创建。
  • 2016/06/02: Version 1.18.1 重新应用 1.17.3 修复。
  • 2016/06/13: Version 1.19.0 文档链接。命名目标更改。对 TextBox 和 PdfTable 的交互式功能支持。
  • 2016/07/27: Version 1.19.1 修复:AddLocationMarker 针对小数点分隔符非句点的区域进行修复。
  • 2017/08/31: Version 1.19.2 修复:调试工作目录未保存为项目的一部分。
  • 2018/06/26: Version 1.19.3 修复 PdfFontFile.BuildLocaTable 方法。长格式缓冲区指针初始化。修复 PdfTableCell 添加 DBNull 类型的值。
  • 2018/07/15: Version 1.20.0 通过添加每个模块的像素数来修改 QR Code 支持。
  • 2019/02/06: Version 1.21.0 支持 PDF417 条形码。
  • 2019/02/13: Version 1.21.1 修复 PDF417 条形码的安静区。
  • 2019/02/18: Version 1.22.0 支持便签。
  • 2019/05/26: Version 1.23.0 支持图层以及对 QRCode 和 Pdf417 条形码的更改。
  • 2019/06/06: Version 1.24.0 支持图层对图像和注释的控制。
  • 2019/06/20: Version 1.24.1 支持以米为单位。
  • 2019/07/15: Version 1.25.0 支持字体集合(主要是 CJK 字体)和非 ASCII 字体名称。
  • 2019/07/28: Version 1.26.0 支持 XMP 元数据和 QR Code ECI 分配号。
  • 2020/09/09: Version 1.27.0 修复与 PDF417 条形码相关的内存不足问题。该问题仅在不寻常情况下发生。
  • 2021/03/31: Version 1.28.0 内部文件结构升级,包含对象流和交叉引用流。
  •  
  • 2022/02/01: Version 2.0.0 PDF 文件编写器 II 版本。
© . All rights reserved.