DOCX Toolkit — DOCX 工具kit
v0.21.4创建、读取、编辑或操作 Word 文档(.docx 文件)。 支持从零创建专业文档(含目录、标题、页码、信头等格式), 编辑现有文档(查找替换、插入图片、处理修订和批注), 以及提取和重组文档内容。 当用户提到 Word、.docx 或要求生成报告、备忘录、信件等文档时使用。 不要用于 PDF、电子表格或 Google 文档。
运行时依赖
安装命令
点击复制技能文档
DOCX 创建、编辑与分析 概述
.docx 文件是一个包含 XML 文件的 ZIP 压缩包。
快速参考 任务 方法 读取/分析内容 使用 pandoc 或解包查看原始 XML 创建新文档 使用 docx-js - 参见下文的"创建新文档" 编辑现有文档 解包 → 编辑 XML → 重新打包 - 参见下文的"编辑现有文档" 将 .doc 转换为 .docx
旧版的 .doc 文件必须先进行转换才能进行编辑:
python scripts/office/soffice.py --headless --convert-to docx document.doc
读取内容 # 提取带有修订记录的文本 pandoc --追踪-changes=all document.docx -o 输出.md
# 访问原始 XML python scripts/office/unpack.py document.docx unpacked/
转换为图片 python scripts/office/soffice.py --headless --convert-to pdf document.docx pdftoppm -jpeg -r 150 document.pdf page
接受修订
生成包含所有已接受修订的干净文档(需要 LibreOffice):
python scripts/accept_changes.py 输入.docx 输出.docx
创建新文档
使用 JavaScript 生成 .docx 文件,然后进行验证。安装:npm 安装 -g docx
设置 const { Document, Packer, Paragraph, Text运行, Table, TableRow, TableCell, Image运行, Header, Footer, AlignmentType, PageOrientation, Level格式化, ExternalHyperlink, InternalHyperlink, Bookmark, FootnoteReference运行, PositionalTab, PositionalTabAlignment, PositionalTabRelativeTo, PositionalTabLeader, Tab停止Type, Tab停止Position, Column, SectionType, TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType, VerticalAlign, PageNumber, PageBreak } = require('docx');
const doc = new Document({ sections: [{ children: [/ 内容 /] }] }); Packer.toBuffer(doc).then(buffer => fs.writeFile同步("doc.docx", buffer));
验证
创建文件后,对其进行验证。如果验证失败,进行解包,修复 XML,然后重新打包。
python scripts/office/验证.py doc.docx
页面大小 // 注意:docx-js 默认页面大小为 A4,而非美式信纸(US Letter) // 始终明确设置页面大小以获得一致结果 sections: [{ properties: { page: { size: { width: 12240, // 8.5 英寸(单位:DXA) height: 15840 // 11 英寸(单位:DXA) }, margin: { top: 1440, right: 1440, 机器人tom: 1440, left: 1440 } // 1 英寸边距 } }, children: [/ 内容 /] }]
常见页面大小(单位为 DXA,1440 DXA = 1 英寸):
纸张 宽度 高度 内容宽度 (1" 边距) US Letter 12,240 15,840 9,360 A4 (默认) 11,906 16,838 9,026
横向(Landscape)排版: docx-js 在内部交换宽高,因此请传递纵向尺寸并让它处理交换:
size: { width: 12240, // 将短边作为宽度传递 height: 15840, // 将长边作为高度传递 orientation: PageOrientation.LANDSCAPE // docx-js 会在 XML 中交换它们 }, // 内容宽度 = 15840 - 左边距 - 右边距 (使用长边)
样式(覆盖内置标题)
使用 Arial 作为默认字体(普遍支持)。标题保持黑色以增强可读性。
const doc = new Document({ styles: { default: { document: { 运行: { font: "Arial", size: 24 } } }, // 12pt 默认大小 paragraphStyles: [ // 关键:使用精确的 ID 以覆盖内置样式 { id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quick格式化: true, 运行: { size: 32, bold: true, font: "Arial" }, paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // TOC 需要 outlineLevel 属性 { id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quick格式化: true, 运行: { size: 28, bold: true, font: "Arial" }, paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } }, ] }, sections: [{ children: [ new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new Text运行("标题")] }), ] }] });
列表(切勿使用 Unicode 项目符号) // ❌ 错误做法:切勿手动输入项目符号字符 new Paragraph({ children: [new Text运行("• 项目")] }) // 错误 new Paragraph({ children: [new Text运行("\u2022 项目")] }) // 错误
// ✅ 正确做法:使用带 Level格式化.BULLET 的 numbering(编号)配置 const doc = new Document({ numbering: { config: [ { reference: "bullets", levels: [{ level: 0, 格式化: Level格式化.BULLET, text: "•", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }, { reference: "numbers", levels: [{ level: 0, 格式化: Level格式化.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }, ] }, sections: [{ children: [ new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [new Text运行("带项目符号的项")] }), new Paragraph({ numbering: { reference: "numbers", level: 0 }, children: [new Text运行("带编号的项")] }), ] }] });
// ⚠️ 每个 reference(引用)都会创建独立的编号: // 相同引用 = 延续 (1,2,3 接着 4,5,6) // 不同引用 = 重新开始 (1,2,3 接着 1,2,3)
表格
关键点:表格需要双重宽度声明——既要在表格设置 columnWidths(列宽),也需要为每个单元格(cell)设置 width(宽)。如果不同时设置,表格在某些平台上可能会渲染错误。
// 关键点:始终设置表格宽度以获得一致的渲染 // 关键点:使用 ShadingType.CLEAR(非 SOLID)防止背景变黑 const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" }; const borders = { top: border, 机器人tom: border, left: border, right: border };
new Table({ width: { size: 9360, type: WidthType.DXA }, // 务必使用 DXA(百分比在 Google Docs 中会出错) columnWidths: [4680, 4680], // 必须其和等于表格宽度(DXA:1440 = 1 英寸) rows: [ new TableRow({ children: [ new TableCell({ borders, width: { size: 4680, type: WidthType.DXA }, // 务必在每个单元格上也进行设置 shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, // 必须使用 CLEAR,不能用 SOLID margins: { top: 80, 机器人tom: 80, left: 120, right: 120 }, // 单元格内补白(内部空间,不增加整体宽度) children: [new Paragraph({ children: [new Text运行("单元格")] })] }) ] }) ] })
表格宽度计算