外观 API
外观 API
A facade 是对核心的简化、面向任务的包装器 Document / Page / Annotation 对象模型。与其自行遍历页面树,你将外观绑定到源 PDF,调用一小组高级方法,并保存结果。每个外观在 Aspose::Pdf::Facades 实现相同的最小合约,由 IFacade (BindPdf, Close),并且当外观产生输出时, ISaveableFacade (Save)。抽象 Facade and SaveableFacade 基类提供默认的 bind/close/save 实现,下面的具体编辑器基于此构建: PdfAnnotationEditor, PdfBookmarkEditor, PdfContentEditor, PdfConverter, PdfExtractor, PdfFileEditor, PdfFileInfo, PdfFileSecurity, PdfFileSignature, PdfFileStamp, PdfPageEditor, PdfXmpMetadata,以及以表单为中心的 FormEditor / FormFieldFacade 对。
Facade 基类和 bind/save 生命周期
IFacade 声明了 BindPdf(srcFile)(也重载以接受内存中的 Document)和 Close()。ISaveableFacade 为写入输出的 facade 添加了 Save(destFile)。Facade 实现了 IFacade,并公开了已绑定的 Document(),以便在 facade 方法未覆盖所需功能时可以回退到核心对象模型;SaveableFacade 使用 Save 实现扩展了 Facade。下面的每个具体编辑器都继承了这种结构,因此相同的 bind → operate → save 模式适用于整个 外观 API。
填写和编辑 AcroForm 字段
FormEditor 在已绑定的文档上添加、删除、重命名和重新定位 AcroForm 字段。AddField(fieldType, fieldName, pageNum, llx, lly, urx, ury) 在指定的页面坐标处创建一个给定 FieldType(Text、CheckBox、Radio、ComboBox、ListBox、PushButton、MultiLineText、Barcode、Signature、Image、Numeric、DateTime)的新字段。RemoveField、RenameField、MoveField 和 SetFieldAttribute 管理已有字段,SetFieldScript / AddFieldScript 附加 JavaScript 动作。SubmitFlag(一个 SubmitFormFlag 值——Fdf、Html、Xfdf、FdfWithComments、XfdfWithComments 或 Pdf)控制提交按钮如何发送表单数据,SetSubmitUrl 设置目标端点。
每个新字段的视觉外观通过 FormEditor.Facade() 控制,它返回一个 FormFieldFacade。其 Font 属性接受一个 FontStyle 值(Helvetica、HelveticaBold、Courier、TimesRoman、Symbol 以及相关变体),TextEncoding 接受一个 EncodingType(Winansi、Macroman、Identity_h、Identity_v、Cp1250、Cp1252、Cp1257),而 BorderStyle / BorderWidth 设置字段的边框。
FormEditor editor;
editor.SrcFileName("template.pdf");
editor.DestFileName("output.pdf");
editor.AddField(FieldType::Text, "FirstName", 1, 100, 700, 300, 720);
editor.SetFieldAttribute("FirstName", AnnotationFlags::Print);
editor.Save();使用 PdfBookmarkEditor 管理大纲
PdfBookmarkEditor 创建、提取、修改和删除 PDF 大纲条目。CreateBookmarks() 将一个 Bookmarks 集合(每个条目是包含 Title、PageNumber、Action、Level、Open 和 ChildItems(用于嵌套大纲)的 Bookmark)写入绑定的文档中。ExtractBookmarks() 将现有大纲读取回为一个 Bookmarks 集合,且 DeleteBookmarks() — 使用可选的 title 过滤器 — 删除条目。ExportBookmarksToXML / ImportBookmarksWithXML 将大纲通过 XML 文件往返传递,而 ExtractBookmarksToHTML / ExportBookmarksToHtml 将大纲渲染为 HTML 页面。
PdfBookmarkEditor editor;
editor.BindPdf("input.pdf");
Bookmarks bookmarks = editor.ExtractBookmarks();
editor.DeleteBookmarks("Draft");
editor.Save("output.pdf");使用 PdfAnnotationEditor 编辑批注
PdfAnnotationEditor 将整个文档的批注扁平化并导入。FlatteningAnnotations() 将批注合并到页面内容流中,使其渲染为静态内容而非交互对象;接受 start/end 页面范围和批注类型的重载限制了该操作。ImportAnnotationsFromXfdf / ImportAnnotationsFromFdf 从外部 FDF/XFDF 文件引入批注,而 DeleteAnnotations()(或针对单一类型的 DeleteAnnotations(annotType))将其移除。
PdfAnnotationEditor editor;
editor.BindPdf("commented.pdf");
editor.FlatteningAnnotations();
editor.Save("flattened.pdf");使用 PdfContentEditor 重写页面内容
PdfContentEditor 编辑已生成页面的内容流,而不是重新构建页面。ReplaceText(srcText, destText) 在整个文档中查找并替换匹配的文本,带有将替换范围限制在单页的重载。ReplaceImage(pageNum, imageNum, fileName) 和 DeleteImage(pageNum, imageNum) 替换或移除已有的图像 XObject。DeleteStampById / HideStampById / ShowStampById / MoveStampById 管理页面上的印章对象(印章的底层内容根据 StampType 枚举要么是 Form 要么是 Image),且 AddDocumentAdditionalAction / AddDocumentAttachment 附加文档级别的 JavaScript 动作和文件附件。
PdfContentEditor editor;
editor.BindPdf("template.pdf");
editor.ReplaceText("{{CustomerName}}", "Jane Doe");
editor.Save("output.pdf");使用 PdfExtractor 提取文本和附件
PdfExtractor 可以使用 BindPdf 进行绑定,也可以直接从已打开的 Document 构造。ExtractText() 随后通过 HasNextPageText() / GetNextPageText(outputFile) 逐页遍历文档。对于嵌入文件,GetAttachNames() 列出存在的附件,而 GetAttachment( outputPath) 将下一个附件写入磁盘:
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/facades/pdf_extractor.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc("attachments.pdf");
Aspose::Pdf::Facades::PdfExtractor extractor(doc);
auto names = extractor.GetAttachNames();
std::cout << "Attachments found: " << names.size() << "\n";
if (!names.empty()) {
extractor.GetAttachment("extracted-attachment.bin");
}
}ExtractImage() / HasNextImage() / GetNextImage(outputFile) 提取嵌入的光栅图像的方式与 GetNextPageText 浏览页面的方式相同。
使用 PdfFileEditor 组装和拆分文件
PdfFileEditor 在文件路径上操作,而不是在绑定的 Document 上,因此每个方法直接接受输入/输出文件名。Concatenate(以及非抛异常的 TryConcatenate)合并两个或多个文件;Append 将一个文件的页面范围插入到另一个文件中;Extract 将页面范围或单页提取到新文件中;Delete 删除页面;以及 SplitFromFirst / SplitToEnd / SplitToPages / SplitToBulks 在页面处、逐页或按固定大小块划分文档。MakeBooklet 和 MakeNUp 重新排列页面以用于小册子或 N-up 打印,ResizeContents / AddMargins / AddPageBreak 调整整个文件的页面几何。大多数操作都有一个以 Try 为前缀的对应版本,在失败时返回 false 而不是抛出异常。
PdfFileEditor editor;
editor.Concatenate("part1.pdf", "part2.pdf", "merged.pdf");
editor.Extract("merged.pdf", 1, 3, "first-three-pages.pdf");使用 PdfConverter 将页面渲染为图像
PdfConverter 将绑定的文档页面渲染为光栅格式。DoConvert() 为迭代准备页面范围(StartPage / EndPage);随后 HasNextImage () / GetNextImage(outputFile) 逐页遍历。SaveAsTIFF 将整个范围写入单个多页 TIFF,并提供分辨率、压缩和 TiffSettings 的重载。RenderingOptions 和 Resolution 控制光栅化质量,而 ImageMergeMode(Vertical、Horizontal、Center)决定在调用方将多个渲染的页面图像合并为一张图像时的合并方式。
PdfConverter converter;
converter.BindPdf("report.pdf");
converter.Resolution(Aspose::Pdf::Devices::Resolution(150));
converter.DoConvert();
while (converter.HasNextImage()) {
converter.GetNextImage("page.png");
}使用 PdfFileSecurity 对文档加密
PdfFileSecurity 绑定源文件并应用或移除加密。EncryptFile(userPassword, ownerPassword, privilege, keySize) 使用 DocumentPrivilege(通过默认构造函数和布尔设置器如 AllowPrint、AllowCopy、AllowModifyContents 构建)和 KeySize(x40、x128 或 x256)进行加密;接受第五个 cipher 参数的重载可显式选择 Algorithm(RC4 或 AES)。DecryptFile( ownerPassword)、ChangePassword 和 SetPrivilege 覆盖其余的密码管理情况,每个都有一个非抛异常的以 Try 为前缀的变体。
PdfFileSecurity security;
security.BindPdf("input.pdf");
DocumentPrivilege privilege;
privilege.AllowPrint(true);
privilege.AllowModifyContents(false);
security.EncryptFile("user-pass", "owner-pass", privilege, KeySize::x256);使用 PdfFileSignature 进行签名和验证
PdfFileSignature 对已绑定的文档进行签名、认证和检查数字签名。Sign(sigName, reason, contact, location, signature) 在现有签名字段上添加新签名;Certify 添加认证签名。GetSignatureNames(onlyEmpty) 和 GetBlankSignatureNames() 将文档的签名字段以 SignatureName 值返回,VerifySignature(sigName) / IsCoversWholeDocument (sigName) 检查有效性和覆盖范围。RemoveSignature 和 RemoveSignatures() 去除已有签名,SetCertificate(pfxFile, password) 在调用 Sign 之前提供签名凭证。
PdfFileSignature signature;
signature.BindPdf("contract.pdf");
signature.SetCertificate("signing-cert.pfx", "cert-password");
bool signed_ok = signature.ContainsSignature();
signature.Save();使用 PdfFileStamp 为页眉、页脚和页码添加印记
PdfFileStamp 在已绑定文件的每一页上覆盖重复内容。AddPageNumber(format) 使用起始编号和可选的显式坐标为页面编号标签加盖印记;AddHeader(text, topMargin) 和 AddFooter(text, bottomMargin) 在指定的边距处添加循环的页眉/页脚文本,并提供左/右边距的重载。KeepSecurity 保留输出文件的任何现有加密,Close() 完成并释放已绑定的文档。
PdfFileStamp stamp;
stamp.InputFile("input.pdf");
stamp.OutputFile("stamped.pdf");
stamp.AddPageNumber("Page # of #", 1);
stamp.Close();使用 PdfFileInfo 读取和写入文档信息
PdfFileInfo 在不打开完整对象模型的情况下读取和重写经典 PDF /Info 字典以及基本的每页几何信息。Author、Title、Subject、Keywords、CreationDate 和 ModDate 为读写属性;Producer 和 GetPdfVersion() 为只读。GetPageWidth、GetPageHeight 和 GetPageRotation 按页码返回每页几何信息,IsEncrypted() / HasOpenPassword() / HasEditPassword() 报告文档的保护状态。SaveNewInfo(outputFile) 将更改写回。
PdfFileInfo info;
info.BindPdf(document);
info.Title("Updated Report Title");
info.SaveNewInfo("output.pdf");使用 PdfPageEditor 重新定位页面
PdfPageEditor 将页面内容整体移动、缩放和旋转。MovePosition(offsetX, offsetY) 在 ProcessPages 选中的页面上平移内容;Zoom 对其进行缩放。Alignment(一个 AlignmentType —— Left、Center 或 Right,均通过对应的静态方法获取)和 VerticalAlignment(一个 VerticalAlignmentType —— Top、Center、Bottom)在 ApplyChanges() 运行后控制内容在目标 PageSize 内的定位方式。GetPageRotation 读取页面当前的旋转角度(以度为单位)。
PdfPageEditor editor;
editor.BindPdf("input.pdf");
editor.Alignment(AlignmentType::Center());
editor.MovePosition(0, -20);
editor.ApplyChanges();使用 PdfXmpMetadata 管理 XMP 元数据
PdfXmpMetadata 是文档 XMP 包的类似映射的外观。Add(key, value)、Remove(key)、Contains(key) / ContainsKey(key),以及 TryGetValue(key, value) 管理单个条目;Keys() 和 Values() 则枚举整个包。RegisterNamespaceURI(prefix, namespaceURI) 在你向其中添加属性之前声明自定义 XMP 命名空间。已知属性名称列在 DefaultMetadataProperties(CreateDate、CreatorTool、Identifier、ModifyDate、Nickname、Thumbnails 等)中,PropertyFlag(ReadOnly、Required、NoExport)描述已注册属性的模式约束。
PdfXmpMetadata xmp;
xmp.BindPdf(document);
xmp.Add("dc:creator", "Report Generator");
xmp.Save("output.pdf");提示和最佳实践
- 每个外观遵循相同的
BindPdf(或接受文件名的构造函数)→ 操作 →Save/Close序列——学习一个外观即可直接迁移到下一个。 - 在处理来自不可信或不可预测来源的文件时,优先使用
PdfFileEditor和PdfFileSecurity上的Try前缀方法——它们在失败时返回false而不是抛出异常。 PdfFileEditor方法接受文件路径,而不是已绑定的Document——在调用Concatenate、Extract或SplitFromFirst之前,你无需自行打开源文件。- 外观包装核心对象模型而不是替换它:
Facade为未被外观方法覆盖的情况公开底层的Document()。 - 在完成对已绑定文档的操作后,调用
Close()(或在支持的情况下让外观超出作用域)以释放底层文件句柄。
常见问题
| 问题 | 原因 | 修复 |
|---|---|---|
Save()/SaveNewInfo() 写入未更改的文件 | BindPdf 从未被调用,或在编辑之后才被调用 | 在进行任何 facade 调用之前,始终绑定源文档 |
EncryptFile 成功,但文档打开时没有密码提示 | userPassword 为空 | 同时提供用户密码和所有者密码,或有意将用户密码留空以实现仅所有者限制 |
PdfFileEditor.Concatenate 在格式错误的输入文件上抛出异常 | AllowConcatenateExceptions 保持默认设置 | 使用 TryConcatenate 并检查返回的 bool,或检查 CorruptedItems() |
使用 FormEditor.AddField 添加的字段渲染时使用了错误的字体 | 在设置 AddField 之前,FormFieldFacade.Font / TextEncoding 未被设定 | 在添加字段之前配置 editor.Facade()(FormFieldFacade) |
PdfFileSignature.Sign 静默失败 | 在签名之前未通过 SetCertificate 提供证书 | 在 Sign 或 Certify 之前调用 SetCertificate(pfxFile, password) |
FAQ
Facade 与核心 Document API 有何区别?
Facade 为单一任务提供了一个小型、面向任务的方法接口——填写表单、合并文件、给页面加盖印章。核心 API(Document、Page、Annotation)提供对每个 PDF 对象的完整访问。通过 Facade 基类公开 Document() 的 Facade 让您在 Facade 方法未覆盖的情况下回退到核心模型。
我需要在每个 Facade 方法之前调用 BindPdf 吗?
是的,对于实现 IFacade 的 Facade —— 必须在任何读取或修改已绑定文档的操作之前运行 BindPdf(或等效的构造函数重载,例如 PdfExtractor(doc))。
可以将 PdfFileEditor 操作链式调用吗?
每个 PdfFileEditor 方法读取自己的输入文件并写入自己的输出文件,因此通过将一个方法的输出文件作为下一个调用的输入文件来链式操作——例如,将 Concatenate 作为 merged.pdf 的输入,然后将 merged.pdf 的输出作为 Extract 的输入。
哪些 Facade 支持非抛异常的错误模式?
PdfFileEditor(TryConcatenate、TryAppend、TryExtract、TrySplitFromFirst以及相关Try*方法)和PdfFileSecurity(TryEncryptFile、TryDecryptFile、TrySetPrivilege、TryChangePassword)都提供以Try为前缀的替代方案,返回bool而不是抛出。
API Reference 摘要
| 类 / 方法 | 描述 |
|---|---|
IFacade | 基础接口:BindPdf,Close |
ISaveableFacade | 向 IFacade 添加 Save(destFile) |
Facade | 默认 IFacade 实现;公开已绑定的 Document() |
SaveableFacade | Facade 加上默认的 Save 实现 |
FormEditor | 添加、删除、重命名以及脚本化 AcroForm 字段 |
FormFieldFacade | 由 FormEditor 添加的字段的字体、编码、边框和对齐方式 |
FieldType | AcroForm 字段种类: Text, CheckBox, Radio, ComboBox, ListBox, PushButton, MultiLineText, Barcode, Signature, Image, Numeric, DateTime |
SubmitFormFlag | 提交按钮数据格式: Fdf, Html, Xfdf, FdfWithComments, XfdfWithComments, Pdf |
DataType | 表单数据的外部数据源格式(FDF, XML, XFDF, PDF, OLEDB, ODBC) |
WordWrapMode | 字段文本换行:Default, ByWords |
PdfBookmarkEditor | 创建、提取、修改和删除 PDF 大纲条目 |
Bookmark / Bookmarks | 单个大纲条目 / 大纲集合,包含 Title、PageNumber、Action、ChildItems |
PdfAnnotationEditor | 在文档中扁平化并导入批注 |
PdfContentEditor | 替换文本/图像并在现有页面内容中管理印章 |
StampType | 印章内容类型:Form, Image |
PdfExtractor | 提取页面文本、图像和文件附件 |
PdfFileEditor | 连接、拆分、提取、调整大小并重新排列跨文件的页面 |
PdfConverter | 将装订文档页面渲染为 TIFF/光栅图像输出 |
ImageMergeMode | 多个渲染页面图像的组合方式:Vertical,Horizontal,Center |
PdfFileSecurity | 对文件进行加密、解密以及更改密码/权限 |
Algorithm | 加密密码算法:RC4,AES |
KeySize | 加密密钥长度: x40, x128, x256 |
PdfFileSignature | 签名、认证、验证并移除数字签名 |
SignatureName | 用于标识签名字段的名称/全名对 |
PdfFileStamp | 为每页添加页码、页眉和页脚 |
PdfFileInfo | 读取/写入 /Info 元数据和每页几何信息 |
PdfPageEditor | 移动、调整大小、旋转并对齐页面内容 |
AlignmentType | 水平对齐:Left、Center、Right |
VerticalAlignmentType | 垂直对齐: Top, Center, Bottom |
AutoRotateMode | 自动页面旋转: None, ClockWise, AntiClockWise |
PositioningMode | 布局定位模式: Legacy, ModernLineSpacing, Current |
PdfXmpMetadata | 读取、写入并枚举文档的 XMP 包 |
DefaultMetadataProperties | 知名的 XMP 属性名称(CreateDate、Identifier、ModifyDate,……) |
PropertyFlag | XMP 架构属性约束:ReadOnly、Required、NoExport |
FontStyle | 由 FormFieldFacade 使用的标准字体:Helvetica、Courier、TimesRoman、Symbol,以及粗体/斜体变体 |
EncodingType | 由 FormFieldFacade 使用的文本编码:Winansi、Macroman、Identity_h、Identity_v、Cp1250、Cp1252、Cp1257 |