关于 docx
docx 是用于创建、编辑和分析 Word .docx 文件的技能,涵盖文档生成、模板占位符替换和 OOXML 编辑,并支持批注、修订处理及渲染检查。
主要功能
- 01使用 docx-js 创建 .docx
- 02替换模板占位符
- 03编辑 OOXML 包内容
- 04读取并校验文档内容
- 05添加批注并接受修订
适用场景
- 01生成新的 Word 文档
- 02填写现有模板中的字段
- 03编辑或审阅带修订的文档
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ k-dense-ai/ scientific-agent-skills --skill docx安装后在 Claude Code 中输入/docx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtscripts/__init__.pyaccept_changes.pycomment.pymerge_runs.pyscripts/office/helpers/__init__.pypptx_chart.pypptx_slide.pypptx_theme.pyscripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsdopc-coreProperties.xsdopc-digSig.xsdopc-relationships.xsdscripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsddml-chartDrawing.xsddml-diagram.xsddml-lockedCanvas.xsddml-main.xsddml-picture.xsddml-spreadsheetDrawing.xsddml-wordprocessingDrawing.xsdpml.xsdshared-additionalCharacteristics.xsdshared-bibliography.xsdshared-commonSimpleTypes.xsdshared-customXmlDataProperties.xsdshared-customXmlSchemaProperties.xsdshared-documentPropertiesCustom.xsdshared-documentPropertiesExtended.xsdshared-documentPropertiesVariantTypes.xsd详细介绍
DOCX 创建、编辑与分析
.docx 是一个由 XML 文件组成的 ZIP 归档。按任务选择你的方法:
| 任务 | 方法 |
|---|---|
| 创建新文档 | 编写一个 docx(npm)脚本——见下面的注意事项 |
| 填充模板中的占位符 | 使用 docx 中的 patchDocument({ data, outputType, patches }) |
| 编辑任意现有内容 | 安全解包 → 编辑相关 OOXML 部分 → 重新打包 |
| 读取内容 | 使用 pandoc -f docx -t markdown --track-changes=all file.docx 进行审阅;使用 accept 获取接受后的文本视图 |
下面的脚本路径相对于本 skill 的目录。
使用 docx-js 创建——注意事项
示例针对 docx 9.8.1。请先在脚本所在项目中检查 node -p "require.resolve('docx')"。如果不存在,请在该项目中用 npm install [email protected] 安装;是否预安装取决于具体环境。以下是主要的布局约束:
- 页面尺寸默认为 A4。 如需 US Letter,请设置
page: { size: { width: 12240, height: 15840 } }(DXA;1440 = 1″)。 - 横向: 传入纵向尺寸并设置
orientation: PageOrientation.LANDSCAPE——docx-js 会在内部交换宽高。 - 表格: 如需可预测的固定几何布局,请使用
layout: TableLayoutType.FIXED、表格width: { size, type: WidthType.DXA }、以 DXA 为单位的数值型columnWidths,并在单元格上设置匹配的宽度。使用跨列时,将跨越的列宽度相加。支持百分比宽度,但跨编辑器布局需要目视验证。 - 表格底纹: 使用
ShadingType.CLEAR搭配fill可获得纯色背景;SOLID使用的是前景图案颜色,而不仅仅是fill。 - 列表: 切勿直接插入
•;请使用带LevelFormat.BULLET的numbering配置。 ImageRun需要type:("png"、"jpg"等)。PageBreak必须位于Paragraph内。- 段落与换行: 段落请使用单独的
Paragraph元素;new TextRun({ break: 1, text: "Next line" })可在段落内产生换行。不要指望纯文本字符串中的\n会创建段落。 - 目录(TOC): 内置的
HeadingLevel.*可与headingStyleRange配合使用。自定义样式请使用stylesWithLevels,或将outlineLevel与useAppliedParagraphOutlineLevel: true搭配使用。在检查页码前,请先在 Word/LibreOffice 中更新 TOC 字段;创建字段并不会计算分页。 - 不要用表格作为水平分隔线——请改用段落底边框。
- 点引导符 / 同行右对齐: 请使用
TextRun内的PositionalTab(alignment: PositionalTabAlignment.RIGHT、relativeTo: PositionalTabRelativeTo.MARGIN、leader: PositionalTabLeader.DOT),而不是字面的.或空格填充。LibreOffice 26.2.4.2 在冒烟测试中未渲染该位置引导符/对齐;当该渲染器必须复现此效果时,请使用段落tabStops加一个Tabrun。
小型创建与模板示例
使用 node example.cjs 运行此 CommonJS 脚本。patchDocument 会替换
{{name}},无需完整重建文档;它是一个占位符修补器,而不是通用的 Word 文档编辑对象模型。
const fs = require("node:fs/promises");
const { Document, Packer, Paragraph, TextRun, HeadingLevel,
patchDocument, PatchType } = require("docx");
async function main() {
const document = new Document({ sections: [{
properties: { page: { size: { width: 12240, height: 15840 } } },
children: [
new Paragraph({ text: "Research memo", heading: HeadingLevel.HEADING_1 }),
new Paragraph("Prepared for {{name}}"),
],
}] });
const template = await Packer.toBuffer(document);
const output = await patchDocument({
data: template, outputType: "nodebuffer",
patches: { name: { type: PatchType.PARAGRAPH,
children: [new TextRun({ text: "Research team", bold: true })] } },
});
await fs.writeFile("output.docx", output);
}
main().catch(error => { console.error(error); process.exitCode = 1; });
验证输出
编写 .docx 后,请渲染并查看它:
mkdir -p preview
python scripts/office/soffice.py --headless --convert-to pdf --outdir preview output.docx
test -s preview/output.pdf
pdftoppm -jpeg -r 100 preview/output.pdf preview/page
ls preview/page-*.jpg # then Read the images
请使用全新的预览目录,或先删除其中的旧 PDF:仅凭转换器的退出状态 并不能证明已写入新文件。请检查每个渲染页面是否存在溢出、 页眉、表格和缺失图片;转换可能会替换不可用的字体。
pdftoppm 会将页码补零至页数所需的宽度(page-01.jpg…page-12.jpg)。
编辑现有文档
旧版 .doc 文件必须先转换:python scripts/office/soffice.py --headless --convert-to docx file.doc。
python - <<'PY'
import sys, zipfile
from pathlib import Path
sys.path.insert(0, "scripts")
from office.helpers import safe_extract
with zipfile.ZipFile("doc.docx") as archive:
safe_extract(archive, Path("unpacked")) # rejects symlinks and traversal
PY
python scripts/merge_runs.py unpacked/ # coalesce fragmented runs so text is findable
# edit unpacked/word/document.xml in place — do NOT reformat or pretty-print
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # bundled schema and package checks
# redlining? add --author "<the name you redlined under>" to check every edit is tracked
Word 会将文本拆分到许多 <w:r> run 中(修订 ID、拼写检查标记),因此你在文档中看到的某个短语,在 XML 中往往并不作为连续字符串存在。merge_runs.py 会合并 word/document.xml 中相邻且格式完全相同的 run,同时保留文本和格式边界;请对结果进行渲染检查,尤其是域和复杂内容;它还接受直接传入 .docx(python scripts/merge_runs.py doc.docx -o merged.docx)。
修订跟踪: 保留已存在的作者/日期/ID 和修订。进行红线标记时,使用 --author "<the name you redlined under>"(需要 --original)进行验证——它会在撤销新增的 <w:ins>/<w:del> 修订后比较正文文本,以暴露接受视图可能隐藏的未跟踪文本编辑。用 w:id、w:author、w:date 属性将 run 包裹在 <w:ins>/<w:del> 中。在 <w:del> 内,文本元素是 <w:delText>,而不是 <w:t>。删除段落标记(<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>)表示“将此段落合并到下一段”——因此,彻底删除一个段落就是该标记再加上用 <w:del> 包裹每个 run。在段落标记的 w:rPr 内,按该内容模型的要求,将修订标记放在其他 run 属性之前。
要生成接受所有修订跟踪的干净副本:python scripts/accept_changes.py in.docx out.docx。
该辅助工具使用临时副本和隔离的 LibreOffice 配置文件。其自身的应用程序
宏以 MacroExecutionMode=NEVER_EXECUTE 打开输入,因此文档提供的
宏被禁用;它不会降低配置文件宏安全性。超时、转换
失败,或任何 Word XML 部分中残留修订元素,都会使目标文件
保持不变。--timeout 120 可提高每次 LibreOffice 操作的超时限制。没有修订
元素的文档会被直接复制,而无需经过 LibreOffice 往返转换。
接受删除的段落标记应将该段落与下一段连接。不要 假设 Pandoc 的接受文本视图或 LibreOffice 转换能完全复现 Word 的段落、列表或格式语义。检查 XML 中删除的段落标记, 并渲染干净副本,尤其是空占位符旁边的已删除编号段落。意外出现的空项目符号需要调查,而不是自动忽略。
内置验证器是针对随附的 2016 schema 以及部分 Microsoft 扩展的实用检查,
并非对当前 Word 兼容性的完整判定。
--original 会抑制继承的 schema 错误。--auto-repair 会重写输入,
并可能改变重要空白;请检查其更改。红线标记检查
仅覆盖正文文本,不覆盖格式、表格的结构性修订或其他故事部分。
文档范围的编辑覆盖
word/document.xml 包含主要内容,但并不包含所有文档文本。在进行
整篇文档替换之前,请通过包关系清点相关的页眉、页脚、脚注、
尾注、批注和文本框故事部分。
merge_runs.py 仅处理 word/document.xml;它不会规范化那些
其他部分。在范围要求的地方应用所请求的编辑,保留
关系,并检查渲染后的首页以及奇偶页页眉和
页脚以及正文。参见 Microsoft 的 WordprocessingML 结构。
批注
基本的批注需要一个批注部件、其关系/内容类型,以及匹配的
commentReference;范围起始/结束标记可选地标识文本区间。
该辅助工具还会额外写入用于回复串接的 Microsoft 扩展部件。请使用它 —— 当你还需要编辑 document.xml 时使用目录模式(可省去一次解压/重新打包的流程),否则使用 .docx 直连模式:
# Against an already-unpacked directory (preferred when also placing markers)
python scripts/comment.py unpacked/ "Fees & expenses cap is too low"
python scripts/comment.py unpacked/ "Agreed" --parent 0
# Against a .docx directly
python scripts/comment.py contract.docx "This cap is too low" -o annotated.docx
该脚本会写入 comments.xml、commentsExtended.xml、commentsIds.xml、commentsExtensible.xml、关系以及内容类型覆盖。批注 ID 会自动分配;重复的显式 ID 会被拒绝。回复会引用父批注的最后一个段落 ID。使用其他文件名的现有部件需要直接编辑那些关系目标;辅助工具会拒绝它们,而不是创建相互竞争的批注部件。随后它会打印 <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> 片段,供你添加到 word/document.xml 中,以便将批注锚定到特定文本 —— 在你放置这些标记之前,批注虽然存在但不可见。
依赖
docx(npm)· Python defusedxml 和 lxml · pandoc · LibreOffice(soffice)· pdftoppm(Poppler)。
Python 包安装:在专用环境中运行 python -m pip install defusedxml lxml。无需凭据或服务 API 调用。
已对照当前的 docx API、 patchDocument、 LibreOffice 命令行、 Microsoft 批注、 回复段落 ID 以及 Pandoc 选项 进行审查。 创建、占位符修补、PDF 渲染、批注和修订接受 均已使用 docx 9.8.1、LibreOffice 26.2.4.2、Pandoc 3.11 和 Poppler 26.09.0 进行冒烟测试。未测试 Microsoft Word 和 Google Docs 的渲染效果。
本技能由 Anthropic 创建并维护。此处改编时添加了 frontmatter 元数据和编辑范围指南;条款见 LICENSE.txt。