简介:PDFtoolkit for D7 是面向 Delphi 7 开发者的 PDF 处理组件包,对应 PDFTK 5.0.0.402 版本,用于在经典 VCL 开发环境中集成 PDF 创建、编辑、合并拆分、水印与权限控制、AcroForm/XFA 表单处理、格式转换、元数据读写、打印控制及文件压缩优化等能力。压缩包共 1728 个文件,约 20.78MB,以 614 个 dcu 编译单元、326 个 pas 源码、310 个 obj 目标文件为主,另含 63 个 dpk 包工程、69 个 res 资源、34 个 inc 头文件及 dproj、bpl、dfm 等工程与组件文件,并附带多套 CJK 字体映射资源,便于直接导入项目引用单元调用 API。已有 591 人学习下载,适合需要在 Delphi 7 中快速落地 PDF 功能的开发者参考源码结构、组件安装与版本兼容性处理。
1. 老 Delphi 7 项目要处理 PDF,为什么我最后选了 pdftoolkit
上周帮一个做票据打印的老项目补功能,客户要求把生成的单据直接导出成 PDF。项目是 Delphi 7 写的,编译环境还停在 2003 年的那套东西上,机器上连 .NET 都没装。我一开始想找个现代库绕过去,结果发现 Delphi 7 的编译器对 Unicode 支持几乎为零,很多新库根本挂不上。翻了一圈,最后落到 pdftoolkit for D7 这个包上——它专门给 Delphi 7 用,不需要额外运行时,纯 VCL 组件,拖到窗体上就能调。
这类老环境装不好会怎样?轻则编译报找不到单元,重则组件面板里能看到但一放就 AV 崩溃,更麻烦的是装完把 IDE 搞坏,连原来的项目都打不开。所以这篇笔记按「环境先列清、再一步步装、最后能验证跑通」的顺序写,适合还在维护 Delphi 7 老项目、需要补 PDF 导出能力的开发者。版本选择、路径配置、装坏了怎么救,我都会写清楚。
2. 装前把环境列清楚:Delphi 7 的版本与路径前提
2.1 确认你的 Delphi 7 是哪个版本
Delphi 7 本身只有一个大版本,但市面上流通的安装包差异很大:有原版光盘镜像、有带 Update Pack 的整合版、还有各种精简版。pdftoolkit for D7 依赖的是标准 VCL 库和 RTL,精简版如果删掉了某些单元,装完就会在编译期报File not found: 'xxx.dcu'。我一般先确认三件事:IDE 主程序版本号、Lib目录是否完整、Bin目录下dcc32.exe能不能正常跑。
打开 Delphi 7,菜单Help → About能看到版本信息。标准版显示的是Delphi 7 Version 7.0 (Build 4.453)这类字样。如果显示的是第三方修改版标识,建议换一个干净的原版安装包再装组件,否则后面排查问题会多一层干扰。
# 在 Delphi 7 安装目录下检查关键文件是否存在 # 假设安装在 C:\Program Files\Borland\Delphi7 dir "C:\Program Files\Borland\Delphi7\Bin\dcc32.exe" dir "C:\Program Files\Borland\Delphi7\Lib\*.dcu" | find /c ".dcu"第一行确认命令行编译器在不在,第二行统计Lib目录下.dcu文件数量。正常完整安装的 Delphi 7,Lib下应该有上千个.dcu。如果数量明显偏少(比如只有几十个),说明是精简版,缺单元的风险很高。这一步不是必须,但能提前排掉一半「装完编译不过」的玄学问题。
2.2 目录规划:别把组件包塞进 IDE 安装目录
很多人图省事,直接把第三方组件解压到Delphi7\Lib或者Delphi7\Bin下面,这是血泪经验里最常见的一个坑。IDE 安装目录下的文件受权限和卸载逻辑管理,一旦组件包和 IDE 自带文件混在一起,后面升级或卸载时根本分不清哪些该删。更糟的是,某些组件包会覆盖同名单元,导致原本能编译的项目突然报错。
我的习惯是单独建一个第三方组件根目录,比如D:\DelphiComponents\,每个包一个子目录。pdftoolkit for D7 解压后放到D:\DelphiComponents\pdftoolkit\下。这样做的另一个好处是,多台机器部署时可以直接拷贝整个目录,路径统一,不用每台机器重新找。
D:\DelphiComponents\ └── pdftoolkit\ ├── Source\ # 源码单元 .pas ├── Lib\ # 编译后的 .dcu(如果有) ├── Demos\ # 示例工程 └── Readme.txt # 版本与安装说明上面是解压后常见的目录结构。不同渠道拿到的包可能略有差异,但核心是Source目录里要有.pas源文件。如果只有.dcu没有源码,安装时就要走「只加库路径」的方式,而不是「编译安装包」的方式,这两种流程后面会分开讲。
2.3 备份 IDE 配置,给自己留后悔药
装任何 Delphi 7 组件之前,我都会先备份两个地方:注册表里的 IDE 配置,以及Delphi7\Bin下的.dsk和.dro文件。组件安装本质上是在改 IDE 的包列表和组件面板注册信息,装坏了最直接的后果就是 IDE 启动报错或者组件面板空白。
# 备份 Delphi 7 的 IDE 注册表项(需要管理员权限运行 cmd) reg export "HKEY_CURRENT_USER\Software\Borland\Delphi\7.0" D:\backup\delphi7_ide.reg # 备份 Bin 目录下的桌面配置 xcopy "C:\Program Files\Borland\Delphi7\Bin\*.dsk" D:\backup\dsk\ /Y xcopy "C:\Program Files\Borland\Delphi7\Bin\*.dro" D:\backup\dro\ /Yreg export把当前用户的 Delphi 7 配置导出成.reg文件,出问题时双击导入就能回滚。.dsk是桌面布局,.dro是对象库配置,这两个文件被组件安装程序改坏的情况不多,但备份成本几乎为零。我见过有人装组件把 IDE 搞到打不开,最后只能重装 Delphi 7,如果提前导出了注册表,恢复只要一分钟。
提示:备份目录不要放在 Delphi 安装目录里面,否则重装 IDE 时可能被一起清掉。
3. 安装 pdftoolkit for D7:从解压到组件面板出现
3.1 解压与目录检查
拿到pdftoolkit for D7.rar之后,先解压到前面规划好的D:\DelphiComponents\pdftoolkit\。解压完不要急着打开 IDE,先看一眼目录里有什么。关键看两点:有没有.dpk或.dpk工程文件(包安装用),有没有Source目录下的.pas文件(编译用)。
# 解压后列出目录内容,确认关键文件类型 dir /s /b D:\DelphiComponents\pdftoolkit\*.pas dir /s /b D:\DelphiComponents\pdftoolkit\*.dpk dir /s /b D:\DelphiComponents\pdftoolkit\*.dcu第一条列出所有 Pascal 源文件,第二条找包工程文件,第三条找预编译单元。如果三条都有输出,说明这个包既提供源码也提供编译好的单元,安装方式比较灵活。如果只有.pas没有.dpk,说明它不是一个设计期包,需要手动把单元加到项目里或者建一个自己的包来编译。
常见做法是优先用源码编译,因为 Delphi 7 的.dcu对编译器版本敏感,别人机器上编译的.dcu拿到你这里不一定能链接通过。源码在手,编译一遍最稳。
3.2 方式一:有 .dpk 包工程的编译安装
如果目录里能找到.dpk文件,这是最省事的方式。用 Delphi 7 打开这个.dpk,IDE 会把它识别为包工程,菜单里会出现Install按钮。
// 典型的包工程文件内容片段(pdftoolkit.dpk) package pdftoolkit; requires rtl, vcl; contains PDFTypes in 'Source\PDFTypes.pas', PDFDocument in 'Source\PDFDocument.pas', PDFCanvas in 'Source\PDFCanvas.pas'; end.requires段声明依赖的运行时包,Delphi 7 下一般是rtl和vcl,这两个是 IDE 自带的,不用额外装。contains段列出包内包含的单元和对应源文件路径。打开.dpk后,先点Compile(不是Build),看消息窗口有没有报错。编译通过后再点Install,IDE 会把包注册到组件面板。
安装成功后,组件面板上会出现一个新的页签,名字通常是包名或者PDF之类。如果编译通过但Install按钮是灰的,说明当前打开的不是设计期包,或者包的{$DESIGNONLY}指令缺失。这种情况不要硬装,回到目录检查有没有另一个带Dcl前缀的包工程。
3.3 方式二:没有 .dpk 时手动加库路径
有些渠道拿到的包只有.pas源码,没有包工程。这时候不需要编译安装,直接把源码目录加到 IDE 的库路径里,然后在项目里uses对应单元即可。这种方式不注册组件面板,但功能一样能用。
操作路径:Tools → Environment Options → Library → Library path 追加:D:\DelphiComponents\pdftoolkit\Source库路径的作用是告诉编译器去哪里找.pas和.dcu。追加时注意用分号和其他路径隔开,不要覆盖原有内容。改完之后点OK,IDE 会提示是否重新加载,选是。之后新建一个测试工程,在uses里加上PDFDocument,能编译通过就说明路径生效了。
这种方式的好处是不动 IDE 的包列表,风险最低;缺点是组件面板上没有可视化组件,只能代码调用。对于只需要导出 PDF、不需要设计期拖拽的场景,我反而更推荐这种,装坏了影响面小。
3.4 方式三:预编译 .dcu 的库路径配置
如果包里只有.dcu没有.pas,那就只能走库路径方式,但要注意.dcu的编译器版本必须匹配。Delphi 7 的.dcu格式和后续版本不兼容,拿 Delphi 2007 编译的.dcu过来是链接不上的。
# 检查 .dcu 文件是否可读(Delphi 7 的 dcu 头部有版本标识) # 简单办法:直接用 dcc32 编译一个 uses 该单元的测试文件 dcc32 -U"D:\DelphiComponents\pdftoolkit\Lib" TestPDF.dpr-U参数指定单元搜索路径,TestPDF.dpr是一个只uses PDFDocument的最小工程。如果编译报Unit 'PDFDocument' is not a valid unit或者版本相关错误,基本可以判定.dcu不匹配,只能找源码重新编译。这一步是我判断「这个包能不能直接用」的快速手段,比在 IDE 里反复试快得多。
注意:
.dcu不匹配时不要试图用十六进制工具改版本号,链接阶段还会出问题,老老实实找源码。
4. 配置与首次调用:让 PDF 导出真正跑起来
4.1 项目级搜索路径与输出目录
组件装好只是第一步,真正让项目用起来还要配项目级的搜索路径。IDE 全局库路径影响所有工程,项目级路径只影响当前工程,后者更适合把依赖固定在项目里,换机器时不容易漏。
操作路径:Project → Options → Directories/Conditionals Conditional defines: 留空(除非包文档要求) Search path: D:\DelphiComponents\pdftoolkit\Source Output directory: ..\bin Unit output directory: ..\dcuSearch path填源码目录,和全局库路径二选一即可,两个都填不冲突但没必要。Output directory是最终 exe 的输出位置,Unit output directory是.dcu的中间产物位置。把这两个从默认的工程目录挪到独立目录,好处是源码目录保持干净,清理时直接删dcu文件夹就行。
我一般还会在项目里建一个lib子目录,把第三方.dcu拷一份进去,配合相对路径引用。这样整个项目打包发给同事时,不依赖对方机器上装没装组件,只要路径结构一致就能编译。
4.2 最小调用示例:生成一个带文字的 PDF
配置到位后,写一个最小示例验证链路。下面这段代码用 pdftoolkit 的典型接口创建一个单页 PDF,写入一行文字后保存。不同版本的单元名和类名可能略有差异,以包内Readme或示例工程为准,这里展示的是常见调用形态。
program TestPDF; {$APPTYPE CONSOLE} uses SysUtils, PDFDocument, // pdftoolkit 的文档类单元 PDFTypes; // 类型定义单元 var Doc: TPDFDocument; begin Doc := TPDFDocument.Create; try Doc.BeginDocument; // 初始化文档结构 Doc.AddPage(595, 842); // A4 尺寸,单位 point Doc.Canvas.Font.Name := 'SimSun'; // 中文字体,必须用系统已安装字体 Doc.Canvas.Font.Size := 12; Doc.Canvas.TextOut(50, 50, 'Hello PDF'); // 坐标原点在左下角 Doc.SaveToFile('D:\temp\test.pdf'); // 输出路径 finally Doc.Free; end; end.BeginDocument负责写 PDF 文件头和基础对象表,漏掉这一步后面保存会得到空文件。AddPage的两个参数是宽高,单位是 point,A4 对应 595×842,传错单位会导致页面尺寸异常但不报错。TextOut的坐标原点在页面左下角,和 Windows GDI 的左上角原点相反,这是第一次用最容易翻车的地方。SaveToFile会做对象表回填和文件尾写入,路径里的目录必须已存在,否则抛异常。
编译这个示例时,如果报Undeclared identifier: 'TPDFDocument',说明单元名或类名和实际包不一致,去Source目录里 grep 一下类声明。如果报链接错误,回到第 3 章检查库路径和.dcu版本。
4.3 中文字体与编码的两个关键参数
Delphi 7 是 ANSI 环境,字符串默认按系统代码页处理。PDF 内部用的是字体编码,两者对不上就会出现乱码或者方框。pdftoolkit 这类库通常提供字体嵌入和编码映射的开关,配置不对时中文显示是重灾区。
// 中文字体配置的常见写法 Doc.Canvas.Font.Name := 'SimSun'; // 必须是系统字体名,不能用字体文件名 Doc.Canvas.Font.Charset := GB2312_CHARSET; // 与系统代码页一致 Doc.EmbedFonts := True; // 嵌入字体,避免目标机器缺字体 Doc.FontSubset := True; // 子集化,只嵌入用到的字形,减小体积Font.Name填的是字体在系统里的注册名,SimSun对应宋体,填simsun.ttc这种文件名是不认的。Charset要和运行环境的代码页匹配,简体中文系统一般是GB2312_CHARSET。EmbedFonts打开后 PDF 体积会变大,但换机器打开不会掉字;FontSubset只嵌入实际用到的字符,是体积和兼容性的折中。如果导出的是纯英文单据,这两个开关可以关掉,文件能小不少。
提示:嵌入字体涉及字体授权,商用前确认所用字体允许嵌入 PDF。
5. 装坏了怎么救:pdftoolkit 安装常见问题排查
5.1 组件面板出现但一放就 AV 崩溃
现象:包安装成功,组件面板能看到 PDF 相关组件,拖到窗体上 IDE 直接报 Access Violation,有时整个 IDE 退出。
原因:设计期包依赖的运行时单元没有正确加载,或者包编译时链接了错误版本的 RTL。Delphi 7 的包分设计期和运行期,设计期包会requires运行期包,如果运行期包没装或者版本错位,设计期实例化组件就会崩。
解决:先卸载已安装的包(Component → Install Packages里取消勾选),然后确认运行期包是否已编译并安装。如果包只有一个.dpk同时承担设计和运行职责,检查{$DESIGNONLY}指令是否误加。实在定位不了,改用第 3.3 节的库路径方式,不走包安装,绕开设计期加载。
5.2 编译报 File not found 某个 .dcu
现象:项目编译时报Fatal: File not found: 'PDFTypes.dcu',但源文件明明在目录里。
原因:库路径没配对,或者路径里含有中文、空格导致解析失败。Delphi 7 对含空格路径的支持时好时坏,尤其是通过环境变量拼接的路径。
解决:把组件目录挪到纯英文无空格路径下,比如D:\DelphiComponents\,然后在Tools → Environment Options → Library里重新确认路径拼写。改完路径后关闭 IDE 再重开,让路径缓存刷新。如果还不行,用dcc32 -U命令行编译一次,看报错是否一致,命令行能过说明是 IDE 缓存问题。
5.3 导出的 PDF 中文全是方框
现象:PDF 能生成,英文正常,中文显示为方框或问号。
原因:字体没有嵌入,或者Charset与字符串实际编码不匹配。Delphi 7 的string是 ANSI,如果源文件保存成了 UTF-8,字符串常量在编译后就是乱码,PDF 里自然对不上字形。
解决:确认.pas文件以 ANSI 编码保存(IDE 编辑器里File → Save As可以看编码)。打开EmbedFonts,Font.Name用系统注册名。如果目标机器没有该字体,嵌入是唯一可靠的办法。排查时先用一个纯英文示例确认链路通,再逐步加中文,缩小问题范围。
5.4 装完 IDE 启动变慢或报包加载失败
现象:装完组件后每次启动 Delphi 7 都弹「Cannot load package」之类的提示,点掉才能进,或者启动明显变慢。
原因:包被注册到了 IDE 的加载列表,但对应的.bpl文件被移动或删除。Delphi 7 启动时会尝试加载列表里的所有包,找不到就报错。
解决:Component → Install Packages里找到报错的包,取消勾选或移除。如果 IDE 已经进不去,用前面备份的注册表恢复:双击delphi7_ide.reg导入,重启 IDE。这也是为什么第 2.3 节要先备份,装包出问题时有后悔药可吃。
5.5 换机器后项目编译不过
现象:本机正常,拷到另一台装了 Delphi 7 的机器上编译报找不到单元。
原因:依赖的是全局库路径,目标机器没配同样的路径;或者项目里引用了绝对路径。
解决:把组件源码或.dcu拷进项目目录,用相对路径引用,项目级Search path填..\thirdparty\pdftoolkit\Source这种形式。打包时连同dcu输出目录一起带上,目标机器只要 Delphi 7 版本一致就能编译。我现在的习惯是每个用到第三方组件的项目都自带一份依赖,不依赖机器环境。
6. 装完怎么验证:三步确认 pdftoolkit 真的可用
装完不验证等于没装。我一般用三步确认:编译通过、运行产出文件、打开文件内容正确。三步都过,才算这套环境真的跑通。
第一步,命令行编译最小工程。不打开 IDE,直接用dcc32编译第 4.2 节的示例,排除 IDE 缓存和包加载的干扰。
# 在示例工程目录下执行,-U 指向组件源码目录 dcc32 -U"D:\DelphiComponents\pdftoolkit\Source" -E"D:\temp\bin" TestPDF.dpr-U是单元搜索路径,-E指定 exe 输出目录。编译成功会生成TestPDF.exe,失败会打印具体行号和错误码。命令行能过,说明源码和路径没问题,剩下的就是运行期验证。
第二步,运行并检查文件是否生成。执行TestPDF.exe,然后确认输出目录下有test.pdf,且文件大小不为 0。
D:\temp\bin\TestPDF.exe dir D:\temp\test.pdf文件大小为 0 通常意味着SaveToFile之前就异常退出了,或者路径目录不存在导致写入失败。正常一个单页带一行文字的 PDF 在几 KB 到几十 KB 之间,明显偏小要怀疑内容没写进去。
第三步,打开 PDF 检查内容。用任意 PDF 阅读器打开,确认页面尺寸、文字内容、中文显示都正常。我还会额外看一眼文档属性里的生成器信息,确认是 pdftoolkit 写的而不是残留的旧文件。
| 验证项 | 通过标准 | 不通过时先查 |
|---|---|---|
| 命令行编译 | 无错误,生成 exe | 库路径、单元名拼写 |
| 运行产出 | test.pdf 存在且大于 0 字节 | 输出目录权限、SaveToFile 路径 |
| 内容正确 | 文字可见、中文无方框 | 字体嵌入、Charset 设置 |
| 换机打开 | 目标机器显示一致 | 字体是否嵌入 |
这张表我一般会贴在项目Readme里,新同事接手时照着走一遍,能省掉大量「我这里怎么不行」的来回。验证通过后再把组件依赖固化进项目目录,后面部署就稳了。
从那以后我每次装 Delphi 7 第三方组件,都强制先备份注册表、再走命令行编译验证,不给自己留「IDE 里点一点就算装好」的侥幸。这套流程看着多几步,真出问题时省下的时间远不止这几步。希望帮到你。
本文还有配套的精品资源,点击获取