如何在 Python 中使用生成的兼容性模块创建文档
Aspose.PDF FOSS for Python 提供了一个 generated 兼容性子包(aspose_pdf.generated),它镜像了主 API 表面的一个稳定子集——一个包含核心生命周期操作的 Document 类,以及 UnsignedContent/UnsignedContentAbsorber 和 PdfAValidateOptions/PdfAValidationResult。该子包面向希望显式使用此更窄表面的调用者,而不是完整的顶层类,并且其类不会被 import aspose_pdf 自动导入——需要直接从 aspose_pdf.generated.* 导入。此包纯粹基于 Python,可通过下列命令进行安装。
分步指南
步骤 1:安装包
安装 Aspose.PDF FOSS 包:
git clone https://github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python.git
cd Aspose-PDF-FOSS-for-Python
pip install -e .通过导入生成的 Document 并打印确认信息来验证安装:
import aspose_pdf
from aspose_pdf.generated.document import Document
print("aspose-pdf-foss-for-python is ready.")步骤 2:导入必需的类
generated 兼容性类位于 aspose_pdf.generated.document、aspose_pdf.generated.forms 和 aspose_pdf.generated.pdfa 中——请通过子模块显式导入它们:
import aspose_pdf
from aspose_pdf.generated.document import Document
from aspose_pdf.generated.forms import UnsignedContent, UnsignedContentAbsorber
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult步骤 3:创建并加载文档
Document(source) 在提供源时会立即加载;调用不带参数的 Document() 会创建一个空实例,您可以稍后使用 load_from 加载。两者都接受文件路径、bytes 或二进制流:
from aspose_pdf.generated.document import Document
document = Document("report.pdf")
print(f"Loaded {len(document.pages)} page(s)")
empty_doc = Document()
empty_doc.load_from("report.pdf")步骤 7:提取未签名的表单内容
UnsignedContentAbsorber 提取未包含在数字签名中的页面、表单字段和注释。调用 extract() 进行提取,调用 has_extracted() 检查是否已运行,以及调用 get_extracted() 再次获取结果而无需重新提取:
from aspose_pdf.generated.forms import UnsignedContentAbsorber
absorber = UnsignedContentAbsorber()
unsigned = absorber.extract()
print(f"Unsigned pages: {len(unsigned.pages)}")
print(f"Unsigned form fields: {len(unsigned.form_fields)}")
if absorber.has_extracted():
same_result = absorber.get_extracted()步骤 8:手动构建 UnsignedContent 容器
UnsignedContent 也是一个普通容器,您可以使用 add_page、add_form_field 和 add_annotation 手动填充——每个都有对应的 remove_* 方法,reset() 可一次性清除这三类集合:
from aspose_pdf.generated.forms import UnsignedContent
content = UnsignedContent()
content.add_page("page-1")
content.add_annotation("signature-placeholder")
print(content) # UnsignedContent(pages=1, form_fields=0, annotations=1)
content.remove_annotation("signature-placeholder")
content.reset()步骤 9:配置并运行 PDF/A 验证
PdfAValidateOptions 收集验证运行的输入和设置。add_input(source) 注册一个输入,set_option(key, value) 存储一个命名选项,get_options() 返回已存储选项的副本。PdfAValidationResult 保存结果 — add_error(message) 将结果标记为无效并追加到 errors,to_dict() 将 is_valid 和 errors 渲染为普通字典:
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult
options = PdfAValidateOptions()
options.add_input("report.pdf")
options.set_option("pdfa_version", "1b")
print(options.get_options())
result = PdfAValidationResult()
result.add_error("Font 'Arial' is not embedded")
print(result.is_valid) # False
print(result.to_dict())常见问题及解决方案
ImportError or AttributeError 访问时 aspose_pdf.generated
子包 generated 未由 import aspose_pdf 重新导出 — 请从其特定子模块导入每个类,例如 from aspose_pdf.generated.document import Document,而不要指望在普通的 import aspose_pdf 之后 aspose_pdf.generated.Document 能工作。
混淆生成的 Document 与主要的 aspose_pdf.Document
aspose_pdf.Document(由 import aspose_pdf 重新导出的顶层类)具有更大的接口 — 它添加了诸如 validate_pdfa、iter_pages 和 redact_text 等方法,而 aspose_pdf.generated.document.Document 并未实现这些方法。如果在生成的 Document 上缺少某个方法,请检查它是否属于顶层的 Document 类。
save() raises AsposePdfException: Cannot save a disposed document
close()/dispose() 永久释放文档的内部状态 — 被处理的 Document 之后无法保存、优化或修复。请在调用 close() 之前完成所有剩余操作,或使用全新的 Document(...) 调用从源重新加载。
change_passwords raises PdfSecurityException: Document is not encrypted
change_passwords 仅在文档已加密的情况下旋转密码。请先调用 encrypt(password),或在尝试更改密码前检查 document.is_encrypted。
PdfAValidationResult.add_error raises TypeError
add_error 需要一个 str 参数。在将异常对象或其他错误详情传递给 add_error 之前,将其转换为字符串 (str(error))。
常见问题
为什么 aspose_pdf.generated 会与主 aspose_pdf.Document 并存?
它镜像了 Aspose.PDF API 的一个更窄且稳定的子集,用于针对该简化表面的代码。对于不特别需要此兼容子集的新代码,通常应使用顶层的 aspose_pdf.Document,它支持更多操作(PDF/A 转换、页面迭代、文本编辑等)。
UnsignedContentAbsorber.extract() 是否接受 Document 进行扫描?
extract() 接受位置参数和关键字参数,用于填充返回的 UnsignedContent 的 pages、form_fields 和 annotations 集合——将你希望表示的集合以关键字参数形式传入(pages=、form_fields=、annotations=)。
如果在提取任何内容之前对 UnsignedContentAbsorber 调用 reset(),会发生什么?
它会清除之前提取的任何结果。随后 get_extracted() 返回 None,并且 has_extracted() 返回 False,直到再次调用 extract()。
可以多次调用 PdfAValidateOptions.add_input 吗?
是的——每次调用都会向 inputs 列表追加另一条目,并返回 self,因此可以链式调用:options.add_input("a.pdf").add_input("b.pdf")。
在生成的 Document 上,close() 与 dispose() 有所不同吗?
No — close() 是一个直接别名,它以相同的参数调用 dispose();任意名称都会释放文档的资源。