一、简介
PDF File Writer C# 类库PdfFileWriter
允许您直接从 .net 应用程序创建 PDF 文件。该库使您免受 PDF 文件结构的详细信息的影响。要使用该库,您需要添加对附加PdfFileWriter.dll
类库文件的引用,using PdfFileWriter
在每个使用该库的源文件中添加一条语句,并将 包含在PdfFileWriter.dll
您的发行版中。更多详细信息,请参阅4. 安装。该代码是使用 .NET Framework 4.6.2 和 Visual Studio 2019 开发的。
1.28.0 版本增强:升级内部 PDF 文件结构以包含对象流和交叉尊重流。升级后的文件结构加载效率更高。此外,生成的文件大小略小。
PDF File Writer C# 类库支持以下 PDF 文档的功能:
- 图形:绘制线条、矩形、多边形、贝塞尔曲线、前景色和背景色、图案和阴影。第2.1节坐标系。
- 世界地区用户的小数分隔符注释,使用逗号来表示分数。请参阅第2.2节小数分隔符。
- 绘图文本。第2.3节语言支持、字体和字符集。
- 绘制图像:绘制光栅(位图)图像和矢量(元文件)图像。第2.4节。图像支持。
- 条码:支持条码 128、条码 39、条码交错 2 of 5、条码 EAN13 和条码 UPC-A。第2.5条形码支持。
- 二维码:支持二维条码。第2.6 QR代码支持。
- PDF417 条码。第2.7节PDF417 条码。
- 网页链接:网页链接互动支持。第2.8节Web 链接支持。
- 书签:支持文档大纲。第2.9节书签支持。
- 图表:支持微软图表。第2.10节图表支持。
- 打印为 PDF:从
PrintDocument
流程创建 PDF 文档。第2.11节PrintDocument 支持。 - 显示数据表。第2.12数据表支持
- 播放视频文件。第2.13播放视频文件
- 播放声音文件。第2.14播放声音文件
- 附加数据文件。第2.15节附加数据文件
- 重新排序页面。第2.16节重新排序页面
- PDF 文档输出到文件或流。第2.17节PDF 文档输出。
- PDF文档信息字典。PDF 阅读器在文档属性的描述选项卡中显示此信息。信息包括:标题、作者、主题、关键字、创建日期和时间、修改日期和时间、生成文件的应用程序、PDF 生成器。第2.18节文档信息字典。
- 内存控制:将完成页面的内容信息写入输出文件,并通过垃圾收集器释放未使用的内存。第2.19节。内存控制。
- 绘制由
System.Windows.Media.PathGeometry
类定义的图稿。输入参数可以是文本字符串或PathGeometry
类。第2.20节Windows Presentation Foundation WPF - 透明度或不透明度可用于绘制形状、线条、文本和图像。您的应用程序可以为所有图形和文本设置颜色的 alpha 分量。第2.21节透明度、不透明度、Alpha 颜色分量和混合
- 混合。该库支持 PDF 颜色混合方案。混合定义了如何处理涂在前一个项目上的新项目的颜色。第2.21节透明度、不透明度、Alpha 颜色分量和混合
- 文档链接和命名目的地。第2.22节文档链接和命名目的地。
- 加密:支持AES-128加密。第2.23节加密支持。
- 粘滞便笺2.24 粘滞便笺或文本注释。
- 图层或可选内容。2.25 图层或可选内容。
- 初始文档显示。2.26 初始文档显示。
- XMP 元数据。2.27 XMP 元数据。
创建 PDF 是一个六个步骤的过程。
- 第 1 步:创建一个文档对象
PdfDocument
。 - 第 2 步:创建资源对象,例如字体或图像(即
PdfFont
或PdfImage
)。 - 第 3 步:创建页面对象
PdfPage
。 - 第 4 步:创建内容对象
PdfContents
。 - 第 5 步:向内容对象添加文本和图形(使用
PdfContents
方法)。 - 对其他页面重复步骤 3、4 和 5
- 第 6 步:通过调用 的
CreateFile
方法创建您的 PDF 文档文件PdfDocument
。
第 5 步是您的大部分编程工作将花费的地方。添加内容是通过调用PdfContents
类的方法渲染图形和文本来实现的。内容类具有一组丰富的(大约 100 个)方法,用于向文档添加文本和图形。
PdfDocument
实现IDisposable
释放非托管资源的接口。该CreateFile
方法Document.Dispose()
在创建 PDF 文件后调用。但是,为了确保资源的释放,您应该使用语句或块将PdfDocument
创建和最终包装起来。/p>CreateFile
using
try/catch
本文所附的演示程序是为调试库而开发的测试程序。在TestPdfFileWriter
有主屏幕上的六个按钮。五个按钮用于生成 PDF 文件示例,一个按钮用于显示计算机上可用的所有字体。第一个按钮“文章示例”创建显示在本文顶部的 PDF 文件。第3节开发指南示例。
如前所述,PdfFileWriter
C# 类库使您免受 PDF 文件结构的复杂性影响。然而,对PDF文件有很好的理解总是一个优势。Adobe PDF 文件规范文档可从 Adobe 网站获得:“PDF 参考,第六版,Adobe 便携式文档格式版本 1.7 2006 年 11 月”。这是一份令人生畏的 1310 页文档。我强烈建议阅读第 4 章图形和文本第 5 章的第 5.2 和 5.3 节。
如果你想分析这个项目创建的PDF文件,或者你想了解一般的PDF文件结构,可以使用我上一篇文章“PDF文件分析器与C#解析类”所附的演示程序。本文简要概述了 PDF 规范。
2. PDF 文件编写器库一般说明
2.1. 坐标系和测量单位
PDF 坐标系原点位于页面的左下角。X 轴指向右侧。Y 轴指向上方。
PDF 的度量单位是点。一英寸有 72 个点。PDF 文件编写器允许您选择自己的度量单位。表示位置、宽度或高度的所有方法参数都必须采用您的度量单位。有两个例外:字体大小和分辨率。字体大小始终以磅为单位。分辨率始终以每英寸像素为单位。PDF 文件编写器将所有输入参数转换为点。所有内部测量值和计算均以双精度完成。在创建 PDF 文件的最后一步,值被转换为文本字符串。转换精度为六位数。使用的转换公式为:
// Value is Double
if(Math.Abs(Value) < 0.0001) Value = 0.0;
String Result = ((Single) Value).ToString();
2.2. 十进制分隔符
PDF 阅读器(如 Adobe Acrobat)期望带分数的实数使用句点作为小数点分隔符。世界上的一些地区使用其他小数点分隔符,例如逗号。由于 PDF 文件编写器库的 1.1 版将使用句点作为小数点分隔符,而不管您的计算机的区域设置如何。
2.3. 语言支持、字体和字符集
PDF 文件编写器库支持您计算机上安装的大多数字体。唯一的例外是设备字体。支持的字体遵循 OpenType 字体规范。更多信息可在Microsoft Typography - OpenType Specification 获得. 要绘制的文本存储在由 Unicode 字符组成的字符串中。库将接受除控制代码 0 到 31 和 128 到 159 之外的任何字符(0 到 65536)。每个字符都被翻译成一个字形。字形在页面上从左到右绘制,其顺序与它们存储在字符串中的顺序相同。大多数字体文件仅支持所有可能的 Unicode 字符的一个子集。换句话说,您必须选择一种支持您的项目语言或您尝试显示的符号的字体。如果输入字符串包含不受支持的字形,PDF 阅读器将显示“未定义字形”。通常它是一个小矩形。本文附带的测试程序有一个“字体系列”按钮。如果单击它,您可以看到计算机上所有可用的字体以及每种字体中所有可用的字符。如果您的项目语言是从左到右的语言,并且每个字符都被翻译成一个字形并且字形在字体中定义,那么结果应该是您所期望的。如果结果不是您所期望的,这里有一些附加说明:
Unicode 控制字符。Unicode 控制字符用于控制文本的解释或显示,但这些字符本身没有视觉或空间表示。PDF 文件编写器无法识别这些字符。该库假定每个字符都是显示字符。它们将显示为未定义字符。
从右到左的语言。通常,文本字符串中字符的顺序就是人们阅读它们的顺序。由于库是从左到右绘制的,因此文本将向后写入。该ReverseString
方法反转字符顺序。如果文本仅由从右到左的字符组成,这将解决问题。如果文本是从右到左、从左到右、数字和一些字符(如括号 ()[]<>{})的混合,则不会产生预期的结果。另一个限制是TextBox
类不能将长的从右到左的文本分成行。
结扎。在某些语言中,两个或多个字符的序列组合在一起以显示一个字形。您的软件可以识别这些序列并用正确的字形替换它们。
虚线圆圈。如果您查看 Glyph Metrics 屏幕的 Glyph 列,您可以看到一些字形有一个小的虚线圆圈(即字符代码 2364 和 2367)。这些字符是字符序列的一部分。不显示虚线圆圈。如果前进宽度为零并且边界框位于 Y 轴的左侧,则该字形将被绘制好。它将显示在前一个字符的顶部。如果前进宽度不为零,则该字形应显示在前一个字符之前。您的软件可以通过反转两个字符来实现它。
2.4. 图像支持
在 PDF 文档中显示图像由 PdfImage 类处理。这个类是一个PDF资源。图片来源可以是:
- 图像文件
- .NET Image 派生类如 Bitmap
- 黑白像素的布尔数组
- QREncoder 类表示的 QRCode 条码
- 由 Pdf417Encoder 类表示的 PDF 417 条码
- PdfChart 是 PdfImage 的派生类
- PdfPrintDocument 在内部使用 PdfImage 来捕获打印页面
图像以下列格式之一保存到 PDF 文件中:
- Jpeg 格式(有损压缩)
- 索引位图(无损压缩)
- 灰色位图(无损压缩)
- 黑白位图(无损压缩)
彩色图片应以 Jpeg 格式保存。要控制图像的大小,您可以降低分辨率或更改图像质量。彩色图片可以保存为灰色阴影。数据大小减少了三个,但您失去了颜色。如果图像是在图表中以编程方式创建的,并且颜色数小于 256,则图像可以保存为索引位图。与 3 个字节相比,每种颜色由一个字节(或更少)表示。这可能会导致非常显着的文件大小减小。例如,ChartExample.pdf 文件从 642KB 减少到 72KB。如果图像是黑白的,如文本的 PdfPrintDocument 图像,则图像可以保存为 BWImage。对于 PrintExample.pdf,Jpeg 文件为 1795KB,黑白版本为 66KB。
将图像添加到您的 PDF 文件
创建一个 PdfImage 类。
C#
//创建 PdfImage 对象
PdfImage MyImage = new PdfImage(Document);
如果需要,设置可选参数。所有参数都有一个默认值。
C#
//保存的图像格式(默认 SaveImageAs.Jpeg)
//其他选择是:IndexedImage、GrayImage、BWImage
MyImage.SaveAs = SaveImageAs.Jpeg; //裁剪矩形是要裁剪的图像区域。
//默认为无裁剪(空矩形)。
//原点在左上角,Y 轴向下。
//尺寸以像素为单位。
//裁剪矩形必须包含在图像中。
MyImage.CropRec = new Rectangle(x, y, width, height); //裁剪百分比矩形是要裁剪的图像区域。
//默认为无裁剪(空矩形)。
//原点在左上角,Y 轴向下。
//尺寸以图像的百分比表示。
//裁剪矩形必须包含在图像中。
MyImage.CropPercent = new RectangleF(x, y, width, height); //图像质量是 0 到 100 范围内的整数。
//代表质量差到最佳质量的图像。
//默认 (-1) 是使用 Bitmap 默认质量保存图像。
//供您参考 Bitmap 类默认图像质量为 75。
//图像质量越低意味着 PDF 文件越小。
MyImage.ImageQuality = PdfImage.DefaultQuality; //图像分辨率设置提供的图像分辨率
//它小于源图像的分辨率。
//默认为 0,保持原始图像分辨率。
//分辨率以每英寸像素数指定。
//降低分辨率意味着更小的 PDF 文件。
MyImage.Resolution = 0 ; //灰度转换为黑白的截止值。
//范围为 1 到 99。默认值为 50。
//如果灰度低于截止值,则结果为黑色。
//如果灰色阴影高于截止值,则结果为白色。
MyImage.GrayToBWCutoff = 50 ; //反转黑白
//默认为 false
//在灰色或黑白图像中,颜色反转
MyImage.ReverseBW = false ; //附加到图层控件
//图像可见性将由查看器应用程序控制。
MyImage.LayerControl = PdfLayer;
将图像加载到 PdfImage 对象中。注意:加载方法将图像保存在 PDF 输出文件中。完成此步骤后,将无法更改图像。
C#
//使用 5 种方法之一加载图像。
//图片来源可以是文件、Bitmap、
// BW bool 数组、QRCode 或 Pdf417 条码
MyImage.LoadImage(image_source);
将图像绘制到 PDF 文档中。
C#
//绘制图像
Contents.DrawImage(MyImage, PosX, PosY, Width, Height);
如果您希望图像保持正确的纵横比,请使用ImageSize
或ImageSizePosition
计算宽度和高度。如果宽度和高度的比例与图像不同,图像将在其中一个方向上看起来被拉伸。
//计算与正确的最大的矩形
//长宽比
尺寸MyImage.ImageSize(双宽度,双高度); //计算
适合给定区域和//位置的具有//正确纵横比
的最大矩形。它基于 <code>ContentAlignment</code> 枚举。
ImageSizePos ImageSizePosition(双倍宽度,双倍高度,ContentAlignment对齐);
2.5. 条码支持
下面的代码说明了如何在 PDF 文档中包含 UPC-A 条形码。
C#
//创建条码对象
BarcodeEAN13 Barcode = new BarcodeEAN13( " 123456789010" ); //在条码下绘制包含文本的条码
Contents.DrawBarcode(PosX, PosY, BarWidth, BarcodeHeight, Barcode, Font, FontSize);
在这种情况下,类是带有 12 位输入字符串的 BarcodeEAN13。结果是 UPC-A 条形码。
PDF 文件编写器库包括一个基类 Barcode
. 对于每个受支持的条形码,都需要一个派生类。类库包括四个子类:Barcode128
, Barcode39
,BarcodeInterleaved2of5
和BarcodeEAN13
。的BarcodeEAN13
产生EAN-13条形码如果输入字符串是13位数字和UPC-A,如果输入字符串为12位。具有 13 位数字和前导零的输入字符串被视为 UPC-A。
该DrawBarcode
方法有许多重载。您指定条码左下角的位置、窄条的宽度、条码的高度和派生的条码类。有可选参数:显示文本的对齐(左、中、右)颜色和字体。条形码周围的安静区域是您的责任。可选文本显示在条形码下方。如果您选择黑色以外的颜色,则应确保与背景的对比度显着。用法示例中给出3.7绘制条形码,ArticleExample.cs
和OtherExample.cs
。
如果要为另一个条码创建派生类,请使用三个包含类的源代码作为示例。
2.6. 二维码支持
PDF 文件编写器库提供对 QR 码的支持。它基于文章QR Code Encoder and Decoder .NET(Framework, Standard, Core) Class Library Written in C#。该程序支持三种字符集:数字、字母数字和八位字节。该程序不支持汉字字符。程序将扫描输入的数据字符串并选择最有效的字符集。如果你的数据可以被分成只有数字或字母数字字符的段,你可以创建一个带有数据字符串数组的二维码对象。
将 QRCode 条码添加到您的 PDF 文档必须遵循以下步骤。
- 创建
QREncoder
对象。 - 设置编码选项。所有编码选项都有默认值。
- 编码数据字符串或数据字节数组。
- 创建
PdfImage
. - 绘制条形码图像
PdfContent.DrawImage
二维码示例
//创建
二维码条码QREncoder QREncoder = new QREncoder(); //设置纠错码(默认为M)
QREncoder.ErrorCorrection = ErrorCorrection.M; //以像素为单位设置模块大小(默认为 2)
QREncoder.ModuleSize = 1 ; //以像素为单位设置静音区(默认为 8)
QREncoder.QuietZone = 4 ; // ECI 分配值(默认为 -1 未使用)
// ECI 值是 0 到 999999 范围内的数字。
//如果未使用,则为-1
Encoder.ECIAssignValue = -1; //编码你的文本或字节数组
QREncoder.Encode(文章链接); //将二维码转换为黑白的
PdfImage PdfImage BarcodeImage = new PdfImage(Document, QREncoder); //绘制图像(QRCode 的高度与宽度相同)
Contents.DrawImage(BarcodeImage, 6 . 0 , 6 . 8 , 1 . 2 );
有关编码示例,请查看3.7 Draw Barcodes 、ArticleExample.cs 和 OtherExample.cs 源代码。
2.7. PDF417条码
PDF417 条码支持软件基于文章PDF417 条码编码器类库和演示应用程序。PDF417 条码文档和规范可在以下网站中找到。*很好地介绍了 PDF417。单击此处访问该页面。PDF417 标准可在此网站上从 ISO 组织购买。可以从该网站免费下载规范的早期版本。如果您想完全了解编码选项,我强烈建议您下载此文档。
PDF417 条形码将字节数组编码为黑白条的图像。编码 Unicode 文本需要将 Unicode 字符转换为字节。解码器必须执行相反的过程才能恢复文本。字节被转换为码字。此转换过程将字节压缩为代码字。编码器添加纠错码字用于错误检测和恢复。一旦知道数据码字和纠错码字的总数,编码器将码字分成数据行和数据列。最后一步是创建黑白图像。
将 PDF417 条码添加到您的 PDF 文档必须遵循以下步骤。
- 创建
Pdf417Encoder
对象。 - 设置编码选项。所有编码选项都有默认值。
- 编码数据字符串或数据字节数组。
- 检查图像宽度和高度或数据列数和数据行数,以确保图像大小适合您的应用程序。如果不是,请调整布局。
- 创建
PdfImage
. - 绘制条形码图像
PdfContent.DrawImage
PDF417条码绘图示例
C#
private void DrawPdf417Barcode()
{
//保存图形状态
Contents.SaveGraphicsState(); //创建 PDF417 条码
Pdf417Encoder Pdf417 = new Pdf417Encoder(); string ArticleLink = " http://www.codeproject.com/Articles/570682/PDF-File-Writer-Csharp-Class-Library-Version" ; //编码文本
Pdf417.Encode(文章链接);
Pdf417.WidthToHeightRatio(2。5); //将 Pdf417 转换为黑白图像
PdfImage BarcodeImage = new PdfImage(Document, Pdf417); //绘制图像
Contents.DrawImage(BarcodeImage, 1 . 1 , 5 . 2 , 2 . 5 ); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
PDF417 条码对象
创建 PDF417 条码对象。该对象可以连续重复使用以生成多个条码。
//创建 PDF417 条码
Pdf417Encoder Pdf417 = new Pdf417Encoder();
设置可选参数以控制编码过程。
编码控制
PDF417 编码器将输入字节编码为码字。有三种类型的码字:字节、文本和数字。该程序有一个算法将输入的数据分成这三种类型来压缩数据。默认为自动。但是,您可以将编码限制为仅字节或仅文本和字节。
C#
Pdf417.EncodingControl = Pdf417EncodingControl.Auto;
//或
Pdf417.EncodingControl = Pdf417EncodingControl.ByteOnly;
//或
Pdf417.EncodingControl = Pdf417EncodingControl.TextAndByte;
纠错级别
PDF417 添加了纠错码字来检测错误并纠正它们。更多的纠错码字提高了条码的可靠性。但是,它会使条形码变大。纠错级别允许您控制条码的质量。该ErrorCorrectionLevel
枚举有两种类型的值。从 0 到 8 的固定级别。以及基于数据码字数的推荐值的级别。中的默认值ErrorCorrectionLevel.AutoNormal
。有关更多详细信息,请查看 PDF417 规范中的表 6 和表 7。
C#
Pdf417.ErrorCorrection = ErrorCorrectionLevel.Level_0; //到 Level_8
//或
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoNormal;
//或
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoLow; //比正常少一个
//或
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoMedium; //比正常多一个
//或
Pdf417.ErrorCorrection = ErrorCorrectionLevel.AutoHigh; //比平常多两个
窄条宽度
窄条码条的宽度(以像素为单位)。默认值为 2。如果更改此值,程序会确保RowHeight
该值至少为该值的三倍。这QuiteZone
至少是该价值的两倍。
C#
Pdf417.NarrowBarWidth =值;
行高
一行的高度(以像素为单位)。该值必须大于或等于该NarrowBarWidth
值的3 倍。默认值为 6。
C#
Pdf417.RowHeight =值;
安静区域
条码周围静区的宽度。静区是白色的。该值必须大于或等于该NarrowBarWidth
值的2 倍。默认值为 4。
C#
Pdf417.QuietZone =值;
默认数据列
默认数据列值。该值必须在 1 到 30 的范围内。默认为 3。输入数据编码后,软件将数据列数设置为默认数据列数并计算数据行数。如果数据行数超过允许的最大值 (90),软件会将行数设置为允许的最大值并重新计算数据列数。如果结果大于允许的最大列数,则会引发异常。
C#
Pdf417.DefaultDataColumns =值;
全局标签 ID 字符集
将全局标签 ID 字符集设置为 ISO 8859 标准。n 可以是 1 到 9 或 13 或 15。如果字符串为空,则使用 ISO-8859-1 的默认值。此处定义了语言支持。
C#
Pdf417.GlobalLabelIDCharacterSet = " ISO-8859-n" ;
全局标签 ID 用户定义
设置全局标签 ID 用户定义值。不使用默认值。我没有找到任何解释此值用法的参考资料。用户定义的值必须介于 810900 和 811799 之间。
C#
Pdf417.GlobalLabelIDUserDefined = UserDefinedValue;
全局标签 ID 通用
设置全局标签 ID 通用值。不使用默认值。我没有找到任何解释此值用法的参考资料。用户定义的值必须介于 900 和 810899 之间。
C#
Pdf417.GlobalLabelIDGeneralPurpose = UserDefinedValue;
编码数据
有两种编码方法。一个接受文本字符串作为输入,另一个接受字节数组作为输入。
C#
Pdf417.Encode( string StringData);
//或
Pdf417.Encode(byte[] BinaryData);
条形码是为二进制数据设计的。因此,上述第一种方法必须将字符串从 16 位字符编码为字节数组。带有字符串输入的 encode 方法具有以下转换逻辑。全局标签 ID 字符集属性控制转换。它分两步完成。第一步字符串到 UTF8,第二步 UTF8 到 ISO-8859-n。如果您想对希伯来语进行编码,您应该将字符集设置为 ISO-8859-8。
C#
公共 无效编码(字符串字符串数据)
{
//将字符串转换为 UTF8 字节数组
byte[] UtfBytes = Encoding.UTF8.GetBytes(StringData); //将 UTF8 字节数组转换为 ISO-8859-n 字节数组
Encoding ISO = Encoding.GetEncoding(_GlobalLabelIDCharacterSet ?? " ISO-8859-1" );
byte[] IsoBytes = Encoding.Convert(Encoding.UTF8, ISO, UtfBytes); //调用编码二进制数据方法
编码(IsoBytes);
返回;
}
最终条码布局
数据进行编码后,可以通过检查这些值检查条形码的布局:ImageWidth
,ImageHeight
,DataColumns
或DataRows
。如果您想重新调整条码的宽度和高度,您可以使用以下方法之一。此外,您可以重新调整可选参数:NarrowBarWidth
,RowHeight
或QuietZone
值。
宽高比
此方法将计算数据行数和数据列数,以达到所需的宽高比。该比率包括安静区。检查返回值是否成功。
C#
Bool Pdf417.WidthToHeightRatio( double Ratio);
设置数据列
此方法将根据所需的数据列数计算数据行数。检查返回值是否成功。
C#
Bool Pdf417.SetDataColumns( int Columns);
设置数据行
此方法将根据所需的数据行数计算数据列数。检查返回值是否成功。
C#
Bool Pdf417.SetDataRows( int Rows);
创建 PDF 文档图像资源
在这一步中,我们从 PDF417 条码创建一个 PDF 文档图像资源。
C#
PdfImage BarcodeImage = new PdfImage(Document, Pdf417);
绘制条码
最后一步是将条形码添加到 PDF 文档页面的内容中。
C#
// PosX 和 PosY 是用户单位的页面坐标。
//宽度为用户单位条码的宽度。
//计算条形码的高度以保持纵横比。
//高度 = 宽度 * BarcodeImage.ImageHeight / BarcodeImage.ImageWidth
Contents.DrawImage(BarcodeImage, PosX, PosY, Width);
2.8. 网页链接支持
PDF 文件编写器库提供对 Web 链接的支持。此功能是 PDF 参考手册第 8 节交互功能中描述的 PDF 交互功能之一。它是注解和动作的结合。注释将 Web 链接与页面上的区域相关联。当用户单击该区域时,PDF 阅读器将激活导航到所需网页的默认 Web 浏览器。
注解区域是由相对于页面左下角的绝对坐标定义的矩形区域。添加类的网页链接调用AddWebLink
方法PdfPage
。
C#
Page.AddWebLink( Double LeftPos, Double BottomPos, Double RightPos, Double TopPos, String WebLink );
注释不是页面内容的一部分。为了让 PDF 文档的读者或 PDF 文档的读者知道单击何处,您需要在页面的同一区域显示适当的文本或图形。换句话说,您需要调用两个方法。AddWebLink
与页面相关联的方法和与内容相关联的第二种方法。第二种方法可以是图形对象,例如图像或矩形,或文本。因为AddWebLink
需要相对于页面左下角的坐标,所以你的图形对象的坐标必须相同。换句话说,不要使用平移、缩放或旋转。如果这样做,您需要确保这两个区域重合。
PDF File Writer 有多种PdfContents
支持文本注释的方法。
绘制一行带有关联 Web 链接的文本。文本将左对齐、下划线和蓝色。文本位置相对于页面的左下角。
C#
//字体大小以
磅为单位 PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize,
Double TextAbsPosX, Double TextAbsPosY, String Text, String WebLink);
绘制一行带有关联 Web 链接的文本。文本位置相对于页面的左下角。
C#
//字体大小以
磅为单位 PdfContents.DrawWebLink(PdfPage Page, PdfFont Font, Double FontSize, Double TextAbsPosX, Double TextAbsPosY,
TextJustify Justify, DrawStyle DrawStyle, Color TextColor, String Text, String WebLink)
在其中绘制 Web 链接TextBox
是一个两步过程。首先,您使用类的AddText
方法之一将文本和 Web 链接字符串添加到框中TextBox
。其次,您TextBox
使用 的DrawText
方法之一将绘制到页面内容PdfContents
。
将网页链接添加到TextBox
. 文本将显示为带下划线和蓝色。
TextBox.AddText(PdfFont Font, Double FontSize, String Text, String WebLink);
将网页链接添加到TextBox
. 文本属性由DrawStyle
和定义FontColor
。
TextBox.AddText(PdfFont Font, Double FontSize, DrawStyle DrawStyle, Color FontColor, String Text, String WebLink);
第二步将文本绘制到内容中。此方法假定没有额外的行距或段落间距。注意,如果你在DrawText
没有PdfPage
参数的情况下调用TextBox
带有WebLink
信息的,ApplicationException
将被抛出。
//注意:PosYTop 是引用。
//在退出方法时,PosYTop 将拥有下一个 Y 位置
PdfContents.DrawText( Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo, TextBox Box, PdfPage Page);
此方法可让您定义额外的行距或段落间距。注意,如果你在DrawText
没有PdfPage
参数的情况下调用TextBox
带有WebLink
信息的,ApplicationException
将被抛出。
//注意:PosYTop 是引用。
//退出方法时,PosYTop 将拥有下一个 Y 位置
PdfContents.DrawText( Double PosX, ref Double PosYTop, Double PosYBottom, Int32 LineNo,
Double LineExtraSpace, Double ParagraphExtraSpace, Boolean FitTextToWidth, TextBox Box, PdfPage Page);
有关编码示例,请查看3.4 Draw Frame、ArticleExample.cs 和 OtherExample.cs 源代码。
2.9. 书签支持
PDF 规范(第 8.2.2 节文档大纲)中对书签的描述如下:“PDF 文档可以选择在屏幕上显示文档大纲,允许用户从文档的一个部分交互导航到另一个部分。大纲包括大纲项目(有时称为书签)的树状结构层次结构,用作可视化目录,向用户显示文档的结构。用户可以通过鼠标单击以交互方式打开和关闭单个项目。”
OtherExample.cs 源代码有一个书签示例。在一个位置有一个三层的层次结构。您可以在 OtherExample.pdf 文件中看到结果。
向应用程序添加书签的第一步是:
//设置程序显示书签
//并获取书签根对象
PdfBookmark BookmarkRoot = Document.GetBookmarksRoot();
此步骤激活文档中的书签并返回根节点。
添加书签类似于向 Windows 窗体添加控件。第一级书签被添加到根目录。后续级别将添加到现有书签中。至少你必须定义一个标题、页面、页面上的垂直位置和一个打开的条目标志。Page 是要转到的页面的 PdfPage 对象。YPos 是相对于页面左下角的垂直位置。如果较低级别的书签可见,则打开条目标志为真,如果较低级别为隐藏,则为假。默认情况下,第一级始终可见。
//层次结构示例
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( “第二章” , 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() 方法有四种重载变体:
//基本
公共PdfBookmark AddBookmark
(
String Title, //书签标题
PdfPage Page, //书签页
Double YPos, //书签相对于页面左下角的垂直位置
Boolean OpenEntries // true 是显示子项。假隐藏孩子
) //标题颜色和样式
public PdfBookmark AddBookmark
(
String Title, //书签标题
PdfPage Page, //书签页
Double YPos, //书签相对于页面左下角的垂直位置
Color Paint, //书签颜色。Coloe.Empty 是以默认颜色显示标题
TextStyle TextStyle, //书签文本样式:正常、粗体、斜体、粗斜体
Boolean OpenEntries // true 是显示子项。假隐藏孩子
) // XPos 和缩放
public PdfBookmark AddBookmark
(
String Title, //书签标题
PdfPage Page, //书签页
Double XPos, //书签相对于页面左下角的水平位置
Double YPos, //相对于页面左下角的书签垂直位置
Double Zoom, / /缩放系数。1.0 是 100%。0.0 是忽略缩放。
Boolean OpenEntries // true 是显示子项。假隐藏孩子
) //所有选项
public PdfBookmark AddBookmark
(
String Title, //书签标题
PdfPage Page, //书签页
Double XPos, //书签相对于页面左下角的水平位置
Double YPos, //相对于页面左下角的书签垂直位置
Double Zoom, / /缩放系数。1.0 是 100%。0.0 是忽略缩放。
Color Paint, //书签颜色。Coloe.Empty 是以默认颜色显示标题
TextStyle TextStyle, //书签文本样式:正常、粗体、斜体、粗斜体
Boolean OpenEntries // true 是显示子项。假隐藏孩子
)
PdfBookmark
类公开了另一种方法GetChild
。您可以通过调用GetChild
一个或多个整数参数来获取任何书签。每个参数都是级别中子位置的零基参数。例如GetChild(2)
是第一级的第三项。GetChild(2, 3)
是第三个第一级项目的第四个第二级项目。
2.10. 图表支持
PDF 规范没有特别支持图表。PDF File Writer 库通过允许开发人员创建 Microsoft Charting 对象并将此对象作为图像绘制到 PDF 文件中来提供图表支持。有关 Microsoft 图表控件注释 MSDN 库文档Visual Studio 2012 图表控件的详细信息。图表命名空间的文档可在数据可视化图表命名空间获得。附件ChartExample.cs
有四个图表示例。如果您打算使用图表,您需要添加System.Windows.Forms.Visualization
对您的项目的引用。在使用的每个源模块中,Chart
您需要添加using System.Windows.Forms.DataVisualization.Charting;
.
将图表添加到 PDF 文档是四步过程。
- 创建图表对象。
- 创建 PdfChart 对象。
- 构建图表。
- 将 PdfChart 绘制为 PdfContents。
创建图表的推荐方法是使用PdfChart
对象的静态方法。
// Document 是您的 PdfDocument 对象。
//宽度和高度以用户单位为单位。
//分辨率以每英寸像素为单位。
//分辨率是可选的。如果未包含,库将采用 .net 默认值。
//库将创建以像素为单位的宽度和高度的 Chart 对象,并以每英寸像素为单位设置分辨率
Chart MyChart = PdfChart.CreateChart(PdfDocument Document, Double Width, Double Height, Double Resolution);
您可以Chart
自己实例化类。
Chart MyChart = new Chart();
MyChart.RenderingDpiY = 300 ; //每英寸 300 像素的示例
MyChart.Width = 1950 ; // 6.5 英寸像素
示例 Mychart.Height = 1350 ; //以像素为单位的 4.6 英寸示例
接下来你PdfChart
从Chart
上面创建的创建一个。或者,您可以覆盖分辨率。
//分辨率是可选的。它将覆盖上面设置的分辨率。
PdfChart MyPdfChart = new PdfChart(PdfDocument Document, Chart MyChart, Double Resolution);
接下来构建图表。ChartExample.cs
有四个例子。构建图表的文档超出了本文的范围。网上有很多例子。
PdfChart
有一种CreateFont
方法可以简化字体的创建。它将根据图表的分辨率计算字体大小。
// FontSizeUnit 是一个枚举
//可用单位:像素、点、用户单位、英寸、厘米、毫米
Font CreateFont( String FontFamilyName, FontStyle Style, Double FontSize, FontSizeUnit Unit);
最后一步是绘制图表。
//绘制在OrigX,OrigY图表中用户单元
//宽度和图表的高度是从图表对象服用。
//它们是根据图表的像素大小和分辨率计算的。
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY); //在 OrigX、OrigY 处绘制图表,宽度和高度均指定,均以用户单位表示。
//注意:应选择宽度和高度以与图表对象的纵横比一致。
public void PdfContents.DrawChart(PdfChart MyPdfChart, Double OrigX, Double OrigY, Double Width, Double Height);
的PdfChart
类提供某些可选的方法来控制图像的定位。
该ImageSize
方法返回适合给定区域的具有正确纵横比的最大矩形。
SizeD ImageSize(双倍宽度,双倍高度);
该ImageSizePosition
方法返回具有正确纵横比的最大矩形,该矩形将适合给定区域并根据ContentAlignment
枚举对其进行定位。
ImageSizePos ImageSizePosition(双倍宽度,双倍高度,ContentAlignment对齐);
2.11. 打印文件支持
打印文档支持允许您以与打印到打印机和生成 PDF 文档相同的方式打印报告。这种生成PDF文件的方法和PdfContents
用来生成PDF文件的区别在于光栅图形和矢量图形的区别。打印文档支持每页创建一个 jpeg 图像。PrintExample.cs
有一个创建三页文档的示例。
通常每个页面都是页面的完整图像。如果您的页面是letter 大小且分辨率为每英寸300 像素,每个像素为3 个字节,则页面的位图长25.245MB。PrintPdfDocument
有一种方法CropRect
可以显着减小位图的大小。假设使用了 1 英寸的边距,位图的活动大小将减少到 15.795 MB。即减少了 37.4%。
//主程序
//创建空文档
Document = new PdfDocument(PaperType.Letter, false , UnitOfMeasure.Inch); //创建 PrintPdfDocument,生成每英寸 300 像素的图像
PdfImageControl ImageControl = new PdfImageControl();
ImageControl.Resolution = 300。0 ;
PrintPdfDocument Print = new PrintPdfDocument(Document, ImageControl); //委托方法 PrintPageEventHandler 中的 PrintPage
//该方法将一次打印一页到 PrintDocument
Print.PrintPage += PrintPage; //以用户单位(左、上、右、下)设置边距
//注意边距顺序是按照 .net 标准而不是 PDF 标准
Print.SetMargins( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ); //裁剪页面图像结果以减小 PDF 文件大小
//裁剪矩形符合 .net 标准。
//原点在左上角。
Print.CropRect = new RectangleF( 0 . 95F , 0 . 95F , 6 . 6F , 9 . 1F ); //启动打印过程(调用 PrintPage 方法)
//打印文档后,将每一页作为图像添加到 PDF 文件中。
Print.AddPagesToPdfDocument(); //处理 PrintDocument 对象
打印处理(); //创建 PDF 文件
Document.CreateFile(FileName);
PrintPage 方法的示例
//将文档的每一页打印到 PrintDocument 类
//您可以使用标准的 PrintDocument.PrintPage(...) 方法。
//注意:图形原点在左上角,Y 轴向下。
//换句话说,这不是 PdfContents 打印。
public void PrintPage(对象发送者,PrintPageEventArgs e)
{
//图形对象快捷方式
图形 G = e.Graphics; //将所有内容设置为高质量
G.SmoothingMode = SmoothingMode.HighQuality;
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
G.PixelOffsetMode = PixelOffsetMode.HighQuality;
G.CompositingQuality = CompositingQuality.HighQuality; //打印边距内的区域
矩形 PrintArea = e.MarginBounds; //在打印区域周围绘制矩形
G.DrawRectangle(Pens.DarkBlue, PrintArea); //行高
Int32 LineHeight = DefaultFont.Height + 8 ;
矩形 TextRect = new Rectangle(PrintArea.X + 4 , PrintArea.Y + 4 , PrintArea.Width - 8 , LineHeight); //显示页面边界
// DefaultFont 在其他地方定义
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; //显示打印区域
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; //为( Int32 LineNo = 1 ; ; LineNo++)打印一些行 {
text = String .Format( "页{0},行{1}",页号,行号);
G.DrawString(text, DefaultFont, Brushes.Black, TextRect);
TextRect.Y += LineHeight;
if (TextRect.Bottom > PrintArea.Bottom)中断;
} //移动到下一页
页号++;
e.HasMorePages = PageNo < = 3 ;
返回;
}
2.12. 数据表支持
数据表类允许您在 PDF 文档中显示数据表。PdfTable
是控制一张表显示的主类。表格由标题行和数据行组成。每行都分为单元格。PdfTableCell
控制一个标题单元格或一个数据单元格的显示。如果使用标题,它将显示在表格的顶部。(可选)它将显示在每个附加页面的顶部。要在单元格中显示数据,请将数据加载到 的Value
属性中 PdfTableCell
。数据可以是文本字符串、基本数值、布尔值、字符、TextBox
、图像、二维码或条形码。独立于数据,您可以加载带有文档链接、Web 链接、视频、音频或嵌入文件的单元格。单击单元格区域内的任意位置将使 PDF 阅读器激活文档链接、Web 链接、视频、音频或嵌入文件。数据的显示由 PdfTableStyle
类控制。PdfTable
类包含默认单元格样式和默认标题样式。您可以使用 .css 文件中的私有样式覆盖默认样式PdfTableCell
。要显示表格,您需要创建一个PdfTable
对象。接下来初始化表格、标题单元格、数据单元格和样式对象。最后,您设置一个循环并加载一行的单元格值,然后绘制该行。这个循环一直持续到显示所有数据。您将在下面找到生成表格的必要步骤序列。
当DrawRow
方法被调用时,该软件计算所需的行高。行高是最高单元格的高度。如果表中有足够的空间,将绘制该行。当底部可用空间太小时,会调用一个新页面,并在表格顶部显示可选标题和当前行。如果所需的行高太大以至于无法放入完整的空表,则会引发异常。为了适应长的多行字符串或TextBoxes
,软件可以灵活地处理这些情况。多行字符串由PdfTabl
e 转换为 a TextBox
。本PdfTableStyle
类有一个TextBoxPageBreakLines
属性。如果此属性设置为零(默认值),则将TextBox
其视为其他数据值。TextBox
高度必须适合页面。如果TextBoxPageBreakLines
设置为正整数,系统将计算单元格的高度为TextBox
高度或由指定的前几行的高度TextBoxPageBreakLines
。系统将使用适合页面的尽可能多的线绘制行。将创建一个新页面,并绘制其余的线条。换句话说, long 的第一个行块TextBox
将至少是TextBoxPageBreakLines
long。TableExample.cs 源包含长TextBox
单元格的示例。
创建一个PdfTable
对象。
//创建表格
PdfTable Table = new PdfTable(Page, Contents, Font, FontSize);
Page 是当前的 PdfPage。内容是当前的 PdfContents。字体是表格默认字体。FontSize 是以磅为单位的默认字体大小。
在页面上定义表的区域。
//页面上表格的区域
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top); //第一页起始垂直位置
Table.RowTopPosition = StartingTopPosition;
四个参数是表格相对于左下角的四个边,以用户单位表示。如果在第一页上,桌面位置不在设置RowTopPosition
为起始顶部位置的页面顶部。在后续页面上,表格将始终从顶部开始。如果TableArea
未指定,库会将其设置为默认页面大小减去一英寸边距。
将表格宽度分成几列。
//将表格区域宽度分成几列
StockTable.SetColumnWidth(Width1, Width2, Width3, ...);
参数的数量是列数。表格宽度减去总边界线将按这些参数的比例进行划分。
一旦使用SetColumnWidth
方法设置了列数,库就会创建两个PdfTableCell
数组。一组用于标题单元格,一组用于数据单元格。
数据表的行和列可以用边框线分隔。边界线属性由PdfTableBorder
和定义PdfTableBorderStyle
。有四个水平边界线:TopBorder
、BottomBorder
、HeaderHorBorder
标题行和第一个数据行CellHorBorder
之间以及数据行之间。有两组垂直边界线:HeaderVertBorder
用于标题行内垂直边界线的数组,以及CellVertBorder
表格数据部分中列之间的垂直边界线的数组。数组大小是列数加一。数组元素零是表格的左边框。数组元素列是表格的右边框。所有其他元素都是分隔列的行。这些行中的每一个都可以单独定义。有一些方法可以一次定义所有边界线或定义每个单独的边界线。
定义所有边界线的方法:
//清除所有边界线
Table.Borders.ClearAllBorders(); //将所有边框线设置为默认值(无需调用)
//所有边框线均为 1 点 (1/72") 宽
//所有网格线均为 1 点宽的 0.2
//所有边框均为黑色
Table.Borders.SetDefaultBorders(); //将所有边框设置为相同宽度和黑色
Table.Borders.SetAllBorders( Double Width); //将所有边框设置为相同的宽度和指定的颜色
Table.Borders.SetAllBorders( Double Width, Color LineColor); //将所有边框设置为一个宽度,将所有网格线设置为另一个宽度所有线条均为黑色
Table.Borders.SetAllBorders( Double FrameWidth, Double GridWidth); //将所有边框设置为一种宽度和颜色,将所有网格线设置为另一种宽度和颜色
Table.Borders.SetAllBorders( Double FrameWidth, Color FrameColor, Double GridWidth, Color GridColor); //将所有框架边框设置为相同宽度和黑色并清除所有网格线
Table.Borders.SetFrame( Double Width); //将所有框架边框设置为相同宽度和指定颜色并清除所有网格线
Table.Borders.SetFrame( Double Width, Color LineColor);
可以清除或设置每个水平边界线。该示例适用于顶部边界线:
//清除边框
Table.Borders.ClearTopBorder(); //将边框设置为默认颜色设置为黑色
//零宽度表示输出设备的一个像素。
Table.Borders.SetTopBorder(双线宽); //设置边框
Table.Borders.SetTopBorder( Double LineWidth, Color LineColor);
可以清除或设置每个垂直边界线。该示例适用于单元格的垂直边框线:
//清除边框
Table.Borders.ClearCellVertBorder( Int32 Index); //设置边框,默认颜色设置为黑色
Table.Borders.SetCellVertBorder( Int32 Index, Double LineWidth); //设置边框
Table.Borders.SetCellVertBorder( Int32 Index, Double LineWidth, Color LineColor);
设置其他可选的表属性。以下示例中给出的值是默认值。
//每个页面的标题
HeaderOnEachPage = true ; //最小行高
MinRowHeight = 0 . 0 ;
表信息一次处理一行。每行由单元格组成。每列一个单元格。单元格信息的显示由PdfTableStyle
类控制。大约有 20 个样式属性。有关完整列表,请查看源代码或帮助文件。其中一些样式特定于要显示的信息类型。这是一个例子
//对默认标题样式进行一些更改
Table.DefaultHeaderStyle.Alignment = ContentAlignment.BottomRight; //为标题第一列创建私有样式
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft; //加载标题值
Table.Header[0].Value = " Date" ; //对默认单元格样式进行一些更改
Table.DefaultCellStyle.Alignment = ContentAlignment.MiddleRight;
Table.DefaultCellStyle.Format = " #,##0.00" ; //为日期列创建私有样式
Table.Cell[0].Style = StockTable.CellStyle;
Table.Cell[0].Style.Alignment = ContentAlignment.MiddleLeft;
Table.Cell[0].Style.Format = null ;
初始化完成后,是时候显示数据了。下面的例子来自TableExample.cs
. 这是一张股票价格表。有 6 列。
//打开股票每日价格
StreamReader Reader = new StreamReader( " SP500.csv" ); //忽略标题
Reader.ReadLine(); //读取所有日常价格
为(;;)
{
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 = Int32 .Parse(Fld[ColVolume]);
StockTable.DrawRow();
} StockTable.Close();
该DrawRow(NewPage)
方法有一个可选参数Boolean NewPage = false
。默认值为false
。如果您希望将下一行打印在下一页的顶部,请将参数设置为true
。
交互功能示例。
//使用网页链接设置单元格编号 6
BookList.Cell[6].WebLink = WebLinkString; //另一种设置网络链接的方法
BookList.Cell[6].AnnotAction = new AnnotWebLink(WebLinkString); //将带有文档链接的单元格设置为第 3 章
BookList.Cell[6].AnnotAction = new AnnotLinkAction( " Chapter3 " ); //播放视频
PdfDisplayMedia Omega = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, " Omega.mp4" ));
BookList.Cell[6].AnnotAction = new AnnotDisplayMedia(Omega); //播放音频
PdfDisplayMedia RingSound = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, " Ring01.wav" ));
BookList.Cell[6].AnnotAction = new AnnotDisplayMedia(RingSound); //允许用户保存或查看嵌入文件
PdfEmbeddedFile EmbeddedFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, " BookList.txt" );
BookList.Cell[6].AnnotAction = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.NoIcon);
有关数据表源代码的更多示例,请查看ArticleExample.cs
和TableExample.cs
。有关、和类的更多详细文档 PdfTable
,请查看帮助文件。PdfTableCell
PdfTableStyle
PdfTableBorder
PdfFileWriter.chm
2.13. 播放视频文件
该PdfFileWriter
支持嵌入PDF文档中的视频文件。播放视频文件的完整示例在 的第 7 页中给出 OtherExample.cs
。添加视频文件需要使用三个类。首先,您需要将视频文件嵌入到 PDF 文档中。
其次,您需要定义视频的播放方式。的 PdfDisplayMedia
类有许多方法来控制视频显示。请参阅类的源代码和文档帮助文件。例如:RepeatCount
或 ScaleMedia
。如果要在浮动窗口中播放视频,则必须使用SetMediaWindow
方法。
第三,您需要在 PDF 页面上定义用户必须单击以激活视频的区域。如果要在注释区域可见时激活视频,请使用ActivateActionWhenPageIsVisible
。
//定义与视频具有相同纵横比的注释矩形
PdfRectangle AnnotRect = ImageSizePos.ImageArea( 480 , 360 ,
AreaLeft, AreaBottom, AreaRight - AreaLeft, AreaTop - AreaBottom, ContentAlignment.MiddleCenter); //创建显示媒体对象
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, " LooneyTunes.mp4" )); //创建注解对象
PdfAnnotation Annotation = Page.AddScreenAction(AnnotRect, DisplayMedia); //当页面可见时激活视频
// Annotation.ActivateActionWhenPageIsVisible(true); //定义 X Object 在视频不播放时绘制注释区域
PdfXObject AnnotArea = AnnotationArea(AnnotRect.Width, AnnotRect.Height, Color.Lavender, Color.Indigo, " Click here to play the video" );
Annotation.Appearance(AnnotArea);
浮窗视频显示
//创建显示媒体对象
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, " Omega.mp4" )); //激活显示控件
DisplayMedia.DisplayControls( true ); //无限重复视频
DisplayMedia.RepeatCount( 0 ); //在浮动窗口中显示
DisplayMedia.SetMediaWindow(MediaWindow.Floating, 640 , 360 , WindowPosition.Center,
WindowTitleBar.TitleBarWithCloseButton, WindowResize.KeepAspectRatio, "浮动窗口示例" ); Double LineSpacing = ArialNormal.LineSpacing( 12 . 0 );
双TextPosX = PosX + 0。5 * 区域宽度;
双TextPosY = PosY + 0。5 * 区域高度 + 行间距;
Double TextWidth = Contents.DrawText(ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center, "点击此文字播放视频" );
TextPosY -= LineSpacing;
Contents.DrawText(ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center, "在浮动窗口中" ); //创建注释对象
PdfRectangle AnnotRect = new PdfRectangle(TextPosX - 0 . 5 * TextWidth, TextPosY - ArialNormal.DescentPlusLeading( 12 . 0 ),
TextPosX + 0。5 * TextWidth, TextPosY + ArialNormal.AscentPlusLeading( 12 . 0 ) + LineSpacing);
Page.AddScreenAction(AnnotRect, DisplayMedia);
2.14. 播放声音文件
该PdfFileWriter
支持嵌入PDF文档中的声音文件。播放声音文件的完整示例在 的第 7 页中给出 OtherExample.cs
。嵌入声音文件本质上与视频文件相同。唯一明显的区别是没有什么可显示的。
//创建嵌入媒体文件
PdfDisplayMedia DisplayMedia = new PdfDisplayMedia(PdfEmbeddedFile.CreateEmbeddedFile(Document, " Ring01.wav" ));
DisplayMedia.SetMediaWindow(MediaWindow.Hidden);
AnnotDisplayMedia RingSound = new AnnotDisplayMedia(DisplayMedia); //显示文本区域以激活声音
Double LineSpacing = ArialNormal.LineSpacing( 12 . 0 );
双TextPosX = PosX + 0。5 * 区域宽度;
双TextPosY = PosY + 0。5 * 区域高度 + 行间距;
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Normal, Color.Red, "点击此文字播放" , RingSound);
TextPosY -= LineSpacing;
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Normal, Color.Red, "铃声" , RingSound);
2.15. 附加数据文件
该PdfFileWriter
支持嵌入PDF文档中的数据文件。的第 7 页给出了嵌入文件的完整示例OtherExample.cs
。用户可以保存文件或显示文件。
//创建嵌入媒体文件
PdfEmbeddedFile EmbeddedFile = PdfEmbeddedFile.CreateEmbeddedFile(Document, " BookList.txt" );
AnnotFileAttachment FileIcon = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.Paperclip); //显示文本区域以激活文件附件
Double LineSpacing = ArialNormal.LineSpacing( 12 . 0 );
双TextPosX = PosX + 0。5 * 区域宽度;
双TextPosY = PosY + 0。5 * 区域高度 + 行间距;
Contents.DrawText(ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center, "右键单击回形针" );
TextPosY -= LineSpacing;
Double TextWidth = Contents.DrawText(ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center, "打开或保存附件" ); //注释
Double IconPosX = TextPosX + 0 . 5 * 文本宽度 + 0。1 ;
双IconPosY = TextPosY;
PdfRectangle AnnotRect = new PdfRectangle(IconPosX, IconPosY, IconPosX + 0 . 15 , IconPosY + 0 . 4 );
Page.AddFileAttachment(AnnotRect, EmbeddedFile, FileAttachIcon.Paperclip);
TextPosY -= 2 * 行间距;
AnnotFileAttachment FileText = new AnnotFileAttachment(EmbeddedFile, FileAttachIcon.NoIcon);
Contents.DrawTextWithAnnotation(Page, ArialNormal, 12 . 0 , TextPosX, TextPosY, TextJustify.Center,
DrawStyle.Underline, Color.Red, "文件附件(右击)" , FileText);
2.16. 重新排序页面
在PdfFileWriter
追加新的页面,页面列表的末尾。如果要将页面从当前位置移动到新位置,请使用以下方法。
//源和目标索引从零开始。
// Source 必须是 0 到 PageCount - 1。
// Destination 必须是 0 到 PageCount。
//如果目标索引是 PageCount,则该页面将是最后一页
// PageCount 是 PdfDocument 的一个属性。
Document.MovePage( Int32 SourceIndex, Int32 DestinationIndex);
2.17. PDF 文档输出
PdfFileWriter 创建 PDF 文档。主类 PdfDocument 构造函数为您提供了两种保存文档的选择。第一种选择是将 PDF 文件保存到磁盘文件。在这种情况下,您为构造函数提供一个文件名。在文件创建结束时,您调用 PdfDocument.CreateFile。此方法将 PDF 写入文件并关闭文件。
//创建主类
PdfDocument Document = new PdfDocument(PaperType.Letter, false , UnitOfMeasure.Inch, FileName); //终止
Document.CreateFile();
第二个选择是流。您创建一个流,内存流或文件流,并将该流作为参数传递给 PdfDocument 构造函数。执行 CreateFile 方法后,您的流将包含 PDF 文档。根据您的应用程序从流中提取文档。您必须关闭应用程序中的流。
//创建内存流
MemoryStream PdfStream = new MemoryStream(); //创建主类
PdfDocument Document = new PdfDocument(PaperType.Letter, false , UnitOfMeasure.Inch, PdfStream); //终止
Document.CreateFile(); //将内存流保存到文件
FileStream FS = new FileStream(FileName, FileMode.Create);
PdfStream.WriteTo(FS);
PdfStream.Close();
FS.关闭();
2.18. 文档信息字典
PDF 文档信息字典由 PDF 阅读器显示在文档属性的描述选项卡中。信息包括:标题、作者、主题、关键字、创建日期和时间、修改日期和时间、生成文件的应用程序、PDF 生成器。在您的应用程序中包含文档信息的操作如下:
PdfInfo Info = new PdfInfo(Document);
Info.Title( "文章示例" );
Info.Author( “ Uzi Granot Granotech Limited” );
Info.Keywords( " PDF, .NET, C#, Library, Document Creator" );
Info.Subject( " PDF 文件编写器 C# 类库 (版本 1.15.0)" );
当PdfInfo
对象被创建,四个额外的字段被添加到词典中。您可以在代码中覆盖所有这些。
//设置创建和修改日期
DateTime LocalTime = DateTime.Now;
Info.CreationDate(LocalTime);
Info.ModDate(LocalTime); //设置创建者和生产者
Info.Creator( " PdfFileWriter C# Class Library Version " + PdfDocument.RevisionNumber);
Info.Producer( " PdfFileWriter C# 类库版本" + PdfDocument.RevisionNumber);
2.19. 内存控制
在构建文档时,PDF 文件编写器会累积创建 PDF 文件所需的所有信息。除图像和嵌入文件外,信息保存在内存中。图像和嵌入文件在声明时会自动写入输出文件。对于非常大的文档,使用的内存不断增长。该库提供方法 ( CommitToPdfFile
) 将内容信息写入输出文件并调用垃圾收集器以释放未使用的内存。该GC.Collect
方法需要时间来执行。如果执行时间是一个问题,请GCCollect
每隔几页设置一次参数。换句话说,CommitToPdfFile
必须为每个页面运行一次,但每隔几页进行一次清理。一旦执行了提交,就不能添加额外的信息。 PdfTable
当下一行无法容纳在当前页面的底部时,自动开始一个新页面。的PdfTable
类有两个成员CommitToPdfFile
和CommitGCCollectFreq
到控制存储器的使用,同时一个表正在被构建。的PdfChart
类生成从.NET图表类的图像。的DrawChart
方法PdfContents
将执行提交。或者,您可以调用 的CommitToPdfFile
方法PdfChart
。
// PdfContents、PdfXObject 和 PdfTilingPattern
//将内容提交到输出文件。
//一旦提交,此 PdfContents 将无法使用。
//参数是 GCCollect
Contents.CommitToPdfFile( true );
2.20 Windows Presentation Foundation WPF
绘制 WPF 图形是一个四步过程。
- 第一步:创建
DrawWPFPath
对象。输入参数是路径和 Y 轴方向。 - 第 2 步:可选择通过调用七个
SetBrush
方法之一或调用UseCurrentBrush
方法来添加画笔。 - 步骤 3:可选择通过调用两种
SetPen
方法之一或调用UseCurrentPen
方法来添加笔。 - 第 4 步:通过调用绘制图形对象
PdfContents.DrawWPFPath
。
如果System.Windows.Media
引用不是可用(即你的应用程序是Windows窗体),你需要添加PresentationCore
和WindowsBase
组件到应用程序。
OtherExample.cs
Example8e 和 Example8f 中给出了使用 WPF 图形类绘图的编程示例。
如果未定义画笔和笔,则绘制图形将作为剪辑路径。
您将在下面找到有关如何将 DrawWPFPath 类用于 WPF 应用程序和其他应用程序的更多详细信息。
DrawWPFPath
构造函数接受两个参数:路径和 Y 轴方向。路径是字符串或System.Windows.Media.PathGeometry
. 文本字符串在Path Markup Syntax 中定义。路径几何类在PathGeometry Class 中描述。为 WPF 环境定义路径时,Y 轴方向向下。Y 轴适用于 PDF 环境。
请注意世界上任何地方使用除句点以外的数字小数分隔符的程序员。表示路径的文本字符串输入必须完全按照路径标记语法中的定义构造。无论世界区域如何,带分数的小数都必须使用句点。如果在 x 和 y 值之间使用可选分隔符,则它必须是逗号。如果字符串是由另一个应用程序生成的,请确保使用以下方法调用 PathGeometry ToString:PathGeometry.ToString(System.Globalization.CultureInfo.InvariantCulture)。换句话说,Microsoft 的 PathGeometry.Parse 方法将无法读取在意大利生成的文本字符串,例如,通过 PathGeometry.ToString 方法没有将 IFormatProvider 设置为InvariantCulture。 |
可以通过三种方法为 WPF 应用程序定义画笔。所有这些方法都会同时设置画笔不透明度。
-
System.Windows.Media.SolidColorBrush
请参阅SolidColorBrush 类 -
System.Windows.Media.LinearGradientBrush
请参阅LinearGradientBrush 类 -
System.Windows.Media.RadialGradientBrush
请参阅RadialGradientBrush 类
有五种方法可以为所有应用程序定义画笔。所有这些方法都会同时设置画笔不透明度。
- 将画笔设置为
System.Drawing.Color
。 - 将画笔设置为
PdfAxialShading
- 将画笔设置为
PdfRadialShading
- 将画笔设置为
PdfTilingPattern
- 将画笔设置为
UseCurrentBrush
如果希望DrawWPFPath
类将画笔设置为当前选定的画笔,请调用UseCurrentBrush
方法。
有一种方法可以为 WPF 应用程序定义笔。SetPen
使用System.Windows.Media.Pen
类调用方法(请参阅Pen 类)。请注意,该Pen.Brush
属性必须为SolidColorBrush
。pen 类包含绘制线条所需的所有信息,例如颜色和宽度。
有一种方法可以为所有应用程序定义一支笔。打电话SetPen
与System.Drawing.Color
论证。color 参数定义了 alpha、红色、绿色和蓝色分量。要设置其他笔特性,请设置以下任何或所有属性和方法:
SetPenWidth
DashArray
DashPhase
LineCap
LineJoin
MiterLimit
如果您希望DrawWPFPath
类将笔设置为当前选定的笔调用UseCurrentPen
方法。
一旦DrawWPFPath
类设置的所有信息需要绘制的路径,调用PdfContents.DrawWPFPath
方法。DrawWPFPath 类根据路径边界框和绘图矩形以及对齐方式计算将输入路径转换为绘图矩形所需的变换矩阵。零对齐(默认)将拉伸路径以适合绘图区域。所有其他对齐值根据参数枚举值在绘图区域内定位路径。
public void DrawWPFPath(
DrawWPFPath Path, //要绘制的路径
double OriginX, //以用户单位绘制矩形 left side
double OriginY, //以用户单位绘制矩形bottom side
double Width, //以用户单位绘制矩形 width
double Height, //绘制矩形以用户为单位高度
//内绘制矩形路径对准
//对齐= 0表示路径将被拉伸
//在水平或垂直方向
//以适合绘制矩形
的ContentAlignment对齐=0 )
2.21 透明度、不透明度、Alpha 颜色分量和混合
默认情况下,PDF 成像模型将对象(形状、线条、文本和图像)不透明地绘制到页面上。每个新对象都完全遮住了它下面的图像。PDF 有两种机制来改变不透明度和混合这种行为。图形状态字典具有描边(笔)和非描边(画笔)操作的不透明度值。完全不透明的不透明度值为 1.0,完全透明的值为 0.0。不透明度值对应于颜色结构的 alpha 分量,1.0 是 255 alpha,0.0 是 0 alpha。如果不透明度值为 0.5,则在页面上绘制的新对象的透明度为 50%。要设置不透明度,请调用SetAlphaStroking
线条 SetAlphaNonStroking
方法或形状方法。混合是将页面上的颜色与正在绘制的新项目的颜色相结合的过程。要设置平淡模式,请调用SetBlendMode
的方法 PdfContents
。参数是BlendMod
枚举。有关完整说明,请参阅 PDF 规范文档的第 7.2.4 节混合模式。例如,请参阅OtherExample.cs
第 8 页。
2.22. 文档链接和命名目的地
文档链接允许 PDF 文档用户单击链接并跳转到文档的另一部分。添加文档链接分两部分完成。目的地被定义为位置标记。位置标记必须具有唯一名称、范围(LocalDest
或NamedDest
)和文档位置(页面和位置)。 NamedDest
范围可用于文档链接或命名目的地或两者。第二部分是链接位置。这两个部分可以按任何顺序定义。他们被名字联系在一起。名称区分大小写。许多链接可以指向同一个位置标记。
命名目标是 PDF 文档中的目标。它们以与文档链接相同的方式使用位置标记定义。范围必须设置为NamedDest
。当 Adobe Acrobat 等 PDF 阅读器打开 PDF 文档时,它可以在打开文档的同时在查看窗口中显示目标。
要嵌入位置标记,请调用 的AddLocationMarker
方法PdfPage
。注意:名称区分大小写。
//给文档添加位置标记(PdfPage 方法)
public void AddLocationMarker
(
string LocMarkerName, //唯一目标名称(区分大小写)
LocMarkerScope Scope, // LocalDest 或 NamedDest
DestFit FitArg, //拟合参数(见下文)
params double[] SideArg // 0、1 或 4 边尺寸参数(见下文) )
)
要添加链接位置,请调用 PdfPage 的 AddLinkLocation 方法。
公共PdfAnnotation AddLinkAction
(
string LocMarkerName, //位置标记名称
PdfRectangle AnnotRect //页面矩形区域激活跳转
)
有关指定目的地的更多信息,请参阅 Adobe PDF 文件规范“PDF 参考,第六版,Adobe 便携式文档格式版本 1.7 2006 年 11 月”。第 582 页的表 8.2。
-
DestFit.Fit
(no arg): 显示页面,其内容被放大到足以在窗口中水平和垂直地容纳整个页面。 -
DestFit.FitH
(1 arg Top):显示页面,垂直坐标顶部位于窗口的上边缘,页面内容被放大到刚好适合窗口内页面的整个宽度。 -
DestFit.FitV
(1 arg Left):显示页面,左水平坐标位于窗口的左边缘,页面内容被放大到刚好适合窗口内页面的整个高度。 -
DestFit.FitR
(4 args Left Bottom Right Top):显示页面,其内容被放大到刚好适合窗口内水平和垂直坐标左、下、右和顶部指定的矩形。 -
DestFit.FitB
(无参数):显示页面,其内容被放大到足以在水平和垂直方向完全适合窗口内的边界框。 -
DestFit.FitBH
(1 arg Top):显示页面,垂直坐标顶部位于窗口的顶部边缘,页面内容被放大到刚好适合窗口内边界框的整个宽度。 -
DestFit.FitBV
(1 arg 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>
2.23. 加密支持
PDF 文件编写器库支持 AES 128 和标准 128 (RC4) 加密。有关更多信息,请参阅 PDF 参考第六版(1.7 版)第 3.5 节加密。PDF 文件编写器支持两种类型的加密过滤器,AES-128 和标准 128。标准 128 是 RC4 加密。它被认为是不安全的。对于新项目,不要使用它。不支持公钥安全对收件人列表进行编码。
要加密您的 PDF 文档,请调用类中SetEncryption
定义的四种方法之一PdfDocument
:
设置不带参数的加密。
PDF File Writer 库将使用 AES-128 加密对 PDF 文档进行加密。PDF 阅读器无需密码即可打开文档。权限标志设置为允许所有。
Document.SetEncryption();
使用一个参数设置加密。
PDF File Writer 库将使用 AES-128 加密对 PDF 文档进行加密。参数是权限。权限标志定义如下。您可以或一起拥有多个权限。PDF 参考手册有权限的完整描述。PDF 阅读器无需密码即可打开文档。
Document.SetEncryption(权限权限);
使用两个参数设置加密。
PDF File Writer 库将使用 AES-128 加密对 PDF 文档进行加密。这两个参数是用户密码和权限。PDF 阅读器将使用用户密码打开文档。权限将根据参数设置。
Document.SetEncryption( String UserPassword, Permission Permissions);
使用四个参数设置加密。
PDF 文件编写器库将使用 EncryptionType.Aes128 加密或 EncryptionType.Standard128 加密对 PDF 文档进行加密。四个参数是用户密码、所有者密码、权限和加密类型。如果用户密码为空,则使用默认密码。如果所有者密码为空,软件将生成随机数密码。Standard128 加密被认为是不安全的。它不应该用于新项目。
Acrobat 等 PDF 阅读器将接受用户或所有者密码。如果使用所有者密码打开文档,PDF 阅读器将使用所有权限设置为允许操作打开它。
Document.SetEncryption( String UserPassword, String OwnerPassword, Permission Permissions, EncryptionType Type);
权限标志如下:
//完整描述见
// PDF 参考版本 1.7 表 3.20
公共 枚举权限
{
无 = 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 , //位 11
打印 = 0x804 , //位 12 + 位 3
All = 0xf3c , //第 3、4、5、6、9、10、11、12 位
}
2.24. 粘滞便笺或文本注释。
PDF 参考文档在第 8.4 节第 621 页中定义了便签或文本注释。“文本注释表示附加到 PDF 文档中某个点的“便签”。关闭时,注释显示为图标;打开时,它会显示一个弹出窗口,其中包含以查看器应用程序选择的字体和大小的笔记文本。文本注释不随页面缩放和旋转;它们的行为就像始终设置 NoZoom 和 NoRotate 注释标志(参见第 608 页的表 8.16)一样。表 8.23 显示了特定于此类注释的注释字典条目。”
在您的文档中添加便利贴非常简单。您添加一行代码。便签被添加到PdfPage
对象。它不是页面内容的一部分。便签的位置是从页面左下角到便签图标左上角的绝对页面位置。文本字符串是弹出窗口的内容。便签参数是下面的枚举项之一。
//便签文本注释
Page.AddStickyNote(PageAbsPosX, PageAbsPosY,
"我的第一个便签" , StickyNoteIcon.Note); //便签图标
public enum StickyNoteIcon
{
//注释(注意:没有图标)
评论, //键
钥匙, //注意(默认)
笔记, //帮助
帮助, //新段落
新段落, //段落
段落, //插入
插,
}
2.25. 图层或可选内容。
PDF 规范文档(第 4.10 节)定义了可选内容如下。“可选内容 (PDF 1.5) 是指 PDF 文档中可以由文档作者或消费者有选择地查看或隐藏的内容部分。此功能在 CAD 绘图、分层图稿、地图和多语言文档等项目中非常有用。”
Adobe Acrobat 查看器在屏幕左侧有导航面板。其中之一是图层面板。如果 PDF 文档使用图层,则此面板中将显示图层控制开关。用户可以显示或隐藏附加到这些图层控件的项目。
向您的 PDF 文档添加图层。完整示例在 中给出LayersExample.cs
。此外OtherExample.cs
还有使用图层控制图像和注释的示例。
创建主要图层控制对象。每份文件一份。
//创建一个图层控件对象并为其命名。
//只允许一个这样的对象。
//名称将显示在图层面板中。
PdfLayers Layers = new PdfLayers(Document, " PDF layers group" );
设置列表模式选项。默认为所有页面
//列表模式
Layers.ListMode = ListMode.AllPages; //默认 //或
Layers.ListMode = ListMode.VisiblePages;
创建一个或多个图层对象。每一项都对应图层面板上的一个复选框。每个人都可以控制一个或多个显示项目。
//创建一个或多个图层对象
PdfLayer LayerName = new PdfLayer(Layers, " Layer name" );
许多层可以组合成单选按钮组。一组单选按钮可以全部关闭或仅打开一层。
//可选地将三层组合成
//一组单选按钮
LayerName1.RadioButton = " Group1" ;
LayerName2.RadioButton = " Group1" ;
在图层窗格中设置图层的顺序。如果不使用 DisplayOrder 方法,程序将在同一主层上列出上面指定的所有层。如果使用 DisplayOrder 方法,则必须包含所有图层
图层列表可以有带有可选名称的子组
//显示顺序
Layers.DisplayOrder(LayerName1);
Layers.DisplayOrder(LayerName2);
Layers.DisplayOrder(LayerName3);
Layers.DisplayOrderStartGroup( "子组" );
Layers.DisplayOrder(LayerName4);
Layers.DisplayOrder(LayerName5);
Layers.DisplayOrder(LayerName6);
Layers.DisplayOrderEndGroup();
定义内容流中的区域以按层控制
//内容流开始层标记
Contents.LayerStart(LayerName1); //您的内容方法
//由 LayerName1 控制 // LayerName1 区域的结尾
Contents.LayerEnd();
直接控制图像或注释。图像可以位于文档中的任何位置。
//图像或注释控件
QREncoder QREncoder = new QREncoder();
QREncoder.ErrorCorrection = ErrorCorrection.M;
QREncoder.Encode( "一些数据" );
PdfImage QRImage = new PdfImage(Document);
QRImage.LayerControl = LayerName1;
QRImage.LoadImage(QREncoder);
2.26. 初始文档显示。
当 PDF 查看器 (Acrobat) 显示文档时,初始文档显示控制文档的外观。它控制屏幕的左窗格。
例如,打开书签窗格。
Document.InitialDocDisplay = InitialDocDisplay.UseBookmarks;
//初始文档显示枚举
public enum InitialDocDisplay
{
//保持左窗格关闭
使用无, //打开书签窗格
使用书签, //打开页面缩略图
使用拇指, //全屏模式
全屏, //打开图层
使用图层, //打开附件
使用附件,
}
2.27. XMP 元数据。
XMP 文件或字节数组嵌入在 PDF 对象中包含的元数据流中。XMP 必须编码为 UTF-8。PdfFileWriter 包括用户提供的输入文件或输入字节数组。用户必须确保 XMP 输入是有效的元文件。XMP 流未压缩或加密。这使读者可以通过很少的编程来获取元数据信息。您应该在创建 PdfDocument 后不久和加载任何图像之前包含 XMP matadata。通过这样做,元数据将位于文件的开头,并且可以被简单的文本编辑器读取。
//添加元数据
new PdfMatadata(Document, FileName); //或
新的PdfMetadata(Document, ByteArray);
3. 示例开发指南
本节介绍将 PDF 文件编写器 C# 类库集成到您的应用程序。测试程序TestPdfFileWriter
程序是对您自己的应用程序的模拟。当您按下“文章示例”按钮时,程序将执行ArticleExample.cs
源文件中的代码。上图显示了生成的 PDF 文件。此方法演示了使用一些文本和图形创建一页文档。看完这个例子后,你应该对这个过程有一个很好的理解。其他示例按钮生成各种 PDF 文档。总的来说,这些示例演示了该库的几乎所有功能。
调试复选框,如果选中,将创建一个可以用文本编辑器查看但不能加载到 PDF 阅读器的 PDF 文件。结果文件未压缩,图像和字体文件替换为文本占位符。调试复选框应该仅用于调试。
TestPdfFileWriter 程序是使用 Microsoft Visual C# 2012 开发的。它已针对 Windows XP、Vista、7 和 8 进行了测试。
3. 示例开发指南
本节介绍将 PDF 文件编写器 C# 类库集成到您的应用程序。测试程序TestPdfFileWriter
程序是对您自己的应用程序的模拟。当您按下“文章示例”按钮时,程序将执行ArticleExample.cs
源文件中的代码。上图显示了生成的 PDF 文件。此方法演示了使用一些文本和图形创建一页文档。看完这个例子后,你应该对这个过程有一个很好的理解。其他示例按钮生成各种 PDF 文档。总的来说,这些示例演示了该库的几乎所有功能。
调试复选框,如果选中,将创建一个可以用文本编辑器查看但不能加载到 PDF 阅读器的 PDF 文件。结果文件未压缩,图像和字体文件替换为文本占位符。调试复选框应该仅用于调试。
TestPdfFileWriter 程序是使用 Microsoft Visual C# 2012 开发的。它已针对 Windows XP、Vista、7 和 8 进行了测试。
3.1. 文档创建概述
下面的测试方法演示了创建 PDF 文件简介中描述的六个步骤。当您按下演示程序的“文章示例”按钮时,将执行该方法。以下小节详细描述了每个步骤。
//创建文章示例测试 PDF 文档
public void Test
(
bool调试,
字符串文件名
)
{
{
//第 1 步:创建空文档
//参数:页面宽度:8.5",页面高度:11",度量单位:英寸
//返回值:PdfDocument 主类
Document = new PdfDocument(PaperType.Letter, false , UnitOfMeasure.英寸,文件名); //用于加密测试
// Document.SetEncryption(null, null, Permission.All & ~Permission.Print, EncryptionType.Aes128); //调试属性
//默认情况下它设置为 false。仅用于调试。
//如果设置了这个标志,PDF 对象将不会被压缩,字体和图像将被
//替换为文本占位符。您可以使用文本编辑器查看文件,但无法使用 PDF 阅读器打开它。
Document.Debug = 调试; PdfInfo 信息 = PdfInfo.CreatePdfInfo(Document);
Info.Title( "文章示例" );
Info.Author( “乌兹·格拉诺特” );
Info.Keywords( " PDF, .NET, C#, Library, Document Creator" );
Info.Subject( " PDF 文件编写器 C# 类库 (版本 1.21.0)" ); //第二步:创建资源
//定义字体资源
定义字体资源(); //定义平铺模式资源
定义TilingPatternResource(); //第三步:添加新页面
Page = new PdfPage(Document); //第 4 步:向页面添加内容
Contents = new PdfContents(Page); //第五步:在contents对象中添加图形和文字内容
DrawFrameAndBackgroundWaterMark();
DrawTwoLinesOfHeading();
DrawHappyFace();
DrawBarcode();
DrawPdf417Barcode();
绘制图像();
绘制图表();
绘制文本框();
DrawBookOrderForm(); //第六步:创建pdf文件
Document.CreateFile(); //启动默认 PDF 阅读器并显示文件
Process Proc = new Process();
Proc.StartInfo = new ProcessStartInfo(FileName);
进程开始(); //退出
返回;
}
3.2. 字体资源
该DefineFontResources
方法创建了本示例中使用的所有字体资源。要查看任何字体可用的所有字符,请按“字体系列”按钮。选择一个族并查看为每个字符定义的字形。要查看单个字形,请按查看或双击。
//定义字体资源
private void DefineFontResources()
{
//定义字体资源
// Arguments: PdfDocument class, font family name, font style, embed flag
//字体样式(必须是:Regular, Bold, Italic or Bold | Italic) 其他所有样式无效。
//嵌入字体。如果为 true,字体文件将嵌入 PDF 文件中。
//如果为false,字体将不会被嵌入
字符串FontName1 = " Arial" ;
string FontName2 = " Times New Roman" ; ArialNormal = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Regular, true );
ArialBold = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Bold, true );
ArialItalic = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Italic, true );
ArialBoldItalic = PdfFont.CreatePdfFont(Document, FontName1, FontStyle.Bold | FontStyle.Italic, true );
TimesNormal = PdfFont.CreatePdfFont(Document, FontName2, FontStyle.Regular, true );
Comic = PdfFont.CreatePdfFont(Document, " Comic Sans MS" , FontStyle.Bold, true );
返回;
}
3.3. 平铺模式资源
该DefineTilingPatternResource
方法定义了示例区域的背景图案资源。图案是浅蓝色背景上的白色“PdfFileWriter”字样。该模式由两行重复的关键字组成。两条线偏斜了半个字长。
如果您想找到有趣的图案,请在互联网上搜索制造地砖或墙砖的公司目录。
//定义平铺模式资源
private void DefineTilingPatternResource()
{
//创建空的平铺图案
WaterMark = new PdfTilingPattern(Document); //该模式将 PdfFileWriter 放在砖模式
字符串中Mark = " PdfFileWriter" ; // Arial 粗体的文本宽度和高度 18
磅double FontSize = 18 . 0 ;
double TextWidth = ArialBold.TextWidth(FontSize, Mark);
double TextHeight = ArialBold.LineSpacing(FontSize); //文本基线
double BaseLine = ArialBold.DescentPlusLeading(FontSize); //整体图案框(我们添加文本高度值作为左右文本边距)
double BoxWidth = TextWidth + 2 * TextHeight;
双框高度 = 4 *文本高度;
WaterMark.SetTileBox(BoxWidth, BoxHeight); //保存图形状态
WaterMark.SaveGraphicsState(); //用浅蓝色背景填充图案框
WaterMark.SetColorNonStroking(Color.FromArgb( 230 , 244 , 255 ));
WaterMark.DrawRectangle( 0 , 0 , BoxWidth, BoxHeight, PaintOp.Fill); //将水印文本的填充颜色设置为白色
WaterMark.SetColorNonStroking(Color.White); //在框的底部中心绘制 PdfFileWriter
WaterMark.DrawText(ArialBold, FontSize, BoxWidth / 2 , BaseLine, TextJustify.Center, Mark); //将基线向上调整一半高度
BaseLine += BoxHeight / 2 ; //绘制 PdfFileWriter 的右半部分,左移半宽
WaterMark.DrawText(ArialBold, FontSize, 0 . 0 , BaseLine, TextJustify.Center, Mark); //绘制 PdfFileWriter 的左半部分右移半宽
WaterMark.DrawText(ArialBold, FontSize, BoxWidth, BaseLine, TextJustify.Center, Mark); //恢复图形状态
WaterMark.RestoreGraphicsState();
返回;
}
3.4. 画框与背景图案
该DrawFrameAndBackgroundWaterMark
方法在具有背景水印图案的示例区域周围绘制框架。模式资源在上一小节中定义。
//在示例区域周围画框
private void DrawFrameAndBackgroundWaterMark()
{
//保存图形状态
Contents.SaveGraphicsState(); //在页面周围绘制边框
//将线宽设置为 0.02"
Contents.SetLineWidth( 0 . 02 ); //设置框架颜色为深蓝色
Contents.SetColorStroking(Color.DarkBlue); //使用水印平铺图案填充框架
Contents.SetPatternNonStroking(WaterMark); //矩形位置:x=1.0", y=1.0", width=6.5", height=9.0"
Contents.DrawRectangle( 1 . 0 , 1 . 0 , 6 . 5 , 9 . 0 , PaintOp.CloseFillStroke); //恢复图形状态
Contents.RestoreGraphicsState(); //在框架下绘制文章名称
//注意:\u00a4 是在字体资源定义期间替换的字符 164
//这个字符是一个实心圆它通常是 Unicode 9679 或 Arial 系列中的 \u25cf
Contents.DrawText(ArialNormal , 9 . 0 , 1 . 1 , 0 . 85 , " PdfFileWriter \u25cf PDF 文件编写器 C# 类库 \u25cf 作者:Uzi Granot" ); //绘制文章的网页链接
Contents.DrawWebLink(Page, ArialNormal, 9 . 0 , 7 . 4 , 0 . 85 , TextJustify.Right,
DrawStyle.Underline, Color.Blue, "点击查看文章" , ArticleLink); 返回;
}
3.5. 绘制两条标题线
该DrawTwoLinesOfHeading
方法在页面中心绘制两条标题线。第一行是绘制带有轮廓特效的文字。
//绘制标题
private void DrawTwoLinesOfHeading()
{
//页面标题
//参数:字体:ArialBold,大小:36 点,位置:X = 4.25", Y = 9.5"
//文本对齐:居中(文本中心将在 X 位置)
//触发颜色:R= 128, G=0, B=255 (文字轮廓)
// 无描边颜色: R=255, G=0, B=128 (文字正文)
Contents.DrawText(Comic, 40 . 0 , 4 . 25 , 9 . 25 , TextJustify.Center, 0 . 02 , Color.FromArgb( 128 , 0 , 255 ), Color.FromArgb( 255 , 0 ,128 ), " PDF 文件编写器" ); //保存图形状态
Contents.SaveGraphicsState(); //将非描边(填充)颜色更改为紫色
Contents.SetColorNonStroking(Color.Purple); //绘制标题文本的第二行
//参数:手写字体,字体大小 30 磅,位置 X=4.25", Y=9.0"
//文本对齐:居中(文本中心将在 X 位置)
Contents.DrawText(Comic , 30 . 0 , 4 . 25 , 8 . 75 , TextJustify.Center, "示例" ); //恢复图形状态(非描边颜色将恢复为默认)
Contents.RestoreGraphicsState();
返回;
}
3.6. 画快乐的脸
该DrawHappyFace
方法是绘制椭圆并从直线和贝塞尔曲线构建路径的示例。
//绘制开心脸
private void DrawHappyFace()
{
//保存图形状态
Contents.SaveGraphicsState(); //将坐标原点平移到笑脸的中心
Contents.Translate( 4 . 25 , 7 . 5 ); //将非描边(填充)颜色更改为黄色
Contents.SetColorNonStroking(Color.Yellow); //绘制笑脸黄色椭圆
Contents.DrawOval(-1. 5 , -1. 0 , 3 . 0 , 2 . 0 , PaintOp.Fill); //将线宽设置为 0.2" 这是眼睛周围的黑色圆圈
Contents.SetLineWidth( 0 . 2 ); //眼睛颜色为白色,带有黑色轮廓圆圈
Contents.SetColorNonStroking(Color.White);
Contents.SetColorStroking(Color.Black); //画眼睛
Contents.DrawOval(-0. 75 , 0 . 0 , 0 . 5 , 0 . 5 , PaintOp.CloseFillStroke);
Contents.DrawOval( 0 . 25 , 0 . 0 , 0 . 5 , 0 . 5 , PaintOp.CloseFillStroke); //嘴巴颜色是黑色
Contents.SetColorNonStroking(Color.Black); //通过创建由一条直线和一条贝塞尔曲线组成的路径来绘制嘴巴
Contents.MoveTo(-0. 6 , -0. 4 );
Contents.LineTo( 0 . 6 , -0. 4 );
Contents.DrawBezier( 0 . 0 , -0. 8 , 0 , -0. 8 , -0. 6 , -0. 4 ); //用黑色填充路径
Contents.SetPaintOp(PaintOp.Fill); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.7. 绘制条码
该DrawBarcode
方法以绘制两个条码 EAN-13 和 Code-128 为例
//绘制条码
private void DrawBarcode()
{
//保存图形状态
Contents.SaveGraphicsState(); //绘制 EAN13 条码
BarcodeEAN13 Barcode1 = new BarcodeEAN13( " 1234567890128" );
Contents.DrawBarcode( 1 . 3 , 7 . 05 , 0 . 012 , 0 . 75 , Barcode1, ArialNormal, 8 . 0 ); //创建
二维码条码QREncoder QREncoder = new QREncoder(); //设置纠错码
QREncoder.ErrorCorrection = ErrorCorrection.M; //以像素为单位设置模块大小
QREncoder.ModuleSize = 1 ; //以像素为单位设置静音区
QREncoder.QuietZone = 4 ; //编码你的文本或字节数组
QREncoder.Encode(文章链接); //将
二维码转换为黑白图像PdfImage BarcodeImage = new PdfImage(Document);
BarcodeImage.LoadImage(QREncoder); //绘制图像(QRCode 的高度与宽度相同)
Contents.DrawImage(BarcodeImage, 6 . 0 , 6 . 8 , 1 . 2 ); //用二维码定义一个网页链接区域 Page.AddWebLink
( 6 . 0 , 6 . 8 , 7 . 2 , 8 . 0 , ArticleLink); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.8. 绘制 PDF417 条码
//绘制条码
private void DrawPdf417Barcode()
{
//保存图形状态
Contents.SaveGraphicsState(); //创建 PDF417 条码
Pdf417Encoder Pdf417 = new Pdf417Encoder();
Pdf417.DefaultDataColumns = 3 ;
Pdf417.Encode(文章链接);
Pdf417.WidthToHeightRatio(2。5); //将 Pdf417 转换为黑白图像
PdfImage BarcodeImage = new PdfImage(Document);
BarcodeImage.LoadImage(Pdf417); //绘制图像
Contents.DrawImage(BarcodeImage, 1 . 1 , 5 . 2 , 2 . 5 ); //用二维码定义一个网页链接区域
double Height = 2 . 5 * Pdf417.ImageHeight / Pdf417.ImageWidth;
Page.AddWebLink( 1 . 1 , 5 . 2 , 1 . 1 + 2 . 5 , 5 . 2 + Height, ArticleLink); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.9. 绘制图像并剪辑它
的Draw
图像的方法是绘制一图象的一个例子。该PdfFileWriter
存储中的所有图像文件的支持绘制图像支持Bitmap
类和Metafile
类。在ImageFormat
类定义所有图像类型。JPEG 图像文件类型是 PDF 文件的原生图像格式。如果您PdfImage
使用 JPEG 文件调用构造函数,程序会将文件原样复制到 PDF 文件中。如果您PdfImage
使用任何其他类型的图像文件调用构造函数,程序会将其转换为 JPEG 文件。为了使 PDF 文件尽可能小,请确保您的图像文件分辨率不会过高。
的PdfImage
类负载可以容纳在用户坐标给定的图像尺寸和保留原始长宽比图像并且计算最大大小。在绘制图像之前,我们创建一个椭圆剪切路径来剪切图像。
//绘制图像并剪辑它
private void DrawImage()
{
//定义本地图片资源
//分辨率每英寸 96 像素,图片质量 50%
PdfImage Image1 = new PdfImage(Document);
Image1.Resolution = 96。0 ;
Image1.ImageQuality = 50 ;
Image1.LoadImage( " TestImage.jpg" ); //保存图形状态
Contents.SaveGraphicsState(); //将坐标原点平移到图片的中心
Contents.Translate( 3 . 75 , 5 . 0 ); //调整图像大小并保持纵横比
PdfRectangle NewSize = Image1.ImageSizePosition( 1 . 75 , 1 . 5 , ContentAlignment.MiddleCenter); //剪切路径
Contents.DrawOval(NewSize.Left, NewSize.Bottom, NewSize.Width, NewSize.Height, PaintOp.ClipPathEor); //绘制图像
Contents.DrawImage(Image1, NewSize.Left, NewSize.Bottom, NewSize.Width, NewSize.Height); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.10. 绘制饼图
该DrawChart
方法是定义图表并将其绘制到 PDF 文档的示例。
//绘制图表
private void DrawChart()
{
//保存图形状态
Contents.SaveGraphicsState(); //创建图表
Chart PieChart = PdfChart.CreateChart(Document, 1 . 8 , 1 . 5 , 300 . 0 ); //使用 Chart 对象创建 PdfChart 对象
PdfChart PiePdfChart = new PdfChart(Document, PieChart);
PiePdfChart.SaveAs = SaveImageAs.IndexedImage; //确保我们有高质量的图像
PieChart.AntiAliasing = AntiAliasingStyles.None; // .所有; //设置颜色
PieChart.BackColor = Color.FromArgb( 220 , 220 , 255 );
PieChart.Palette = ChartColorPalette.BrightPastel; //默认字体
Font DefaultFont = PiePdfChart.CreateFont( " Verdana" , FontStyle.Regular, 0 . 05 , FontSizeUnit.UserUnit);
Font TitleFont = PiePdfChart.CreateFont( " Verdana" , FontStyle.Bold, 0 . 07 , FontSizeUnit.UserUnit); //标题(字体大小为 0.25 英寸)
Title Title1 = new Title( "饼图示例" , Docking.Top, TitleFont, Color.Purple);
PieChart.Titles.Add(Title1); //说明
图例Legend1 =新图例();
PieChart.Legends.Add(Legend1);
Legend1.BackColor = Color.FromArgb( 230 , 230 , 255 );
Legend1.Docking = Docking.Bottom;
Legend1.Font = DefaultFont; //图表区域
ChartArea ChartArea1 = new ChartArea();
PieChart.ChartAreas.Add(ChartArea1); //图表区域背景颜色
ChartArea1.BackColor = Color.FromArgb( 255 , 200 , 255 ); //系列 1
系列系列 1 =新系列 ();
PieChart.Series.Add(Series1);
Series1.ChartType = SeriesChartType.Pie;
Series1.Font = DefaultFont;
Series1.IsValueShownAsLabel = true ;
Series1.LabelFormat = " {0} %" ; //系列值
Series1.Points.Add( 22 . 0 );
Series1.Points[0].LegendText = "苹果" ;
Series1.Points.Add( 27 . 0 );
Series1.Points[1].LegendText = "香蕉" ;
Series1.Points.Add( 33 . 0 );
Series1.Points[2].LegendText = "橙色" ;
Series1.Points.Add( 18 . 0 );
Series1.Points[3].LegendText = "葡萄" ; Contents.DrawChart(PiePdfChart, 5 . 6 , 5 . 0 ); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.11. 绘制文本框
该DrawTextBox
方法是使用TextBox
该类的一个示例。本TextBox
类格式文本,以适应列中。可以使用多种字体样式和大小来绘制文本。
//绘制一个文本框的例子
private void DrawTextBox()
{
//保存图形状态
Contents.SaveGraphicsState(); //将原点转换为 PosX=1.1" 和 PosY=1.1" 这是文本框示例的左下角
Contents.Translate( 1 . 1 , 1 . 1 ); //定义常量
//框宽 3.25"
//框高为 3.65"
//正常字体大小为 9.0 磅。
const double宽度 = 3。15 ;
const double高度 = 3。65 ;
const double FontSize = 9。0 ; //创建宽度为 3.25" 的文本框对象
//首行缩进 0.25"
TextBox Box = new TextBox(Width, 0 . 25 ); //添加文本到文本框
Box.AddText(ArialNormal, FontSize,
"此区域是显示太长而无法容纳在固定宽度 " +
"区域内的文本的示例。文本显示在右边缘对齐。您定义一个具有所需 " +
"宽度和首行缩进的文本框。你在这个框中添加文本。这个框会将文本分成“ +
”行。每行由文本段组成。对于每个段,你定义字体、字体“ +
”大小、绘图样式和颜色。加载所有内容后文本,程序将绘制格式化文本。\n" );
Box.AddText(TimesNormal, FontSize + 1 . 0 , "多种字体示例:Times New Roman, " );
Box.AddText(Comic, FontSize, " Comic Sans MS, " );
Box.AddText(ArialNormal, FontSize, "正则示例, " );
Box.AddText(ArialBold, FontSize, " bold, " );
Box.AddText(ArialItalic, FontSize, " italic, " );
Box.AddText(ArialBoldItalic, FontSize, "粗体加斜体。" );
Box.AddText(ArialNormal, FontSize - 2 . 0 , " Arial size 7, " );
Box.AddText(ArialNormal, FontSize - 1 . 0 , " size 8, " );
Box.AddText(ArialNormal, FontSize, " size 9, " );
Box.AddText(ArialNormal, FontSize + 1 . 0 , " size 10." );
Box.AddText(ArialNormal, FontSize, DrawStyle.Underline, " Underline, " );
Box.AddText(ArialNormal, FontSize, DrawStyle.Strikeout, " Strikeout. " );
Box.AddText(ArialNormal, FontSize, " 下标 H" );
Box.AddText(ArialNormal, FontSize, DrawStyle.Subscript, " 2" );
Box.AddText(ArialNormal, FontSize, " O. Superscript A" );
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, " 2" );
Box.AddText(ArialNormal, FontSize, " +B" );
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, " 2" );
Box.AddText(ArialNormal, FontSize, " =C" );
Box.AddText(ArialNormal, FontSize, DrawStyle.Superscript, " 2" );
Box.AddText(ArialNormal, FontSize, " \n" );
Box.AddText(Comic, FontSize, Color.Red, " Some color, " );
Box.AddText(Comic, FontSize, Color.Green, " green, " );
Box.AddText(Comic, FontSize, Color.Blue, " blue, " );
Box.AddText(Comic, FontSize, Color.Orange, " orange, " );
Box.AddText(Comic, FontSize, DrawStyle.Underline, Color.Purple, " and Purple.\n" );
Box.AddText(ArialNormal, FontSize, "支持非拉丁字母: " );
Box.AddText(ArialNormal, FontSize, Contents.ReverseString( " עברית " ));
Box.AddText(ArialNormal, FontSize, " АБВГДЕ" );
Box.AddText(ArialNormal, FontSize, " αβγδεζ" ); Box.AddText(ArialNormal, FontSize, " \n" ); //绘制文本框
//文本左边缘为零(注意:原点已转换为 1.1")
//顶部文本基线位于 Height 减去第一行上升处。
//文本绘制仅限于垂直坐标为零.
//要绘制的第一行是第 0 行。
//在每行之后添加额外的 0.015"。
//每段后添加额外的 0.05"
//拉伸所有线条以使框宽度为 3.15" 的右边缘平滑
//绘制完所有线条后,PosY 将设置为框最后一段之后的下一个文本行
double PosY =高度;
Contents.DrawText( 0 . 0 , ref PosY, 0 . 0 , 0 , 0 . 015 , 0 . 05 , TextBoxJustify.FitToWidth, Box); //创建宽度为 3.25" 的文本框对象
//首行无缩进
Box = new TextBox(Width); //像以前一样添加文本。
//没有额外的行间距。
//无右边缘调整
Box.AddText(ArialNormal, FontSize,
"在此区域上方的示例中,文本框的首行缩进设置为 " +
" 0.25 英寸。该段落首行缩进为零且没有右对齐。);
Contents.DrawText( 0 . 0 , ref PosY, 0 . 0 , 0 , 0 . 01 , 0 . 05 , TextBoxJustify.Left, Box); //创建宽度为 2.75 的文本框对象
//第一行悬挂缩进 0.5"
Box = new TextBox(Width - 0 . 5 , -0. 5 ); //添加文字
Box.AddText(ArialNormal, FontSize,
"本段设置首行悬挂缩进 0.5 英寸。" +
"本段左边距为 0.5 英寸。); //绘制文本
//左边缘 0.5"
Contents.DrawText( 0 . 5 , ref PosY, 0 . 0 , 0 , 0 . 01 , 0 . 05 , TextBoxJustify.Left, Box); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
3.12. 画册订购表
该DrawBookOrderForm
方法是订单输入表或发票的示例。它是数据表支持的示例。它演示了PdfTable
,PdfTableCell
和PdfTableStyle
类的使用。
//绘制订单示例
private void DrawBookOrderForm()
{
//定义常量以使代码可读
const double Left = 4 . 35 ;
const double Top = 4。65 ;
const double底部 = 1。1 ;
const double右 = 7。4 ;
const double FontSize = 9。0 ;
const double MarginHor = 0。04 ;
常量 双边距 = 0。04 ;
const double FrameWidth = 0。015 ;
const double GridWidth = 0。01 ; //列宽
double ColWidthPrice = ArialNormal.TextWidth(FontSize, " 9999.99" ) + 2 . 0 * 保证金霍尔;
double ColWidthQty = ArialNormal.TextWidth(FontSize, " Qty" ) + 2。0 * 保证金霍尔;
double ColWidthDesc = Right - Left - FrameWidth - 3 * GridWidth - 2 * ColWidthPrice - ColWidthQty; //定义表格
PdfTable Table = new PdfTable(Page, Contents, ArialNormal, FontSize);
Table.TableArea = new PdfRectangle(Left, Bottom, Right, Top);
Table.SetColumnWidth( new double[] { ColWidthDesc, ColWidthPrice, ColWidthQty, ColWidthPrice }); //定义边框
Table.Borders.SetAllBorders(FrameWidth, GridWidth); // margin
PdfRectangle Margin = new PdfRectangle(MarginHor, MarginVer); //默认标题样式
Table.DefaultHeaderStyle.Margin = Margin;
Table.DefaultHeaderStyle.BackgroundColor = Color.FromArgb( 255 , 196 , 255 );
Table.DefaultHeaderStyle.Alignment = ContentAlignment.MiddleRight; //用于描述的私有标题样式
Table.Header[0].Style = Table.HeaderStyle;
Table.Header[0].Style.Alignment = ContentAlignment.MiddleLeft; //表格标题
Table.Header[0].Value = " Description" ;
Table.Header[1].Value = "价格" ;
Table.Header[2].Value = "数量" ;
Table.Header[3].Value = "总计" ; //默认样式
Table.DefaultCellStyle.Margin = Margin; //描述列样式
Table.Cell[0].Style = Table.CellStyle;
Table.Cell[0].Style.MultiLineText = true ; //数量列样式
Table.Cell[2].Style = Table.CellStyle;
Table.Cell[2].Style.Alignment = ContentAlignment.BottomRight; Table.DefaultCellStyle.Format = " #,##0.00" ;
Table.DefaultCellStyle.Alignment = ContentAlignment.BottomRight; Contents.DrawText(ArialBold, FontSize, 0 . 5 * (Left + Right), Top + MarginVer + Table.DefaultCellStyle.FontDescent,
TextJustify.Center, DrawStyle.Normal, Color.Purple, " PdfTable 支持示例" ); //重置订单总计
double Total = 0 ; //对订单中的所有项目进行循环
// Order 类是此示例
foreach的 atabase 模拟(Order Book in Order.OrderList)
{
Table.Cell[0].Value = Book.Title + " . By: " + Book.Authors;
Table.Cell[1].Value = Book.Price;
Table.Cell[2].Value = Book.Qty;
Table.Cell[3].Value = Book.Total;
Table.DrawRow(); //累计总数
总计 += Book.Total;
}
Table.Close(); //保存图形状态
Contents.SaveGraphicsState(); //表格线宽 0.01"
Contents.SetLineWidth(FrameWidth);
Contents.SetLineCap(PdfLineCap.Square); //得出税前总额
双[] ColumnPosition = Table.ColumnPosition;
double TotalDesc = ColumnPosition[3] - MarginHor;
double TotalValue = ColumnPosition[4] - MarginHor;
double PosY = Table.RowTopPosition - 2。0 * MarginVer - Table.DefaultCellStyle.FontAscent;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, " Total before tax" );
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString( " # .00 " )); //抽税(加拿大安大略省 HST)
PosY -= Table.DefaultCellStyle.FontLineSpacing;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, " Tax (13%)" );
double Tax = Math.Round( 0 . 13 * Total, 2 , MidpointRounding.AwayFromZero);
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Tax.ToString( " # .00 " )); //绘制总线
PosY -= Table.DefaultCellStyle.FontDescent + 0 . 5 * MarginVer;
Contents.DrawLine(ColumnPosition[3], PosY, ColumnPosition[4], PosY); //绘制最终总
PosY -= Table.DefaultCellStyle.FontAscent + 0。5 * MarginVer;
Contents.DrawText(ArialNormal, FontSize, TotalDesc, PosY, TextJustify.Right, " Total pay " );
总计 += 税;
Contents.DrawText(ArialNormal, FontSize, TotalValue, PosY, TextJustify.Right, Total.ToString( " # .00 " )); PosY -= Table.DefaultCellStyle.FontDescent + MarginVer;
Contents.DrawLine(ColumnPosition[0], Table.RowTopPosition, ColumnPosition[0], PosY);
Contents.DrawLine(ColumnPosition[0], PosY, ColumnPosition[4], PosY);
Contents.DrawLine(ColumnPosition[4], Table.RowTopPosition, ColumnPosition[4], PosY); //恢复图形状态
Contents.RestoreGraphicsState();
返回;
}
4. 安装
集成PdfFileWriter
到您的应用程序需要以下步骤。PdfFileWriter.dll
在您的开发区安装附件。启动 Visual C# 程序并打开您的应用程序。转到解决方案资源管理器,右键单击引用并选择添加引用。选择浏览选项卡并将文件系统导航到PdfFileWriter.dll
. 当您的应用程序发布时,PdfFileWriter.dll
必须包含 。
源代码文档以帮助文件的形式提供 PdfFileWriter.chm
。该文件由 Sandcastle 制作。结果看起来像 Microsoft 文档页面。
如果您想访问PdfFileWriter
项目的源代码,请PdfFileWriter
在您的开发区安装该项目。该PdfFileWriter.dll
会在PdfFileWriter\bin\Release
目录中。
将以下语句添加到使用此库的所有源模块。
use PdfFileWriter;
如果您打算使用图表,则需要添加对: 的引用System.Windows.Forms.Visualization
。在使用的每个源模块中,Chart
您需要添加
use System.Windows.Forms.DataVisualization.Charting;
5. 历史
- 2013/04/01:1.0 版原版。
- 2013/04/09:版本 1.1 支持小数点分隔符不是句点的国家/地区。
- 2013/07/21: Version 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: Version 1.6 (1) CreateFile 方法在文件创建后将 PdfDocument 重置为初始状态。(2) PdfFont 对象正确释放非托管代码资源。
- 2014/08/25:1.7 版支持文档加密、网页链接和二维码。
- 2014/09/12:1.8 版支持书签。
- 2014/10/06:1.9 版支持图表、PrintDocument 和图像元文件。
- 2014/10/12:版本 1.9.1 修复了 ChartExample。使用句点以外的小数分隔符解析区域中的数字字段。
- 2014/12/02:1.10.0 版本支持数据表。添加源代码文档。增加每个文档的最大图像数量。
- 2015/01/12:1.11.0 版本支持视频、声音和附件文件。添加对 Interleave 2 of 5 条码的支持。
- 2015/04/13:1.12.0 版支持重新排序页面并增强数据表边框线支持。
- 2015/05/05:版本 1.13.0 PDF 文档输出到流。PDF 表格插入分页符。图像质量增强。支持标准 128 (RC4) 加密。
- 2015/06/08:版本 1.14.0 支持 PDF 表格中的长文本块或 TextBox。
- 2015/06/09:版本 1.14.1 一行更改为 PdfTableStyle 类的 Copy 方法。
- 2015/06/17:版本1.15.0 文档信息字典。PdfImage 重写。其他图像保存选项。
- 2015/06/18:版本 1.15.1 从解决方案资源管理器中删除未使用的源。
- 2015/07/27:版本 1.16.0 Unicode 支持。提交页面方法。
- 2015/08/07:版本 1.16.1。修复小 (<0.0001) 实数转换为字符串的问题。
- 2015/09/01:版本 1.16.2。修复未定义的字符。所选字体不支持使用的字符。
- 2015/09/22:版本 1.16.3。PdfTable 构造函数使用当前页面大小来计算默认表格区域矩形。当 PdfTable 开始一个新页面时,页面类型和方向取自上一页。
- 2015/09/30:版本 1.16.4 一致使用 IDisposable 接口来释放非托管资源。
- 2016/01/26:1.17.0 版 WPF 图形、透明度、颜色混合、椭圆弧和二次贝塞尔曲线。
- 2016/02/29:1.17.1 版 PdfTable 将在第一列标题是 TextBox 时正确显示标题。
- 2016/03/22:版本 1.17.2 PdfInfo PDF 文档属性将正确显示。
- 2016/04/14:版本 1.17.3 修复了在将小数分隔符定义为非句点(逗号)的区域中非整数字体大小的问题。
- 2016/05/24:版本 1.18.0 命名目的地和创建 PdfFont 资源。
- 2016/06/02:版本 1.18.1 重新应用 1.17.3 修复。
- 2016/06/13:版本 1.19.0 文档链接。对命名目的地的更改。交互式功能支持 TextBox 和 PdfTable。
- 2016/07/27:版本 1.19.1 修复:AddLocationMarker 修复了小数分隔符不是句点的区域。
- 2017/08/31:版本 1.19.2 修复:调试工作目录未保存为项目的一部分
- 2018/06/26:版本 1.19.3 修复 PdfFontFile.BuildLocaTable 方法。长格式缓冲区指针初始化。修复 PdfTableCell 添加 DBNull 的值类型。
- 2018/07/15:版本 1.20.0 通过添加每个模块的像素数来修改 QR 码支持。
- 2019/02/06:版本 1.21.0 支持 PDF417 条码。
- 2019/02/13:版本 1.21.1 修复了 PDF417 条码静区。
- 2019/02/18:1.22.0 版本支持便签。
- 2019/05/26:版本 1.23.0 支持层和对 QRCode 和 Pdf417 条码的更改。
- 2019/06/06:版本 1.24.0 支持图像和注释的图层控制。
- 2019/06/20:版本 1.24.1 支持米作为测量单位。
- 2019/07/15:版本 1.25.0 支持字体集合(主要是 CJK 字体)和非 ASCII 字体名称。
- 2019/07/28:1.26.0 版本支持 XMP 元数据和二维码 ECI 分配编号。
- 2020/09/09:版本 1.27.0 修复了与 PDF417 条码相关的内存不足问题。该问题仅在不寻常的情况下发生。
- 2021/03/31:版本 1.28.0 升级内部文件结构以包括对象流和交叉尊重流。