Document¶
featherdoc::Document 是 .docx 文档包的根对象。通常先用它打开或创建
文档,再通过正文、页眉、页脚、分节和检查 API 完成编辑与验证。
常用任务入口¶
已经知道目标工作流时,可以从这里开始:
打开和保存文档:使用
Document(path)、open()、save()和save_as(path)。填充正文模板:使用
body_template(),或直接调用文档级replace_content_control_text_by_tag(...)快捷入口。修改页眉或页脚:使用
header_template(...)、footer_template(...)、section_header_template(...)或section_footer_template(...)。直接编辑正文内容:使用
paragraphs()、tables()、append_table(...)和图片追加方法。修改前检查结构:使用
inspect_sections()、inspect_body_blocks()、list_bookmarks()、list_content_controls()和last_error()。
成功/失败语义¶
返回形态 |
成功含义 |
失败或无变化含义 |
|---|---|---|
|
空错误码表示包操作完成。 |
非空错误码表示操作失败;用 |
|
|
|
|
非零值表示匹配并修改或追加的项目数量。 |
|
|
包含请求的检查结果或设置值。 |
空值表示分节、设置或语义对比结果无法解析。 |
句柄对象 |
返回的 |
使用前应按对应对象页的有效性规则确认目标存在。 |
bool 修改方法的 false 是“未发生修改”的合并信号,不是结构化错误码;
它可能表示目标无效、参数不适用,或目标本来已经处于请求状态。只有某个方法的
文档明确承诺设置 last_error() 时,调用方才能用它区分失败原因,也不能把上一次
操作遗留的错误当作当前 false 的原因。需要可靠区分这些状态时,应先检查
is_open()、句柄 valid() 和目标当前值,再比较修改后的状态。1.13.x 为保持
源码兼容,不批量改变现有 bool 签名;下一次破坏性 API 版本再统一引入结构化
mutation result。
短 C++ 示例¶
featherdoc::Document doc{"template.docx"};
if (doc.open()) return 1;
doc.replace_content_control_text_by_tag("customer", "Ada");
return doc.save_as("filled.docx") ? 1 : 0;
类型化签名导读¶
Document 是文档包级句柄。处理已有文件时先调用 open(),创建新包时
先调用 create_empty(),再使用编辑方法。大多数下标都从 0 开始。路径参数
表示文件系统路径;文本参数会写入解析后的 WordprocessingML 目标。
签名 |
参数 |
返回语义 |
|---|---|---|
|
|
创建句柄;调用 |
|
|
转移文档包状态,使源、目标对象此前返回的句柄全部失效;源对象变为关闭状态, 但仍可复用。 |
|
无。 |
空错误码表示新文档包已初始化。 |
|
无。 |
空错误码表示当前路径已加载。 |
|
|
空错误码表示文档包已写入新路径。 |
|
无。 |
返回正文模板部件句柄;编辑前应检查句柄有效性。 |
|
|
返回该物理部件的页眉模板部件句柄。 |
|
|
返回解析后的分节页眉模板部件句柄。 |
|
|
返回匹配、替换、请求和缺失书签统计。 |
|
|
返回被替换的匹配控件数量; |
|
|
返回新建的正文表格句柄。 |
|
|
分节页面设置写入成功时返回 |
|
|
分节或页面设置无法解析时返回空值。 |
生命周期¶
用于打开、创建、保存文档,并检查当前包状态。
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
无。 |
|
创建空句柄;调用 |
|
|
|
创建绑定到指定路径的文档句柄。 |
|
|
|
转移文档包状态;源对象变为关闭状态并可继续复用。 |
|
无。 |
|
初始化一个新的空 |
|
|
|
替换当前路径,并重置已经加载的包状态。 |
|
无。 |
|
返回当前绑定路径。 |
|
无。 |
|
以严格 OPC 校验加载当前路径对应的 |
|
|
|
按指定策略加载文档;仅在修复历史损坏包时选择 |
|
无。 |
|
返回宽容打开期间发现的包结构问题、严重度、部件名和可修复标记。 |
|
|
|
事务式修复内存中的包结构;遇到不安全或被选项禁用的问题时不做部分修改。 |
|
无。 |
|
将修改保存回当前路径。 |
|
|
|
将修改另存为新路径。 |
|
无。 |
|
判断 |
|
无。 |
|
查看最近一次失败的 |
|
无。 |
|
写入 |
|
无。 |
|
清除“打开时更新域”的设置。 |
|
无。 |
|
检查“打开时更新域”设置;为空表示当前无法读取该设置。 |
路径绑定与 UTF-8¶
文件系统路径由 std::filesystem::path 传入;Windows 内部使用宽字符系统调用,传给
ZIP 层、错误详情和 CLI JSON 的路径统一转换为 UTF-8,因此中文、日文、emoji、空格和
启用长路径后的路径不会经过系统 ANSI code page。源码、文档、CLI stdout/stderr 和
JSON 也统一使用 UTF-8;MSVC 构建保持 /utf-8。
成功 open() 时,FeatherDoc 会把源路径解析为当时工作目录下的绝对 I/O 路径并冻结。
后续懒加载图片、样式、编号、页眉页脚等部件以及 save() 重开源归档时都使用该冻结
路径,即使进程之后改变 current working directory,也不会误读同名文件。为保持调用方
兼容,path() 仍原样返回传入的路径拼写。save_as(relative_path) 则在每次调用时
按当时的 current working directory 解析输出路径;它不会改变 path() 或已冻结的源
归档路径。
保存事务与持久化语义¶
save() 和 save_as() 在目标同目录排他创建唯一临时文件,不使用固定
.tmp/.bak 名称。ZIP 完整 finalize 后,临时文件会先执行用户态 flush 和文件
同步,再通过同文件系统原子替换发布为目标;POSIX 随后同步父目录,Windows 使用
write-through 的替换 API。POSIX 写入期间临时文件保持 0600;替换已有目标时
保留其 mode bits,新目标使用进程 umask 计算后的权限。
错误边界如下:
output_archive_open_failed、条目写入错误、output_archive_finalize_failed、output_file_sync_failed、package_repair_validation_failed和output_replace_failed都发生在替换完成 之前;原目标保持不变。output_directory_sync_failed_after_replace只在原子替换已经成功、但 POSIX 父目录持久化无法确认时返回。此时新目标已经可见,last_error().detail会明确 说明该状态;调用方应重新打开目标核对内容,不能假设旧文件仍然存在。成功返回表示 ZIP finalize、文件同步和平台替换步骤均成功;在支持父目录同步的 平台上也表示目录项同步成功。
保存期裁剪与包修复不再使用 pugixml 无法报告失败的 reset(source) 复制。FeatherDoc
会在隔离 DOM 中逐项检查 node、name、value 和 attribute 分配,完整成功后才发布副本;
clone 或修复 mutation 分配失败会在部分 DOM 替换内存包状态或目标文件前返回
std::errc::not_enough_memory。
所有归档 reader、条目缓冲区、临时输出流和 ZIP writer 均由 RAII guard 持有。原子替换
前发生标准分配失败时,FeatherDoc 会关闭全部归档资源、删除唯一临时文件、保持已有目标
逐字节不变,并允许同一个 Document 实例直接重试。替换后的持久化路径不再构造新的
路径或诊断字符串,因此已经完成的替换不会在随后被误报为分配失败。
打开校验与资源限制¶
无参数 open() 等价于传入默认 document_open_options。默认使用
package_validation_mode::strict,并要求 [Content_Types].xml、根关系、
word/document.xml 和 w:document/w:body 结构有效。需要读取历史损坏包做
修复时,调用方必须显式选择 package_validation_mode::tolerant;宽容模式不会
关闭 ZIP 资源限制,也不会静默修改文档。
XML parser 分配失败属于运行故障,而不是历史包损坏:所有急切加载和懒加载 XML 部件
在两种模式下都必须以 std::errc::not_enough_memory fail closed,不能降级为 tolerant
诊断,也不能静默跳过 Custom XML item。Default/@ContentType 或
Override/@ContentType 缺失、空值或 MIME 语法损坏时,两种模式都会拒绝,因为库
无法安全推断其真实含义。调用方应读取 package_diagnostics(),再显式调用
repair_package(),并使用 save_as() 写入新文件。
tolerant 模式是“检查并显式修复”的安全边界,不是通用的兼容编辑模式。真正缺失的
relationship part 可以由负责该关系的 API 创建;但如果已经存在的
word/_rels/document.xml.rels 或页眉/页脚 .rels 的根节点名称或 package
namespace、Relationship 子节点 namespace 或结构非法,库绝不会隐式重建该关系部件。
校验会拒绝 namespace reset、未知或嵌套元素、缺失的 Id/Type/Target、重复
标识符和非法 TargetMode。元素名称按 expanded QName 匹配,因此
Relationships/Relationship 既支持默认 namespace,也支持绑定到 OPC
relationship namespace 的合法前缀。已有子节点前缀保持不变,新建 relationship 使用根
节点前缀;Id/Type/Target/TargetMode 仍必须是不带前缀的 OPC 属性。
所有已加载的 .rels 部件都会先完成 Markup Compatibility and Extensibility
(MCE)预处理,再执行 OPC schema 校验。该预处理配置只理解 OPC Relationships
namespace,不额外声明任何 markup configuration namespace。mc:AlternateContent
按文档顺序检查 Choice/@Requires,直到找到第一个受支持的 Choice。完整 XML 树都会
接受 namespace well-formedness 与 MCE 语法校验,包括所有 Choice/Fallback wrapper、
指令、Requires 列表,以及随后会被忽略或未选中的内容。只有最终选中的 Choice 或
Fallback 才进入内容语义预处理;被忽略和未选中的内容不会执行其 ProcessContent
语义,也不会强制其 MustUnderstand。外来元素自身的
Ignorable/ProcessContent 声明会在语义阶段参与判断该元素应被丢弃还是解包。被
ProcessContent 选中并解包的外来 wrapper 并非被完整忽略:移除 wrapper 前仍会
执行它自己的 MustUnderstand。未知
mc:MustUnderstand、非法 MCE 语法、旧版
Preserve* 指令和非 ignorable 扩展标记,在 strict 与 tolerant 两种模式中都会以
mce_mismatch 或 invalid_mce_markup fail closed。
未发生修改的来源 relationship entry 仍可按原始字节复制;一旦该关系部件变为 dirty,
FeatherDoc 写出的是已清洗的选中视图,ignorable 内容、未选分支和 MCE 控制属性会被
移除。XML declaration、comment、processing instruction,以及 OPC Relationship
允许的简单文本/CDATA 都会保留,包括合法 UTF-8 中文和其他 Unicode 文本。
任何依赖 relationship 的修改都会
fail closed,并返回 document_errc::invalid_package_structure,包括超链接和图片
关系、singleton part 挂接、分节页眉页脚关系编辑,以及内容控件图片替换。失败发生在
提交相关内容 XML、媒体 entry、Content Types 修改或 dirty 状态之前;后续保存不会用
新关系树覆盖原来的非法 .rels;保存边界还会再次拒绝 dirty 且结构非法的关系 DOM,
内容控件图片操作也不会留下只完成一半的替换结果。
调用方应先检查诊断并执行明确支持的显式修复,再恢复常规编辑流程。
[Content_Types].xml 同样按 expanded QName 匹配。Types、Default 和
Override 可以使用默认 namespace,也可以使用任意正确绑定到 OPC Content Types
namespace 的前缀;修改时会沿用现有根前缀。namespace shadow/reset、未知或嵌套元素、
任何文本或 CDATA(包括纯空白)以及未声明属性都属于结构错误。tolerant 打开会记录
invalid_content_types_root,仍允许检查或不改变该部件的原样另存,但所有依赖
Content Types 的普通修改都会以 invalid_package_structure fail closed,不会扩展
存在歧义的 XML 树。
挂接 settings、numbering 或 styles 单例部件时,会把该 DOM 与
word/_rels/document.xml.rels 的 checked clone 作为同一事务准备。只有 relationship
与对应 Override 都完整创建后,才会发布两个副本、dirty 状态和新部件;准备挂接时
发生分配失败,文档包保持不变,同一个 Document 可以直接重试。现有源包首次挂接
该部件后会立即标记为 dirty,因此随后内容修改即使失败,保存也不会只写 relationship
与 Override 而漏掉新 XML 部件。
主文档、页眉、页脚、样式、编号、设置、脚注、尾注和批注也统一按 expanded QName
解析。transitional WordprocessingML namespace 可以使用默认 namespace,或任意合法的
UTF-8 NCName 前缀,包括中文前缀。加载时,FeatherDoc 会以原子方式把
WordprocessingML 元素名和属性名规范化为内部 w: 拼写,同时保留 namespace 声明、
外来标记,以及 MCE/data-binding QName 等依赖前缀的属性值。常规保存始终会重新序列化
主文档及已加载的页眉/页脚,并写出规范 w: 名称。未修改的懒加载 singleton 部件
(样式、编号、设置、脚注、尾注和批注)仍可按原始字节复制;一旦 dirty,保存会写出
规范形式。显式 xmlns:w 如果绑定到其他
namespace,或出现未绑定/非法 QName、重复 expanded attribute,都会被拒绝,绝不会
冒充 WordprocessingML。主文档根错误时,strict 模式拒绝,tolerant 模式只记录结构
诊断;页眉/页脚在打开时急切加载,因此错误根在两种模式下都会使 open() 失败。
懒加载 singleton 的根会在首次访问时校验,并在两种模式下返回
invalid_package_structure;此时包本身可能已经打开成功。commentsExtended 属于
另一套 schema,不会经过该规范化器。遍历采用迭代实现,并限制为最多 65,536 层、
1,000,000 个元素和 1,000,000 个属性。
公开 archive_limits 聚合体保持原有 5 个可配置字段,默认值分别为:10,000 个
条目、单个 XML 部件 64 MiB、单个二进制部件 256 MiB、总解压量 512 MiB、最大
压缩比 200。业务确有需要时可以调高这些限制,但应保留与输入来源相匹配的上限。
中央目录 64 MiB、单个物理 entry name 511 bytes、全部物理 entry name 合计
8 MiB 是另外三项内部固定安全默认值,会在分配或读取完整中央目录之前生效;它们
不是 archive_limits 的新增字段。
Relationships MCE 清洗还会把临时输出 DOM 限制为最多 1,000,000 个元素、262,144 个
属性,并限制每个元素最多 hoist 4,096 个有效 namespace binding。namespace token
解析、复制、比较、context push/pop、排序和 binding hoist 共用 64 MiB 累计工作预算。
这些内部固定边界
用于阻止 ProcessContent 移除 wrapper 后,把继承的 namespace 声明无限复制到
大量子元素。超过限制时原始 DOM 保持不变,并返回 archive_limit_exceeded;分配失败
统一返回 std::errc::not_enough_memory,tolerant 模式也不得把它降级为包诊断继续读取。
物理 entry 名必须是合法 UTF-8 的相对包路径,且不得包含嵌入 NUL。strict 模式还
要求物理名称采用 OPC 规范 ASCII 形式:非 ASCII UTF-8 字节和空格必须使用大写
%HH 转义。tolerant 模式可以读取历史包中的 raw Unicode 或其他非规范拼写,但
两种模式都会拒绝路径穿越、错误转义、重复项、ASCII 大小写等价项,以及 raw/percent
表示不同但逻辑身份相同的部件。保存时统一写出 percent-encoded 规范物理名称,因此
中文、日文、emoji 等 Unicode 逻辑部件名不依赖具体 ZIP 实现的 raw-name 行为。
内部 OPC relationship target 以来源部件为基准,直接按 UTF-8 package path 解析,
不经过主机文件系统 code page 转换。
Package PartName 使用 RFC 3986 pchar 字符集合,并额外遵守 OPC 段规则:不得有
空段或全点段,段不能以点结尾,也不能同时存在“给一个名称追加路径段即可得到另一个
名称”的两个部件。编码后的 #、?``(``%23、%3F)以及字面量冒号仍是
合法名称。Content Types 中的 Override PartName 和 Default 扩展名按 ASCII
大小写无关身份比较,逻辑重复声明会 fail closed。Default/@Extension 遵守 OPC
ST_Extension 词法;Unicode 扩展名必须使用 UTF-8 %HH 字节,不能直接写 raw
非 ASCII XML 文本。
内部 metadata 限制不会扩展 archive_limits 或 Document。新增的包校验与
relationship bookkeeping 通过现有 opaque handle-lifetime state 持有的 sidecar 保存,
因此 Document 继续维持 1.13 对象布局,移动构造和移动赋值也继续保持
noexcept。原有五参数 archive_limits 聚合初始化及依赖 1.13 Document 布局
的代码,仍保持原来的源码与二进制字段映射。
每次懒加载重新打开源包时,都会先复验当前整个包的 entry 数、单项/总量、压缩比、
UTF-8 路径、规范形式和唯一性;随后再依据关系与内容语义对选中的 XML 部件应用
XML 限制,而不是只看扩展名。save()/save_as() 在复制保留 entry 前也会执行
同样的全源包复验。reader 关闭失败会返回 archive_close_failed,且发生在提交
懒加载结果或替换保存目标之前。
open() 还会为每个 ZIP entry 保存有顺序、只含 metadata 的源包指纹:物理名称、
规范名称、逻辑身份、CRC32、压缩/解压大小和目录标记。懒加载和保存时复制来源 entry
都会把重新打开的包与该快照精确比较。entry 修改、新增、删除或调序通常会改变一个或
多个已记录的指纹字段;只要这些字段存在差异,就会在混用旧 DOM 与新包内容之前返回
source_archive_changed。save() 覆盖自身源路径
时,会在原子替换前立即再比较一次,并用 open() 当时的原始限制重新打开已 finalize
的输出;只有替换成功后才刷新快照。输出一旦超过原始限制,会在 FeatherDoc 替换源路径
之前拒绝替换。
源路径身份遵循目录项语义:Windows 会解析大小写、8.3 与 Win32 别名,同时尊重启用
大小写敏感的目录;POSIX 会解析带符号链接的父目录。两个平台都不会把不同 hard-link
名称合并,因为原子替换发布的是单个目录项,而不是同一文件对象的全部链接。
该指纹用于一致性保护,不是身份认证或安全哈希:ZIP CRC32 和中央目录 metadata 都不 提供密码学完整性证明。最终检查基于路径,并不会锁住“关闭检查句柄到执行原子替换”间 的极短窗口;需要多写入者协同时,调用方必须提供外部文件锁或更高层版本协议。
显式包修复¶
默认修复策略只处理能够确定恢复且不会覆盖未知元数据的问题:在合法
w:document 下补建 w:body,补建缺失的根关系或主文档关系,以及补建缺失的
[Content_Types].xml 或修正主文档 MIME。已有 XML 损坏、根节点/namespace
错误、重复主文档声明和 external 主文档关系会返回
package_repair_not_possible,不会先修改其他部件。
修复成功后,save()/save_as() 会先把结果写入同目录临时文件,再用 strict
模式重新打开该临时包;复验失败返回 package_repair_validation_failed,原目标
保持不变。CLI 可使用 inspect-package <input.docx> --json 查看诊断,使用
repair-package <input.docx> --output <repaired.docx> --json 安全地另存修复结果。
句柄失效规则¶
Paragraph、Run、Table、TableRow、TableCell 和
TemplatePart 等对象是指向当前 DOM 的受跟踪非拥有句柄。句柄同时记录包级
generation 和节点级 epoch;因此它不会延长 Document 生命周期,也不会在
DOM 已重置或节点已删除后继续解引用悬空的 pugixml 节点。
set_path(...)、open(...)和create_empty()会重置整个包,因此使 该Document先前返回的全部 XML 句柄失效。移动构造和移动赋值会使源对象此前返回的句柄失效;移动赋值还会使目标对象旧状态 返回的句柄失效。移动后的源
Document处于关闭状态,可以重新设置路径、打开 文档或调用create_empty()。成功且实际发生修改的
repair_package(...)会替换被修复的 DOM,因此也必须 重新获取此前保存的 XML-backed 句柄。删除节点会使该节点及其后代句柄失效。
Paragraph::set_text(...)和TableCell::set_text(...)会先构建完整替换内容。 失败时原 XML 和全部句柄保持不变;成功时段落或单元格自身及其祖先句柄保持有效, 但被替换的旧段落/run 子句柄失效。Run::set_text(...)成功后该Run句柄仍 有效。段落/run/表格追加与插入失败时不会留下空占位节点。表格插入、行列修改、合并与取消合并会统一准备
tblGrid、单元格属性和待删除 子树。失败时整个表格及句柄保持不变;成功时仅被删除或被替换子树上的句柄失效, 未删除的表格、行、单元格和兄弟子树句柄继续有效。fill_bookmarks(...)和apply_bookmark_block_visibility(...)以整个 bindings 列表为一个事务。任一绑定重复、非法、结构损坏或分配失败时,早先绑定不会被发布, 原 XML、错误详情和句柄保持不变;成功时仅被替换或删除范围内的句柄失效。脚注、尾注、批注及修订 mutation 会把正文/相关 story、relationship、Content Types、 review sidecar 和 dirty 状态作为一个事务准备。分配失败返回
std::errc::not_enough_memory,不会发布部分包状态或推进句柄 epoch。成功时,已发布 正文、页眉或页脚 story 中的旧句柄失效,调用方必须从Document重新获取;未发布 story 的句柄继续有效。成功执行
remove_header_part(...)或remove_footer_part(...)会统一发布 分节引用清理并销毁一个物理 XML 部件。由于TemplatePart在文档 generation 范围内跟踪该部件,本操作会使该文档此前返回的全部 XML-backed 句柄失效;被拒绝 或失败的删除不会推进 generation,现有句柄保持有效。move_section(...)会先在隔离副本中准备新的正文顺序。失败时正文、settings 元数据及全部现有句柄保持不变;成功时正文句柄失效,不相关的页眉、页脚句柄仍有效。append_section(...)、insert_section(...)和remove_section(...)同样先在隔离副本中准备正文结构修改。失败时已发布正文和全部句柄保持不变;成功时 正文句柄失效,已加载的页眉、页脚句柄仍有效。set_section_page_setup(...)以及非结构性的分节引用创建、绑定、复制或移除, 只发布完整准备好的w:sectPr。失败时全部状态和句柄保持不变;对结构正常的包, 成功后正文和相关部件句柄仍有效。若 tolerant 包中已有错误的xmlns:r绑定,且 操作必须修复该绑定,则可能回退为整份 document 发布,此时正文句柄会失效。move_header_part(...)和move_footer_part(...)会在隔离副本中准备 relationship 顺序,并在发布阶段以不分配的方式调整所有权顺序;无论失败还是成功,现有正文及 相关部件句柄都保持有效。替换一个已解析且已存在的页眉/页脚部件文本采用事务式发布。分配失败时该部件及全部 现有句柄保持不变;成功时只有目标部件子树中的句柄失效,正文和其他 story 的句柄 仍有效。若目标物理部件尚不存在,操作所需的 relationship 和 Content Types 也会 作为一个事务准备;对结构正常的包,先前返回的句柄仍保持有效。
sync_content_controls_from_custom_xml()会把正文及全部已加载页眉、页脚作为一次 事务处理。分配失败时,已发布 DOM、未保存编辑和现有句柄均保持不变;成功同步至少 一个内容控件时才统一发布隔离副本,并使全部 XML-backed 句柄失效;同步数量为零时 不会使句柄失效。rename_style(...)、merge_style(...)、干净且非空的apply_style_refactor(...)批处理,以及成功执行且实际修改文档的restore_style_refactor(...),都会把样式、正文、页眉页脚及样式挂接所需的包部件 作为一个事务统一发布。分配失败时,完整的已发布 DOM、dirty 状态和现有句柄均保持 不变;apply_style_refactor(...)的后续操作失败时不会留下此前操作的修改。被拒绝 的 restore 条目自身不发生修改,但同一 restore 结果中的其他有效条目仍可成功应用。 任一成功修改都会使全部 XML-backed 句柄失效,必须从Document重新获取。表格、段落、内容控件或模板部件的结构重建,会使被替换子树上的句柄失效。
Paragraph、Run、Table、TableRow 和 TableCell 可通过
valid() 检查;TemplatePart 使用显式 bool 转换检查。失效句柄的读取
返回空结果,修改返回 false 或空句柄,不会访问已释放内存。除非上文明确说明
某个操作会推进整个文档 generation,否则未被删除的兄弟子树保持有效。完成上述
操作后,应从 Document 或仍有效的父级入口重新获取需要继续使用的句柄。
破坏性 API 迁移说明¶
旧版允许调用方用两个 pugi::xml_node 直接构造 Paragraph、Run、
Table、TableRow 或 TableCell,也公开了 set_parent /
set_current。这些入口无法携带生命周期信息,现已彻底删除。调用方应只从
Document、TemplatePart 或父级句柄获取子句柄;公开 API 不再要求业务
代码直接依赖 pugixml DOM。
模板部件入口¶
当同一类操作需要作用在正文、页眉或页脚上时,优先使用模板部件入口。
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
无。 |
|
通过模板部件 API 访问正文。 |
|
|
|
按物理页眉部件下标访问页眉。 |
|
|
|
按物理页脚部件下标访问页脚。 |
|
|
|
访问某个分节和引用类型解析后的页眉。 |
|
|
|
访问某个分节和引用类型解析后的页脚。 |
分节与检查¶
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
|
|
在文档末尾追加分节。 |
|
|
|
在指定分节前插入新分节。 |
|
|
|
删除指定分节。 |
|
|
|
在不重建整篇文档的情况下调整分节顺序。 |
|
无。 |
|
返回分节数量。 |
|
无。 |
|
返回物理页眉/页脚部件数量。 |
|
无。 |
|
返回分节、页眉和页脚检查结果。 |
|
无。 |
|
返回每个物理关联部件,以及引用它的分节和引用类型。 |
|
|
|
检查单个分节;为空表示目标分节不可用。 |
|
|
|
读取页面尺寸、页边距、方向等页面设置。 |
|
|
|
将页面设置应用到指定分节。 |
|
|
|
替换指定分节解析后的页眉文本。 |
|
|
|
替换指定分节解析后的页脚文本。 |
|
|
|
只移除分节引用,不删除物理页眉部件。 |
|
|
|
只移除页脚引用,不删除物理页脚部件。 |
|
无。 |
|
检查正文中段落和表格的顺序。 |
|
|
|
检查正文段落,返回原始编号 ID,并可选择解析编号定义元数据。 |
|
|
|
比较两个文档的语义内容差异。 |
paragraph_inspection_options::resolve_numbering_metadata 默认为 true。
启用时,段落检查会把 numId 解析到编号定义;源包重新打开或编号查找失败时,通过
last_error() 原样返回错误,不会交付只填充了一部分的结果。只需要原始 num_id
和 level,且不希望触发编号部件解析时,可将其设为 false。TemplatePart
也通过 inspect_paragraphs_with_options(options) 和
inspect_paragraph_with_options(index, options) 为正文、页眉和页脚部件提供相同
选项。独立的 *_with_options 名称可避免形成重载,从而保证已有代码对原
inspect_paragraphs 或 inspect_paragraph 成员函数取址时仍保持源码兼容。
模板填充快捷入口¶
这些方法直接从 Document 操作。常见模板填充场景不必先取得
TemplatePart。
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
|
|
替换匹配书签文本,并返回替换数量。 |
|
|
|
批量填充书签,并报告 requested、matched、replaced 和缺失书签。 |
|
|
|
不额外构造容器时填充少量书签。 |
|
|
|
填充前检查可用书签槽位。 |
|
|
|
替换匹配内容控件,并返回替换数量。 |
|
|
|
按 alias/title 填充内容控件。 |
|
无。 |
|
填充前检查内容控件 tag、alias、锁定状态和数据绑定信息。 |
|
|
|
修改文档前定位要填充的内容控件。 |
|
|
|
将匹配内容控件替换为生成段落。 |
|
|
|
在周围表格上下文中将匹配内容控件替换为表格行。 |
|
|
|
将匹配内容控件替换为生成表格。 |
|
|
|
将匹配内容控件替换为图片。 |
|
|
|
将匹配内容控件替换为指定尺寸图片。 |
正文、表格和图片¶
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
无。 |
|
返回正文段落迭代/编辑入口。 |
|
无。 |
|
返回正文表格迭代/编辑入口。 |
|
|
|
追加表格并返回新建表格句柄。 |
|
|
|
按图片自然尺寸追加行内图片。 |
|
|
|
按指定尺寸追加行内图片。 |
|
|
|
追加浮动图片。 |
|
|
|
追加指定尺寸的浮动图片。 |
批注、修订和链接¶
详细能力在对应对象页中展开;这里列出 Document 级常用入口。
方法 |
参数 |
返回值 |
用途 |
|---|---|---|---|
|
|
|
添加批注;成功返回 |
|
|
|
给段落内精确文本范围添加批注。 |
|
起止段落下标、文本偏移、批注正文和可选元数据。 |
|
给跨段落文本范围添加批注。 |
|
无。 |
|
检查修订记录。 |
|
|
|
接受或拒绝单条修订。 |
|
|
|
追加脚注。 |
|
无。 |
|
编辑前检查超链接文本和目标。 |
|
|
|
在正文追加超链接。 |
|
|
|
替换已有超链接。 |
相关 API 家族¶
Document 根对象还暴露以下公开 API 家族。完整方法集和示例请进入对应专题页:
分节和页面设置 API:分节段落、页眉页脚分配、物理页眉页脚部件删除和页面设置。
字段、链接和审阅 API:批注、批注回复、已解决状态、脚注、尾注、超链接和修订操作。
TemplatePart:模板校验、schema 扫描、模板上架、自定义 XML 同步和内容控件表单状态。
图片 API:行内/浮动图片列表、提取、替换和删除。
Paragraph 和 Run 与 Table、TableRow 和 TableCell:从
Document返回的段落、run、表格、行和单元格编辑入口。
示例¶
打开模板、填充内容控件并保存:
featherdoc::Document doc{"template.docx"};
if (doc.open()) {
return 1;
}
doc.body_template().replace_content_control_text_by_tag("customer", "Ada");
return doc.save_as("filled.docx") ? 1 : 0;
直接从 Document 填充,并读取失败诊断:
featherdoc::Document doc{"template.docx"};
if (auto error = doc.open()) {
std::cerr << doc.last_error().detail << '\n';
return 1;
}
const auto replaced =
doc.replace_content_control_text_by_tag("customer", "Ada");
if (replaced == 0) {
return 1;
}
if (auto error = doc.save_as("filled.docx")) {
std::cerr << doc.last_error().detail << '\n';
return 1;
}
return 0;
创建新文档、追加表格并设置打开时更新域:
featherdoc::Document doc;
if (doc.create_empty()) {
return 1;
}
doc.enable_update_fields_on_open();
auto table = doc.append_table(2, 3);
if (auto customer = table.find_cell(0, 0)) {
customer->set_text("Customer");
}
if (auto status = table.find_cell(0, 1)) {
status->set_text("Status");
}
return doc.save_as("report.docx") ? 1 : 0;