docx 库字段(Fields)完全指南:SimpleField、公式字段与邮件合并域实战
docx 库字段Fields完全指南SimpleField、公式字段与邮件合并域实战【免费下载链接】docxEasily generate and modify .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.项目地址: https://gitcode.com/GitHub_Trending/do/docx字段Fields是 Word 文档中一段可以随环境或数据动态变化的文本页码、作者名、保存日期、文档属性乃至整个目录都可以通过字段实现。本文以 docx 库官方文档 docs/usage/fields.md 为骨架结合仓库源码与 demo/66-fields.ts 完整示例讲解如何用SimpleField插入字段代码、如何借助缓存值cached value控制初始显示、如何用书签变量编写公式字段以及如何用SimpleMailMergeField为模板文档接入邮件合并。读完你即可在 Node.js 或浏览器环境下生成包含动态文本的.docx文档。什么是字段Fields字段是一段动态文本插入后内容由 Word或其他兼容的文字处理器在打开文档、打印或按 F9 时根据字段代码field code重新计算。最常用的字段是页码与交叉引用也可以插入文档属性例如作者名AUTHOR或最后保存日期。docx 库把字段封装成了常规的段落子元素你可以像添加TextRun一样把它放进Paragraph的children数组中无需手动拼接任何 OOXML 标签。字段代码速查表Word 使用字段代码来标识字段的计算结果。你可以在 Word 中通过Insert - Quick Parts - Field...插入一个字段再点击 Field codes 按钮查看对应的字段代码。以下是常用字段代码及其含义字段类型示例说明 (Formula)2*21计算公式的结果也可以使用书签作为变量见下文公式字段。AuthorAUTHOR显示文档属性中记录的作者。CreateDateCREATEDATE文档的创建日期。DateDATE今天的日期。FileNameFILENAME \p文档名称追加\p开关可显示完整路径。InfoINFO NumWords文档属性中的数据例如文档的总字数。NumPagesNUMPAGES文档的总页数。UserNameUSERNAMEOffice 个性化设置中的用户名。补充字段代码不区分大小写AUTHOR、author与Author等价文档创建日期同时存在对应的底层指令CREATEDATE配合格式开关可控制显示样式例如 demo 中的CREATEDATE \ d MMMM yyyy会渲染成类似 16 September 2026 的格式。简单字段SimpleFieldWord 中有些字段非常复杂比如目录 TOC但在很多场景下整个字段只需要一段指令文本、拥有相同的格式属性即可。此时可以使用简单字段。在 OOXML 中简单字段对应w:fldSimple元素字段指令放在w:instr属性中。docx 库的SimpleField类即封装了这一结构源码位于 src/file/paragraph/run/simple-field.ts构造时以instruction为w:instr属性值创建FldSimpleAttrs若传入了缓存值则追加一个TextRun作为子元素。字段可以作为一个段落的孩子添加import { Document, Packer, Paragraph, SimpleField, TextRun } from docx; const paragraph new Paragraph({ children: [new TextRun(This document was created by: ), new SimpleField(AUTHOR)], });缓存值cached value字段可以包含一个缓存值cached value用来在没有重新计算全部字段的情况下让文字处理器先展示一段文本。缓存值可以在打开文档后通过选中字段并按下 F9 更新。缓存值作为构造函数第二个参数传入const paragraph new Paragraph({ children: [new TextRun(This document was created by: ), new SimpleField(AUTHOR, Richard Brodie)], });从实现上看缓存值会被渲染成w:fldSimple内部的TextRun见 src/file/paragraph/run/simple-field.ts。这正是文档先有可读内容、再按需刷新的关键机制——例如在 demo/66-fields.ts 中new SimpleField(NUMWORDS, 34)先显示 34 作为占位待 Word 计算后更新为真实字数。公式字段Formulas公式是字段的一种可以用来做基础计算。计算既可以使用静态值例如2*21也可以引用书签中的值。下面这个例子演示了如何把两个书签的值相加import { Bookmark, Paragraph, SimpleField, TextRun } from docx; const paragraph new Paragraph({ children: [ new TextRun(Value one is: ), new Bookmark({ id: One, children: [new TextRun(451)] }), new TextRun(. The second value is: ), new Bookmark({ id: Two, children: [new TextRun(886)] }), new TextRun(. The sum of these values is: ), new SimpleField(OneTwo), ], });这里的诀窍是Bookmark中的文本即书签的值而OneTwo指令中的One、Two对应书签 id。demo 中还有更进阶的用法把公式与书签结合描述一个打印场景new Bookmark({ id: TimesPrinted, children: [new TextRun(42)], }), // ... new SimpleField(INT((TimesPrinted1)/2)),即若打印 42 次双面需要INT((421)/2)张纸公式会引用书签值自动计算。书签的完整用法可参考 docs/usage/bookmarks.md。邮件合并字段Mail merge fields字段在邮件合并mail merge中非常常见先创建模板文档再在合并阶段把来自 Excel 或数据库的数据插入文档。docx 库为此提供了便捷类SimpleMailMergeField只需传入数据集中的字段名即可与普通字段一样作为段落子元素使用const paragraph new Paragraph({ children: [new TextRun(Your score was ), new SimpleMailMergeField(Score), new TextRun( of 100 points)], });这段代码与下面的写法完全等价const paragraph new Paragraph({ children: [new TextRun(Your score was ), new SimpleField(MERGEFIELD Score, «Score»), new TextRun( of 100 points)], });从源码看src/file/paragraph/run/simple-field.tsSimpleMailMergeField直接继承SimpleField构造时生成指令MERGEFIELD ${fieldName}并把«${fieldName}»作为缓存值——« »是 Word 邮件合并的默认占位符样式合并执行后会被真实数据替换。简单字段与复杂字段底层结构差异理解fldSimple之前需要知道 Word 还有另一套复杂字段表示法。复杂字段由三个字段字符w:fldChar围出区域begin标记开始、separate分隔字段指令与结果、end标记结束。docx 库在 src/file/paragraph/run/field.ts 中提供了createBegin、createSeparate、createEnd三个工厂函数并支持dirty属性标记字段需要重新计算。// 一个复杂字段的 OOXML 结构示意 // w:rw:fldChar w:fldCharTypebegin w:dirtytrue//w:r // w:rw:instrTextPAGE/w:instrText/w:r // w:rw:fldChar w:fldCharTypeseparate//w:r // w:rw:fldChar w:fldCharTypeend//w:r与之相对简单字段w:fldSimple把指令与结果收敛在单个元素内不需要 begin/end 配对因而更适合指令简单、无需嵌套的场景。需要嵌套结构如指令文本内部还要区分格式的字段则必须走复杂字段路线。仓库内置的其他字段能力源码佐证除了文档正文提到的SimpleField与SimpleMailMergeFielddocx 库还针对常见字段场景提供了开箱即用的封装类可以在段落中直接使用页码与节信息src/file/paragraph/run/page-number.ts提供了PagePAGE指令当前页号、NumberOfPagesNUMPAGES总页数、NumberOfPagesSectionSECTIONPAGES本节页数、CurrentSectionSECTION当前节号。这些指令以w:instrText输出通常与复杂字段的 begin/end 配合使用。需要页码的更多用法可参考 docs/usage/page-numbers.md。顺序编号SEQsrc/file/paragraph/run/sequential-identifier.ts中的SequentialIdentifier生成SEQ字段可分别为图、表、公式维护独立的自动递增序列例如new SequentialIdentifier(Figure)。它内部组合了createBegin(true)SEQ指令 createSeparate()createEnd()属于复杂字段的典型封装。页码交叉引用PAGEREFsrc/file/paragraph/links/pageref.ts中的PageReference(bookmarkId, options)生成PAGEREF字段用于显示某书签所在页码支持hyperlink\h开关将引用变为超链接与useRelativePosition\p开关同页时显示 above/below、跨页时显示 on page #。编号项引用REFsrc/file/paragraph/links/numbered-item-ref.ts中的NumberedItemReference基于SimpleField实现REF字段可引用书签对应段落的编号文本并通过NumberedItemReferenceFormatnone/relative(\r) /no_context(\n) /full_context(\w)控制编号的展示粒度默认hyperlink: true、full_context。目录TOC目录本质上也是一个复杂字段。src/file/table-of-contents/field-instruction.ts会把配置项如headingStyleRange、hyperlink、stylesWithLevels拼装成TOC \o 1-3 \h形式的指令文本详细用法见 docs/usage/table-of-contents.md。完整示例一个充满字段的文档仓库中的 demo/66-fields.ts 把上述知识点串成了一个可直接运行的完整示例——它创建了一个包含文件名、创建日期、作者、字数、书签和公式字段的文档并导出为 My Document.docx// Use fields to include dynamic text import * as fs from fs; import { Bookmark, Document, Packer, Paragraph, SimpleField, TextRun } from docx; const doc new Document({ creator: Me, sections: [ { properties: {}, children: [ new Paragraph({ children: [ new TextRun(This document is called ), new SimpleField(FILENAME, My Document.docx), new TextRun(, was created on ), new SimpleField(CREATEDATE \\ d MMMM yyyy), new TextRun( by ), new SimpleField(AUTHOR), ], }), new Paragraph({ children: [ new TextRun(The document has ), new SimpleField(NUMWORDS, 34), new TextRun( words and if youd print it ), new Bookmark({ id: TimesPrinted, children: [new TextRun(42)], }), new TextRun( times two-sided, you would need ), new SimpleField(INT((TimesPrinted1)/2)), new TextRun( sheets of paper.), ], }), ], }, ], }); Packer.toBuffer(doc).then((buffer) { fs.writeFileSync(My Document.docx, buffer); });运行方式在仓库根目录或你自己的项目里安装docx后用 ts-node / tsx 执行该脚本即可在输出目录得到生成的.docx文件。示例中所有SimpleField都提供了缓存值因此文档在没有打开 Word 重新计算字段前也能正常显示一段合理的内容。实战注意事项缓存值决定了未刷新前的显示给SimpleField传入第二个参数可以保证文档在计算前就具备可读内容不传则字段区域可能为空。对于MERGEFIELD这类字段缓存值«Score»还是最终数据的占位提示。F9 刷新Word 打开文档后默认不会自动重算全部字段选中字段按 F9 即可更新打印时 Word 通常也会刷新部分字段。复杂字段是兜底方案当字段需要跨多个 run 分隔、或者指令本身需要细分格式例如 src/file/paragraph/run/page-number.ts 中的指令输出时应使用createBegin/createSeparate/createEnd构造复杂字段而不是SimpleField。指令字符串保持原样SimpleField的instruction参数会原样写入w:instr因此开关、空格与格式开关如\ d MMMM yyyy、\p都需要你自己拼写正确拼写错误不会被库拦截只会影响 Word 侧的计算结果。小结字段是让 docx 文档活起来的关键机制。通过SimpleField一行代码即可注入 AUTHOR、DATE、NUMPAGES 等动态内容借助缓存值参数可以控制刷新前的显示公式字段配合Bookmark能完成引用书签值的计算SimpleMailMergeField则让模板与外部数据源的合并变得轻而易举。若需要更复杂的页码、交叉引用或目录场景仓库还提供了PageReference、NumberedItemReference、SequentialIdentifier与TableOfContents等内置封装它们都是建立在本文所述的字段机制之上的。【免费下载链接】docxEasily generate and modify .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.项目地址: https://gitcode.com/GitHub_Trending/do/docx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考