ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

pypdf 常量与枚举全解析:从 AnnotationFlag 到 UserAccessPermissions 的 PDF 字典键与位标志指南

2026/9/16 4:37:26 拓冰建站 浏览量
pypdf 常量与枚举全解析:从 AnnotationFlag 到 UserAccessPermissions 的 PDF 字典键与位标志指南 pypdf 常量与枚举全解析从 AnnotationFlag 到 UserAccessPermissions 的 PDF 字典键与位标志指南【免费下载链接】pypdfA pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files项目地址: https://gitcode.com/GitHub_Trending/py/pypdf导读PDF 文件本质上是一系列字典Dictionary与流的集合其中大量键值以/Type、/MediaBox、/Ff这类带斜杠的魔法字符串形式存在直接手写极易出错且难以阅读。pypdf 在 pypdf/constants.py 中集中定义了这些键名常量、枚举与位标志为读写 PDF 提供了类型安全的编程接口。本文以 docs/modules/constants.rst 中正式公开文档化的五个类为核心——AnnotationFlag、ImageType、PageLabelStyle、UserAccessPermissions与FieldDictionaryAttributes逐一讲解其取值含义、对应 PDF 规范出处并结合PdfWriter、PdfReader与注解模块的源码说明实际调用方式。读完本文你将能够用枚举而不是裸字符串来设置页面标签、读取加密文档权限、过滤图片提取类型、配置表单字段标志位。constants 模块的定位让 PDF 魔法字符串可读、可查、可校验打开 pypdf/constants.py 的第一行注释即可看到它的使命Various constants, enums, and flags to aid readability.各种用于提升可读性的常量、枚举与标志位。该模块把 PDF 1.7 与 ISO 32000-2PDF 2.0规范中散落在各章节的键名和位定义收拢为几十个类并按用途分类字典键常量类CatalogAttributes文档目录、PageAttributes/PagesAttributes页面树、TrailerKeystrailer 字典、Resources资源字典、StreamAttributes流字典、ImageAttributes图像字典、DocumentInformationAttributes文档信息等成员值就是 PDF 中的实际键名如/Pages、/Rotate。枚举与位标志类AnnotationFlag注解标志、ImageType图片类型、PageLabelStyle页面标签风格、UserAccessPermissions访问权限、FieldDictionaryAttributes.FfBits表单字段标志等。纯字符串枚举FilterTypes解码过滤器、ColorSpaces、PageLayouts、BorderStyles、FontFlags等。从源码结构看IntFlag用于表示可组合的位标志如注解的隐藏 只读StrEnum用于表示取值互斥的 PDF 名称对象name objectauto()用于自动递增位值。这种设计使调用方可以直接把枚举传给 API由枚举的__str__返回带/的规范字符串。AnnotationFlag注解的可见性与交互行为位标志AnnotationFlag定义于 pypdf/constants.py 的AnnotationFlag类注释明确标注其规范出处为 PDF 规范 §12.5.3 Annotation Flags。它是一个IntFlag枚举各成员的位值与含义如下成员位值含义INVISIBLE1注解不可见除非由NoView等交互动作激活HIDDEN2注解不显示也不打印除非用户主动将其显示PRINT4注解在打印时输出若未设置则打印时不显示NO_ZOOM8页面放大时注解不随之缩放NO_ROTATE16页面旋转时注解不随之旋转NO_VIEW32屏幕上不显示注解但可能打印READ_ONLY64用户不能修改注解且其外观不可由用户交互改变LOCKED128注解内容不可被用户删除或修改TOGGLE_NO_VIEW256点击注解时在NoView与可见之间切换LOCKED_CONTENTS512注解内容Contents条目不可被用户修改由于继承自IntFlag多个标志可以用按位或组合例如一个屏幕隐藏但允许打印且只读的注解可表示为AnnotationFlag.HIDDEN | AnnotationFlag.PRINT | AnnotationFlag.READ_ONLY。源码中的实际调用在 pypdf/annotations/_markup_annotations.py 中构造标注类时通过self.flags AnnotationFlag.PRINT将新注解默认设为可打印。这意味着开发者用 pypdf 添加高亮、下划线等标注后默认即可随文档打印输出若要改变行为可读取并修改注解对象的flags属性后再写回。ImageType图片提取时的类型过滤开关ImageType定义于 pypdf/constants.py 的ImageType类是一个基于IntFlag的枚举配合auto()自动生成位值NONE 0不提取任何图片XOBJECT_IMAGES提取以 XObject 形式嵌入的图片最常见的图片形式INLINE_IMAGES提取内联图片直接写在内容流BI ... ID ... EI之间的图片DRAWING_IMAGES提取由矢量绘图如Do运算符引用的图形对象产生的图片ALL XOBJECT_IMAGES | INLINE_IMAGES | DRAWING_IMAGES全部类型IMAGES ALL为与ObjectDeletionFlag保持命名一致的别名。它已在 pypdf/init.py 中被导入并列入__all__因此可写作from pypdf import ImageType直接使用。典型场景是调用PageObject的图片提取接口时传入该枚举控制提取范围例如只关心页面内联图片时传ImageType.INLINE_IMAGES需要全部时传ImageType.ALL。由于是位标志也可组合为ImageType.XOBJECT_IMAGES | ImageType.INLINE_IMAGES。相关图片解码过程可参考 pypdf/generic/_image_inline.py 与 pypdf/generic/_image_xobject.py。PageLabelStyle页面标签的编号风格PageLabelStyle定义于 pypdf/constants.py 的PageLabelStyle类规范出处为 PDF 1.7 规范的 Table 8.10 与 PDF 2.0 规范的 Table 161。它是一个StrEnum成员对应页面标签编号Page Label的风格成员值编号风格DECIMAL/D十进制阿拉伯数字1, 2, 3…UPPERCASE_ROMAN/R大写罗马数字I, II, III…LOWERCASE_ROMAN/r小写罗马数字i, ii, iii…UPPERCASE_LETTER/A大写字母A–Z26 页后 AA–ZZ依此类推LOWERCASE_LETTER/a小写字母a–z26 页后 aa–zz依此类推实际用法PdfWriter.set_page_label()方法定义于 pypdf/_writer.py直接接受Optional[PageLabelStyle]作为style参数签名与校验逻辑如下def set_page_label( self, page_index_from: int, page_index_to: int, style: Optional[PageLabelStyle] None, prefix: Optional[str] None, start: Optional[int] 0, ) - None:其约束在源码中清晰可见pypdf/_writer.py 对应方法实现处style与prefix至少给出一个否则抛出ValueErrorstyle必须是tuple(PageLabelStyle)中的成员否则抛出ValueError错误信息会列出全部合法值页码索引从 0 开始page_index_from必须 ≥ 0page_index_to必须 ≥page_index_from且小于总页数start若给定则必须 ≥ 1默认 1表示范围内第一页标签的数值起点未被任何范围覆盖的页面默认应用从 1 开始的十进制标签。典型示例为前 3 页设置小写罗马数字并加前缀 Preface-后续页面保持默认十进制from pypdf import PdfWriter from pypdf.constants import PageLabelStyle writer PdfWriter() writer.append(input.pdf) writer.set_page_label(0, 2, stylePageLabelStyle.LOWERCASE_ROMAN, prefixPreface-) writer.write(labeled.pdf)生成的页面标签将以Preface-i、Preface-ii、Preface-iii形式显示实际落盘时写入文档目录的/PageLabels编号树对应CatalogAttributes.PAGE_LABELS /PageLabels。UserAccessPermissions加密文档的用户访问权限UserAccessPermissions定义于 pypdf/constants.py 的UserAccessPermissions类规范出处为 PDF 1.7 规范的 Table 3.20User access permissions与 PDF 2.0 规范的 Table 22。它是一个IntFlag32 个位全部定义其中既有实际权限位也有规范保留位R1、R2、R7、R8、R13–R32。主要权限位非保留成员位值权限含义PRINT4允许打印MODIFY8允许修改文档内容EXTRACT16允许复制或提取文本与图形兼容低版本阅读器ADD_OR_MODIFY32允许添加或修改注释与交互表单字段FILL_FORM_FIELDS256允许填写表单字段即使ADD_OR_MODIFY未设置EXTRACT_TEXT_AND_GRAPHICS512允许无障碍阅读场景下的文本与图形提取ASSEMBLE_DOC1024允许组装文档插入、旋转、删除页面PRINT_TO_REPRESENTATION2048允许以低分辨率表示形式打印其余R1、R2、R7、R8及R13–R32为规范保留位不表示具体权限。配套方法该类提供三个实用的类方法与实例方法源码位于 pypdf/constants.pyto_dict()把当前标志值转换为{print: True, modify: False, ...}形式的可读映射自动跳过保留位from_dict(value)反向把可读映射合并回标志值保留位按规范自动取默认值除R1、R2外的保留位默认为 1即激活若传入映射含未知键则抛出ValueErrorall()返回除R1、R2外所有位均置位的全部权限值即(2**32 - 1) - R1 - R2。读取实际权限PdfReader继承自 pypdf/_doc_common.py提供user_access_permissions属性返回Optional[UserAccessPermissions]未加密时返回None加密时返回UserAccessPermissions(self._encryption.P)即直接由加密字典的/P整数标志构造。使用方式from pypdf import PdfReader reader PdfReader(encrypted.pdf) perms reader.user_access_permissions if perms is not None and UserAccessPermissions.PRINT in perms: print(允许打印) if perms is not None and not (UserAccessPermissions.MODIFY in perms): print(不允许修改内容)注意源码中user_access_permissions属性文档提示应配合are_permissions_valid属性pypdf/_doc_common.py 中对应实现验证权限是否有效因为某些文档可能声明了不合理的权限组合。FieldDictionaryAttributes表单字段字典键与 /Ff 标志位FieldDictionaryAttributes定义于 pypdf/constants.py规范出处为 PDF 1.7 规范的 Table 8.69Entries common to all field dictionaries其类文档自述这里只做了非常局部的记录very partially documented here并明确说明FfBits提供 Table 8.70/8.75/8.77/8.79 中/Ff使用的常量。注意 docs/modules/constants.rst 在生成文档时通过:exclude-members:排除了FT, Parent, Kids, T, TU, TM, V, DV, AA, Opt及两个辅助方法attributes/attributes_dict因此公开文档中主要呈现Ff键与FfBits标志。字段字典常用键对应 PDF 键名FT/FT字段类型终端字段必填、Parent/Parent父字典子字段必填、Kids/Kids子字段数组、T/T字段名、TU/TU替代字段名即界面显示名、TM/TM映射名、Ff/Ff字段标志整数、V/V当前值、DV/DV默认值、AA/AA附加动作字典、Opt/Opt选项数组。FfBits嵌套 IntFlag用于组合/Ff字段标志按适用字段类型分组源码注释标注了对应 PDF 1.7 规范表号位成员适用类型10ReadOnlyTx / Btn / ChTable 8.70 通用11RequiredTx / Btn / Ch通用12NoExportTx / Btn / Ch通用112Multiline文本Tx113Password文本Tx114NoToggleToOff按钮Btn115Radio按钮Btn116Pushbutton按钮Btn117Combo选择Ch118Edit选择Ch119Sort选择Ch120FileSelect文本Tx121MultiSelect文本Tx122DoNotSpellCheckTx / Ch123DoNotScroll文本Tx124Comb文本Tx125RadiosInUnison按钮Btn125RichText文本Tx126CommitOnSelChange选择Ch注意RadiosInUnison与RichText位值相同125这在规范中合法因为二者分别只适用于 Btn 与 Tx 类型同一字段不会同时是按钮和文本。另有独立的FieldFlag类READ_ONLY 1、REQUIRED 2、NO_EXPORT 4作为 Table 8.70 全部字段类型通用标志的简化版适合不需要区分类型细节的快速判断。源码中的使用FieldDictionaryAttributes源码中常以FA别名导入见 pypdf/_doc_common.py 的from .constants import FieldDictionaryAttributes as FA在 pypdf/generic/_data_structures.py表单字段读取与 pypdf/generic/_appearance_stream.py外观流生成中被用于构造和识别字段字典键。此外类方法attributes()返回全部字段键的元组attributes_dict()返回键到可读名称的映射如FA.FT: Field Type可辅助遍历表单字段时做键名归一化。支撑类的快速索引其余常用常量一览除上述五个重点类外pypdf/constants.py 还定义了大量供内部与高级用户使用的常量以下列出与日常操作最相关的几组完整清单见 docs/modules/constants.rst 与源码Core/TrailerKeys/CatalogAttributes/PagesAttributes/PageAttributes分别对应 PDF 文档结构中的根键/Outlines、/Threads、/Page、/Pages、/Catalog、trailer 键/Size、/Root、/Encrypt、/Info、/ID、文档目录键与页面树键。例如PageAttributes.MEDIABOX /MediaBox是读写页面尺寸的键。FilterTypes与FilterTypeAbbreviations流解码过滤器及其缩写如FlateDecode/Fl、DCTDecode/DCT是 pypdf/filters.py 解码逻辑的对照表。ImageAttributes与ColorSpaces图像 XObject 的键/Width、/Height、/BitsPerComponent、/ColorSpace与常用颜色空间名称。DocumentInformationAttributes文档信息字典键/Title、/Author、/CreationDate等供 pypdf/_doc_common.py 的DocumentInformation使用。AnnotationDictionaryAttributes/BorderStyles/AFRelationship注解通用字典键、边框样式与关联文件关系类型PDF 2.0 Table 43。FontFlags/OutlineFontFlag字体描述符标志与书签字体样式标志italic 1、bold 2。LzwFilterParameters/CcittFaxDecodeParametersLZW 与 CCITT 传真解码参数键。PageLayouts/TypFitArguments/GoToActionArguments页面布局、视图适配参数/FitH、/FitV等与跳转动作键。兼容性与演进以 CatalogDictionary 的弃用为例常量模块本身也随 pypdf 版本演进CatalogDictionary类是一个演示弃用机制的典型源码位于 pypdf/constants.py。它继承CatalogAttributes但通过自定义元类_CatalogDictionaryMeta在访问任何属性时调用deprecate_with_replacement(CatalogDictionary, CatalogAttributes, 7.0.0)提示在 7.0.0 版本中应以CatalogAttributes取代。这提醒使用者常量类名可能随规范整理而调整优先使用当前文档化名称docs/modules/constants.rst 列出的AnnotationFlag、ImageType、PageLabelStyle、UserAccessPermissions、FieldDictionaryAttributes并在升级 pypdf 后关注弃用警告。使用建议小结优先导入枚举而非手写字符串from pypdf.constants import PageLabelStyle, UserAccessPermissions, ImageType, AnnotationFlag可借助枚举成员校验与 IDE 自动补全降低拼写错误且StrEnum的__str__自动输出规范键名。位标志按位组合AnnotationFlag、UserAccessPermissions、ImageType、FfBits均为IntFlag判断是否允许某权限用UserAccessPermissions.PRINT in perms组合用|清零用 ~。注意默认行为例如注解默认带PRINT标志、未赋标签的页面默认十进制从 1 编号见 pypdf/_writer.py 的set_page_label文档、未加密文档的user_access_permissions为None见 pypdf/_doc_common.py。版本差异部分常量与弃用行为随版本调整如CatalogDictionary→CatalogAttributes升级后留意DeprecationWarning。测试佐证仓库 tests/ 目录下的test_forms.py、test_writer.py、test_encryption.py、test_page.py等测试文件覆盖了表单字段标志、页面标签、加密权限与注解标志的相关路径可作为学习枚举实际效果的参考用例。【免费下载链接】pypdfA pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files项目地址: https://gitcode.com/GitHub_Trending/py/pypdf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考