Loading...
Loading...
Compare original and translation side by side
| Need | Method |
|---|---|
| Text content only (summarize, analyze, translate) | Read tool is fine |
| Formatting info (copy styles, preserve layout, template filling) | Unzip and parse XML |
| Structure + comments/track changes | |
| 需求 | 方法 |
|---|---|
| 仅需文本内容(总结、分析、翻译) | 使用读取工具即可 |
| 需要格式信息(复制样式、保留布局、填充模板) | 解压并解析XML |
| 需要结构 + 批注/修订模式 | |
libreoffice --headless --convert-to docxlibreoffice --headless --convert-to docxdocx/
├── SKILL.md ← This file (entry point + reference)
├── references/
│ └── EditingGuide.md → Complete Python editing tutorial (comments, track changes, 5-file sync)
├── scripts/
│ ├── docx → Unified entry (the only script to call)
│ ├── fix_element_order.py → Auto-fix XML element ordering
│ ├── validate_docx.py → Business rule validation
│ ├── generate_backgrounds.py → Morandi style backgrounds
│ ├── generate_inkwash_backgrounds.py → Ink-wash style backgrounds
│ └── generate_chart.py → matplotlib (only for heatmaps/3D/radar; simple charts must use native)
├── assets/
│ └── templates/
│ ├── KimiDocx.csproj → Project file template (for creating new docs)
│ ├── Program.cs → Program entry template
│ ├── Example.cs → Complete example (cover+TOC+charts+back cover)
│ ├── CJKExample.cs → CJK content patterns (quote escaping, fonts)
│ └── xml/ → XML templates for comments infrastructure
└── validator/ → OpenXML validator (pre-compiled binary, AI does not modify)./scripts/docx buildExample.csCJKExample.csreferences/EditingGuide.mddocx/
├── SKILL.md ← 本文件(入口点 + 参考文档)
├── references/
│ └── EditingGuide.md → 完整的Python编辑教程(批注、修订模式、多文件同步)
├── scripts/
│ ├── docx → 统一入口(唯一需要调用的脚本)
│ ├── fix_element_order.py → 自动修复XML元素顺序问题
│ ├── validate_docx.py → 业务规则验证
│ ├── generate_backgrounds.py → 莫兰迪风格背景生成
│ ├── generate_inkwash_backgrounds.py → 水墨风格背景生成
│ └── generate_chart.py → matplotlib(仅用于热力图/3D图/雷达图;简单图表必须使用原生Word图表)
├── assets/
│ └── templates/
│ ├── KimiDocx.csproj → 项目文件模板(用于创建新文档)
│ ├── Program.cs → 程序入口模板
│ ├── Example.cs → 完整示例(封面+目录+图表+封底)
│ ├── CJKExample.cs → CJK内容示例(引号转义、字体配置)
│ └── xml/ → 批注基础设施的XML模板
└── validator/ → OpenXML验证器(预编译二进制文件,AI无需修改)./scripts/docx buildExample.csCJKExample.csreferences/EditingGuide.mdcd /app/.kimi/skills/kimi-docx/
./scripts/docx init| Path | Purpose |
|---|---|
| SKILL directory, where commands are executed |
| Working directory, edit |
| Output directory, final deliverables |
| User upload location (input files) |
./scripts/docx <cmd>| Command | Purpose |
|---|---|
| Show environment status (no changes) |
| Setup dependencies + workspace |
| Compile, run, validate (default: output/output.docx) |
| Validate existing docx |
cd /app/.kimi/skills/kimi-docx/
./scripts/docx init| 路径 | 用途 |
|---|---|
| SKILL目录,所有命令在此执行 |
| 工作目录,在此编辑 |
| 输出目录,最终交付文件存放于此 |
| 用户上传文件的位置(输入文件) |
./scripts/docx <cmd>| 命令 | 用途 |
|---|---|
| 查看环境状态(无修改操作) |
| 安装依赖 + 初始化工作区 |
| 编译、运行、验证(默认输出:output/output.docx) |
| 验证现有docx文件 |
./scripts/docx builddotnet build && dotnet run./scripts/docx builddotnet build && dotnet run// Correct - get output path from command line arguments
string outputFile = args.Length > 0 ? args[0] : "/mnt/okcomputer/output/output.docx";
// Wrong - hardcoded path causes build failure
string outputFile = "my_document.docx"; // Script can't find file!| Step | Action | Notes |
|---|---|---|
| 1. Compile | | Provides fix suggestions on failure |
| 2. Generate | | Path passed via command line args |
| 3. Auto-fix | | Fixes XML element ordering issues |
| 4. OpenXML validation | | Mandatory |
| 5. Business rules | | Mandatory |
| 6. Statistics | Character + word count | Optional (requires pandoc) |
// 正确方式 - 从命令行参数获取输出路径
string outputFile = args.Length > 0 ? args[0] : "/mnt/okcomputer/output/output.docx";
// 错误方式 - 硬编码路径会导致构建失败
string outputFile = "my_document.docx"; // 脚本无法找到该文件!| 步骤 | 操作 | 说明 |
|---|---|---|
| 1. 编译 | | 编译失败时会提供修复建议 |
| 2. 生成 | | 通过命令行参数传递路径 |
| 3. 自动修复 | | 修复XML元素顺序问题 |
| 4. OpenXML验证 | | 必须执行 |
| 5. 业务规则验证 | | 必须执行 |
| 6. 统计 | 字符数 + 单词数 | 可选(需安装pandoc) |
cd /app/.kimi/skills/kimi-docx/
./scripts/docx validate /mnt/okcomputer/output/report.docxcd /app/.kimi/skills/kimi-docx/
./scripts/docx validate /mnt/okcomputer/output/report.docxpandoc output.docx -t plain--track-changes=allcomments.xmldoc_treereferences/EditingGuide.mdpandoc output.docx -t plain--track-changes=allcomments.xmldoc_treereferences/EditingGuide.mdTitlePageTitlePageTable of Contents
─────────────────
Chapter 1 Overview .......................... 1
Chapter 2 Methods ........................... 3
...
(Hint: On first open, right-click the TOC and select "Update Field" to show correct page numbers)目录
─────────────────
第一章 概述 .......................... 1
第二章 方法 ........................... 3
...
(提示:首次打开时,右键点击目录并选择「更新域」以显示正确页码)| Feature | Reason |
|---|---|
| Watermark | Changes visual state. SDK limitation: VML watermark classes don't serialize correctly; must write raw XML to header. |
| Document protection | Restricts editing |
| Mail merge fields | Requires data source |
| 功能 | 原因 |
|---|---|
| 水印 | 会改变文档视觉状态。SDK限制:VML水印类无法正确序列化;必须直接编写XML到页眉中。 |
| 文档保护 | 会限制编辑权限 |
| 邮件合并字段 | 需要数据源支持 |
| Chart Type | Method | Notes |
|---|---|---|
| Pie chart | Native | |
| Bar chart | Native | |
| Line chart | Native | Reference bar chart structure, use |
| Horizontal bar | Native | Reference bar chart structure, use |
| Heatmap, 3D, radar | matplotlib | Word native doesn't support |
| Complex statistics (box plot, etc.) | matplotlib | Word native doesn't support |
| 图表类型 | 方法 | 说明 |
|---|---|---|
| 饼图 | 原生 | |
| 柱状图 | 原生 | |
| 折线图 | 原生 | 参考柱状图结构,使用 |
| 横向柱状图 | 原生 | 参考柱状图结构,使用 |
| 热力图、3D图、雷达图 | matplotlib | Word原生不支持 |
| 复杂统计图表(箱线图等) | matplotlib | Word原生不支持 |
AddInlineImage()AddInlineImage(body, mainPart, "/path/to/image.png", "Description", docPrId++);X imagesAddInlineImage()AddInlineImage(body, mainPart, "/path/to/image.png", "Description", docPrId++);X images| User Request | Execution Standard |
|---|---|
| Specific word count (e.g., "3000 words") | Actual output within ±20% |
| Specific page count (e.g., "5 pages") | Exact match |
| Range (e.g., "2000-3000 words") | Within range |
| Minimum (e.g., "at least 5000 words") | No more than 2x the requirement |
| 用户需求 | 执行标准 |
|---|---|
| 特定字数(如"3000字") | 实际输出在±20%范围内 |
| 特定页数(如"5页") | 完全匹配页数 |
| 范围要求(如"2000-3000字") | 输出在指定范围内 |
| 最低要求(如"至少5000字") | 输出不超过要求的2倍 |
| Style | Palette | Suitable Scenarios |
|---|---|---|
| Morandi | Soft muted tones | Artistic, editorial |
| Earth tones | Brown, olive, natural | Environmental, organic |
| Nordic | Cool gray, misty blue | Minimalist, tech |
| Japanese Wabi-sabi | Gray, raw wood, zen | Traditional, contemplative |
| French elegance | Off-white, dusty pink | Luxury, feminine |
| Industrial | Charcoal, rust, concrete | Manufacturing, engineering |
| Academic | Navy, burgundy, ivory | Research, education |
| Ocean mist | Misty blue, sand | Marine, wellness |
| Forest moss | Olive, moss green | Nature, sustainability |
| Desert dusk | Ochre, sandy gold | Warm, regional |
| 风格 | 调色板 | 适用场景 |
|---|---|---|
| 莫兰迪 | 柔和低饱和色调 | 艺术类、编辑类文档 |
| 大地色系 | 棕色、橄榄绿、自然色调 | 环保类、有机类文档 |
| 北欧风 | 冷灰色、雾蓝色 | 极简主义、科技类文档 |
| 日式侘寂风 | 灰色、原木色、禅意色调 | 传统类、沉思类文档 |
| 法式优雅 | 米白色、灰粉色 | 奢侈品、女性向文档 |
| 工业风 | 炭黑色、铁锈红、混凝土色 | 制造业、工程类文档 |
| 学术风 | 藏青色、酒红色、象牙白 | 研究、教育类文档 |
| 海洋雾感 | 雾蓝色、沙色 | 海洋、健康类文档 |
| 森林苔藓 | 橄榄绿、苔藓绿 | 自然、可持续发展类文档 |
| 沙漠黄昏 | 赭石色、沙金色 | 温暖、地域特色类文档 |
| Property | XML | Effect |
|---|---|---|
| Keep with next | | Heading stays on same page as following paragraph |
| Keep lines together | | Paragraph won't break across pages |
| Page break before | | Force new page (for H1) |
| Widow/orphan control | | Prevent single lines at top/bottom of page |
// Example: H1 always starts on new page, stays with next paragraph
new ParagraphProperties(
new ParagraphStyleId { Val = "Heading1" },
new PageBreakBefore(),
new KeepNext(),
new KeepLines()
)// Allow row to break across pages (avoid large blank areas)
new TableRowProperties(
new CantSplit { Val = false } // false = can split
)
// Repeat header row on each page
new TableRowProperties(
new TableHeader()
)| 属性 | XML | 效果 |
|---|---|---|
| 与下段同页 | | 标题与后续段落保持在同一页 |
| 段落内不分页 | | 段落不会跨页拆分 |
| 段前分页 | | 强制新页面(用于H1标题) |
| 孤行控制 | | 避免页面顶部/底部出现单行文本 |
// 示例:H1标题始终从新页面开始,并与后续段落保持同页
new ParagraphProperties(
new ParagraphStyleId { Val = "Heading1" },
new PageBreakBefore(),
new KeepNext(),
new KeepLines()
)// 允许行跨页拆分(避免出现大面积空白)
new TableRowProperties(
new CantSplit { Val = false } // false = 允许拆分
)
// 每页重复表头行
new TableRowProperties(
new TableHeader()
)| Task | Stack | Reference |
|---|---|---|
| Create new document | C# + OpenXML SDK | 4.1-4.6 + |
| Edit existing document | Python + lxml | 4.7 + |
| 任务 | 技术栈 | 参考文档 |
|---|---|---|
| 创建新文档 | C# + OpenXML SDK | 4.1-4.6 + |
| 编辑现有文档 | Python + lxml | 4.7 + |
// Normal style must exist - all Heading styles use basedOn="Normal"
styles.Append(new Style(
new StyleName { Val = "Normal" },
new StyleParagraphProperties(
new SpacingBetweenLines { After = "200", Line = "276", LineRule = LineSpacingRuleValues.Auto }
),
new StyleRunProperties(
new RunFonts { Ascii = "Calibri", HighAnsi = "Calibri" },
new FontSize { Val = "22" },
new FontSizeComplexScript { Val = "22" }
)
) { Type = StyleValues.Paragraph, StyleId = "Normal", Default = true });// 必须存在Normal样式 - 所有Heading样式都基于Normal样式
styles.Append(new Style(
new StyleName { Val = "Normal" },
new StyleParagraphProperties(
new SpacingBetweenLines { After = "200", Line = "276", LineRule = LineSpacingRuleValues.Auto }
),
new StyleRunProperties(
new RunFonts { Ascii = "Calibri", HighAnsi = "Calibri" },
new FontSize { Val = "22" },
new FontSizeComplexScript { Val = "22" }
)
) { Type = StyleValues.Paragraph, StyleId = "Normal", Default = true });fix_element_order.py| Parent | Key Rule |
|---|---|
| |
| Must have |
fix_element_order.py| 父元素 | 关键规则 |
|---|---|
| |
| |
// Correct - table must define grid
var table = new Table();
table.Append(new TableProperties(...));
table.Append(new TableGrid( // Required!
new GridColumn { Width = "4680" },
new GridColumn { Width = "4680" }
));
table.Append(new TableRow(...));
// Wrong - missing tblGrid, Word cannot open
var table = new Table();
table.Append(new TableProperties(...));
table.Append(new TableRow(...)); // Adding rows directly// 正确方式 - 表格必须定义网格
var table = new Table();
table.Append(new TableProperties(...));
table.Append(new TableGrid( // 必需!
new GridColumn { Width = "4680" },
new GridColumn { Width = "4680" }
));
table.Append(new TableRow(...));
// 错误方式 - 缺少tblGrid,Word无法打开
var table = new Table();
table.Append(new TableProperties(...));
table.Append(new TableRow(...)); // 直接添加行gridColtblGridtcW// Correct - gridCol and tcW match exactly
table.Append(new TableGrid(
new GridColumn { Width = "3600" }, // First column
new GridColumn { Width = "5400" } // Second column
));
var row = new TableRow(
new TableCell(
new TableCellProperties(
new TableCellWidth { Width = "3600", Type = TableWidthUnitValues.Dxa } // Matches gridCol!
),
new Paragraph(new Run(new Text("Content")))
),
new TableCell(
new TableCellProperties(
new TableCellWidth { Width = "5400", Type = TableWidthUnitValues.Dxa } // Matches gridCol!
),
new Paragraph(new Run(new Text("Content")))
)
);| Rule | Reason |
|---|---|
| gridCol count = table column count | Otherwise column width calculation fails |
| gridCol.Width = tcW.Width | Mismatch causes skewing (checked during validation) |
| All rows in same column use same tcW | Maintains column width consistency |
tblGridgridColtcW// 正确方式 - gridCol与tcW宽度完全匹配
table.Append(new TableGrid(
new GridColumn { Width = "3600" }, // 第一列
new GridColumn { Width = "5400" } // 第二列
));
var row = new TableRow(
new TableCell(
new TableCellProperties(
new TableCellWidth { Width = "3600", Type = TableWidthUnitValues.Dxa } // 与gridCol匹配!
),
new Paragraph(new Run(new Text("内容")))
),
new TableCell(
new TableCellProperties(
new TableCellWidth { Width = "5400", Type = TableWidthUnitValues.Dxa } // 与gridCol匹配!
),
new Paragraph(new Run(new Text("内容")))
)
);| 规则 | 原因 |
|---|---|
| gridCol数量 = 表格列数 | 否则列宽计算会失败 |
| gridCol.Width = tcW.Width | 不匹配会导致表格变形(验证时会检查) |
| 同一列的所有行使用相同的tcW | 保持列宽一致性 |
paraId0x80000000paraId0x80000000| Task | Method | Why |
|---|---|---|
| Create new document | C# OpenXML SDK | Handles package structure, rels, Content_Types automatically |
| Edit existing document | Python + lxml | Transparent, no black box, full control |
Example.csreferences/EditingGuide.md| 任务 | 方法 | 原因 |
|---|---|---|
| 创建新文档 | C# OpenXML SDK | 自动处理包结构、关系、Content_Types |
| 编辑现有文档 | Python + lxml | 透明无黑盒,完全可控 |
Example.csreferences/EditingGuide.md| What to Learn | What NOT to Learn |
|---|---|
| Section division (cover → TOC → body → back cover) | Specific color values |
| Floating background insertion code | Business content from the example |
| Chart creation API calls | Copy/wording from the example |
| Style definition structure | Hardcoded data from the example |
| Feature | Function | Line # |
|---|---|---|
| Document Structure | ||
| Styles (Normal, Heading1-3) | | 85-203 |
| Cover page | | 369-453 |
| Table of contents | | 458-526 |
| Body section | | 531-729 |
| Back cover | | 734-794 |
| Visual Elements | ||
| Floating background | | 228-279 |
| Proportional inline image | | 285-364 |
| Tables | ||
| Three-line table | | 853-888 |
| Header row (gray bg) | | 933-971 |
| Data row | | 976-1008 |
| Charts | ||
| Pie chart | | 1013-1049 |
| Bar chart | | 1133-1169 |
| Page Elements | ||
| Header with background | within | 534-575 |
| Footer with page numbers | within | 578-588 |
| Page number field | | 1345-1354 |
| Total pages field | | 1356-1365 |
| Advanced Features | ||
| Footnote | | 1370-1410 |
| Cross-reference | | 1415-1425 |
| Numbering/lists | | 1327-1340 |
| 需要学习的内容 | 不需要学习的内容 |
|---|---|
| 章节划分(封面 → 目录 → 正文 → 封底) | 具体颜色值 |
| 浮动背景插入代码 | 示例中的业务内容 |
| 图表创建API调用 | 示例中的文案 |
| 样式定义结构 | 示例中的硬编码数据 |
| 功能 | 函数 | 行号 |
|---|---|---|
| 文档结构 | ||
| 样式(Normal、Heading1-3) | | 85-203 |
| 封面 | | 369-453 |
| 目录 | | 458-526 |
| 正文 | | 531-729 |
| 封底 | | 734-794 |
| 视觉元素 | ||
| 浮动背景 | | 228-279 |
| 等比例嵌入式图片 | | 285-364 |
| 表格 | ||
| 三线表 | | 853-888 |
| 表头行(灰色背景) | | 933-971 |
| 数据行 | | 976-1008 |
| 图表 | ||
| 饼图 | | 1013-1049 |
| 柱状图 | | 1133-1169 |
| 页面元素 | ||
| 带背景的页眉 | 位于 | 534-575 |
| 带页码的页脚 | 位于 | 578-588 |
| 页码域 | | 1345-1354 |
| 总页数域 | | 1356-1365 |
| 高级功能 | ||
| 脚注 | | 1370-1410 |
| 交叉引用 | | 1415-1425 |
| 编号/列表 | | 1327-1340 |
CJKExample.csExample.cs""\u201c\u201dExample.csCJKExample.csExample.cs""\u201c\u201dExample.csFieldChar(Begin)FieldCode(" PAGE ")FieldChar(Separate)TextFieldChar(End)UpdateFieldsOnOpenFieldChar(Begin)FieldCode(" PAGE ")FieldChar(Separate)TextFieldChar(End)UpdateFieldsOnOpenBookmarkStartBookmarkEnd" REF bookmarkName \\h "BookmarkStartBookmarkEnd" REF bookmarkName \\h "scripts/generate_backgrounds.pyscripts/generate_backgrounds.py| Style | Key Elements | Scenarios |
|---|---|---|
| MUJI | Thin borders + white space | Minimalist, Japanese, lifestyle |
| Bauhaus | Scattered geometric shapes | Art, design, creative |
| Swiss Style | Grid lines + accent bars | Professional, corporate |
| Soft Blocks | Soft color rectangles, overlapping transparent | Warm, education, healthcare |
| Rounded Geometry | Rounded rectangles, pill shapes | Tech, internet, youthful |
| Frosted Glass | Blur + transparency + subtle borders | Modern, premium, tech |
| Gradient Ribbons | Soft gradient ellipses + small dots | Feminine, beauty, soft |
| Dot Matrix | Regular dot pattern texture | Technical, data, engineering |
| Double Border | Nested borders + corner decorations | Traditional, formal, legal |
| Waves | Bottom SVG waves + gradient background | Ocean, environmental, flowing |
| Warm Natural | Earth tones + organic shapes | Environmental, agriculture, natural |
device_scale_factor=2BehindDoc=trueExample.cs:CreateFloatingBackground()| 风格 | 核心元素 | 适用场景 |
|---|---|---|
| 无印良品风 | 细边框 + 留白 | 极简主义、日式、生活方式类文档 |
| 包豪斯风 | 分散的几何图形 | 艺术、设计、创意类文档 |
| 瑞士风格 | 网格线 + 强调条 | 专业、企业类文档 |
| 柔和色块 | 柔和彩色矩形、透明重叠 | 温暖、教育、医疗类文档 |
| 圆角几何 | 圆角矩形、胶囊形状 | 科技、互联网、年轻化文档 |
| 毛玻璃 | 模糊 + 透明度 + 细微边框 | 现代、高端、科技类文档 |
| 渐变丝带 | 柔和渐变椭圆 + 小点 | 女性向、美妆、柔和风格文档 |
| 点阵纹理 | 规则点阵图案 | 技术、数据、工程类文档 |
| 双层边框 | 嵌套边框 + 角落装饰 | 传统、正式、法律类文档 |
| 波浪纹理 | 底部SVG波浪 + 渐变背景 | 海洋、环保、流动感文档 |
| 温暖自然 | 大地色系 + 有机形状 | 环保、农业、自然类文档 |
device_scale_factor=2BehindDoc=trueExample.cs:CreateFloatingBackground()TitlePageSectionPropertiesSectionPropertiesTitlePagesectPrColumnssectPrsectPrColumnssectPr<m:e><m:e><m:r><m:t>text</m:t></m:r><m:oMath><m:oMathPara><m:oMath>| Element | Structure |
|---|---|
| Fraction | |
| Subscript | |
| Superscript | |
| Radical | |
| Matrix | |
| Nary (∑∫) | |
| Delimiter | |
| Equation array | |
<m:e><m:mc><m:e><m:e><m:r><m:t>text</m:t></m:r><m:oMath><m:oMathPara><m:oMath>| 元素 | 结构 |
|---|---|
| 分数 | |
| 下标 | |
| 上标 | |
| 根式 | |
| 矩阵 | |
| 累加/积分(∑∫) | |
| 分隔符 | |
| 方程组 | |
<m:e><m:mc><m:mc>""\"“”‘’CJKExample.cs// ❌ Wrong - Chinese quotes break compilation
new Text("请点击"确定"按钮") // CS1003!
// ✓ Correct - use Unicode escapes
new Text("请点击\u201c确定\u201d按钮")| Character | Unicode | Usage |
|---|---|---|
| " (left double) | | Opening quote |
| " (right double) | | Closing quote |
| ' (left single) | | Opening single |
| ' (right single) | | Closing single |
@""\u// ❌ WRONG - @"" verbatim string, \u NOT escaped, outputs literal "\u201c"
string text = @"她说\u201c你好\u201d"; // Outputs: 她说\u201c你好\u201d
// ✓ CORRECT - regular string, \u IS escaped
string text = "她说\u201c你好\u201d"; // Outputs: 她说"你好"
// ✓ For long text, use + concatenation
string para = "第一段内容," +
"她说\u201c这是引用\u201d," +
"继续写第二段。";""\"“”‘’CJKExample.cs// ❌ 错误方式 - 中文引号会导致编译失败
new Text("请点击"确定"按钮") // CS1003!
// ✓ 正确方式 - 使用Unicode转义
new Text("请点击\u201c确定\u201d按钮")| 字符 | Unicode | 用途 |
|---|---|---|
| “ (左双引号) | | 开引号 |
| ” (右双引号) | | 闭引号 |
| ‘ (左单引号) | | 开单引号 |
| ’ (右单引号) | | 闭单引号 |
@""\u// ❌ 错误方式 - @""逐字字符串,\u未被转义,输出字面量"\u201c"
string text = @"她说\u201c你好\u201d"; // 输出:她说\u201c你好\u201d
// ✓ 正确方式 - 普通字符串,\u会被转义
string text = "她说\u201c你好\u201d"; // 输出:她说“你好”
// ✓ 长文本可使用+拼接
string para = "第一段内容," +
"她说\u201c这是引用\u201d," +
"继续写第二段。";wp:extenta:extcy = cx * height / widthwp:extenta:extcy = cx * height / widthKeepNextKeepNextsectPrpPrPageBreakContinuousNextPagesectPrpPrPageBreakContinuousNextPageUpdateFieldsOnOpenFieldChar(Begin)FieldCode(" TOC ...")FieldChar(Separate)FieldChar(End)Example.cs:AddTocSection()\o "1-3"\h\z\uHeading1Heading2UpdateFieldsOnOpenFieldChar(Begin)FieldCode(" TOC ...")FieldChar(Separate)FieldChar(End)Example.cs:AddTocSection()\o "1-3"\h\z\uHeading1Heading2// 1. Create header part
var headerPart = mainPart.AddNewPart<HeaderPart>();
var headerId = mainPart.GetIdOfPart(headerPart);
headerPart.Header = new Header(
new Paragraph(
new ParagraphProperties(
new ParagraphStyleId { Val = "Header" },
new Justification { Val = JustificationValues.Center }
),
new Run(new Text("Document Title"))
)
);
// 2. Create footer part (with page numbers)
var footerPart = mainPart.AddNewPart<FooterPart>();
var footerId = mainPart.GetIdOfPart(footerPart);
var footerPara = new Paragraph(
new ParagraphProperties(
new Justification { Val = JustificationValues.Center }
)
);
// PAGE field: Begin → FieldCode → Separate → Text → End
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
footerPara.Append(new Run(new FieldCode(" PAGE ")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Separate }));
footerPara.Append(new Run(new Text("1"))); // Placeholder, updated on open
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
footerPara.Append(new Run(new Text(" / ") { Space = SpaceProcessingModeValues.Preserve }));
// NUMPAGES field (same structure)
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
footerPara.Append(new Run(new FieldCode(" NUMPAGES ")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Separate }));
footerPara.Append(new Run(new Text("1")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
footerPart.Footer = new Footer(footerPara);
// 3. Reference in SectionProperties
new SectionProperties(
new HeaderReference { Type = HeaderFooterValues.Default, Id = headerId },
new FooterReference { Type = HeaderFooterValues.Default, Id = footerId },
new PageSize { Width = 11906, Height = 16838 },
new PageMargin { Top = 1440, Right = 1440, Bottom = 1440, Left = 1440, Header = 720, Footer = 720 }
)| Type | HeaderFooterValues | Purpose |
|---|---|---|
| Default | | Odd pages (or all pages) |
| Even | | Even pages |
| First | | First page |
TitlePage()<w:evenAndOddHeaders/>// 1. 创建页眉部分
var headerPart = mainPart.AddNewPart<HeaderPart>();
var headerId = mainPart.GetIdOfPart(headerPart);
headerPart.Header = new Header(
new Paragraph(
new ParagraphProperties(
new ParagraphStyleId { Val = "Header" },
new Justification { Val = JustificationValues.Center }
),
new Run(new Text("文档标题"))
)
);
// 2. 创建页脚部分(带页码)
var footerPart = mainPart.AddNewPart<FooterPart>();
var footerId = mainPart.GetIdOfPart(footerPart);
var footerPara = new Paragraph(
new ParagraphProperties(
new Justification { Val = JustificationValues.Center }
)
);
// PAGE域:Begin → FieldCode → Separate → Text → End
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
footerPara.Append(new Run(new FieldCode(" PAGE ")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Separate }));
footerPara.Append(new Run(new Text("1"))); // 占位符,打开时会更新
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
footerPara.Append(new Run(new Text(" / ") { Space = SpaceProcessingModeValues.Preserve }));
// NUMPAGES域(相同结构)
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Begin }));
footerPara.Append(new Run(new FieldCode(" NUMPAGES ")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.Separate }));
footerPara.Append(new Run(new Text("1")));
footerPara.Append(new Run(new FieldChar { FieldCharType = FieldCharValues.End }));
footerPart.Footer = new Footer(footerPara);
// 3. 在SectionProperties中引用
new SectionProperties(
new HeaderReference { Type = HeaderFooterValues.Default, Id = headerId },
new FooterReference { Type = HeaderFooterValues.Default, Id = footerId },
new PageSize { Width = 11906, Height = 16838 },
new PageMargin { Top = 1440, Right = 1440, Bottom = 1440, Left = 1440, Header = 720, Footer = 720 }
)| 类型 | HeaderFooterValues | 用途 |
|---|---|---|
| 默认 | | 奇数页(或所有页面) |
| 偶数页 | | 偶数页 |
| 首页 | | 第一页 |
TitlePage()<w:evenAndOddHeaders/><!-- Required in footnotes.xml / endnotes.xml before user notes -->
<w:footnote w:type="separator" w:id="-1">
<w:p><w:r><w:separator/></w:r></w:p>
</w:footnote>
<w:footnote w:type="continuationSeparator" w:id="0">
<w:p><w:r><w:continuationSeparator/></w:r></w:p>
</w:footnote>
<!-- User notes start from id="1" --><!-- footnotes.xml / endnotes.xml中用户注释之前必须包含以下内容 -->
<w:footnote w:type="separator" w:id="-1">
<w:p><w:r><w:separator/></w:r></w:p>
</w:footnote>
<w:footnote w:type="continuationSeparator" w:id="0">
<w:p><w:r><w:continuationSeparator/></w:r></w:p>
</w:footnote>
<!-- 用户注释从id="1"开始 -->NumberingDefinitionsPartAbstractNumNumberingInstanceNumberingPropertiesAbstractNumLevelDecimalUpperLetterLowerRomanBulletChineseCountingNumberingDefinitionsPartAbstractNumNumberingInstanceNumberingPropertiesLevelAbstractNumDecimalUpperLetterLowerRomanBulletChineseCounting<w:hyperlink>var relId = mainPart.AddHyperlinkRelationship(new Uri("https://example.com"), true).Id;
paragraph.Append(new Hyperlink(new Run(
new RunProperties(new Color { Val = "0563C1" }, new Underline { Val = UnderlineValues.Single }),
new Text("Click here")
)) { Id = relId })<w:hyperlink>var relId = mainPart.AddHyperlinkRelationship(new Uri("https://example.com"), true).Id;
paragraph.Append(new Hyperlink(new Run(
new RunProperties(new Color { Val = "0563C1" }, new Underline { Val = UnderlineValues.Single }),
new Text("点击此处")
)) { Id = relId })| Requirement | Preferred | Alternative |
|---|---|---|
| Data charts | Word native | matplotlib PNG |
| Flowcharts | DrawingML Shapes | Table layout |
| Illustrations | Image generation | Image search |
NumberLiteralDataPointdpi=300axes.unicode_minus=False| 需求 | 首选方案 | 备选方案 |
|---|---|---|
| 数据图表 | Word原生图表 | matplotlib PNG |
| 流程图 | DrawingML形状 | 表格布局 |
| 插图 | 图片生成 | 图片搜索 |
NumberLiteralDataPointdpi=300axes.unicode_minus=Falsedocx_lib.editingfrom scripts.docx_lib.editing import (
DocxContext,
add_comment, reply_comment, resolve_comment, delete_comment,
insert_paragraph, insert_text, propose_deletion,
reject_insertion, restore_deletion, enable_track_changes
)
with DocxContext("input.docx", "output.docx") as ctx:
# add_comment(ctx, para_text, comment, highlight=None)
# - para_text: text to locate paragraph
# - comment: comment content
# - highlight: text to highlight (omit to highlight entire paragraph)
add_comment(ctx, "M-SVI index", "Please define", highlight="M-SVI")
insert_text(ctx, "The method", after="method", new_text=" and materials")references/EditingGuide.mddocx_lib.editingfrom scripts.docx_lib.editing import (
DocxContext,
add_comment, reply_comment, resolve_comment, delete_comment,
insert_paragraph, insert_text, propose_deletion,
reject_insertion, restore_deletion, enable_track_changes
)
with DocxContext("input.docx", "output.docx") as ctx:
# add_comment(ctx, para_text, comment, highlight=None)
# - para_text: 用于定位段落的文本
# - comment: 批注内容
# - highlight: 需要高亮的文本(省略则高亮整个段落)
add_comment(ctx, "M-SVI index", "请定义该术语", highlight="M-SVI")
insert_text(ctx, "The method", after="method", new_text=" and materials")references/EditingGuide.md<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:eastAsia="SimSun"/>
<w:sz w:val="24"/> <!-- 12pt = 24 half-points -->
<w:b/><w:i/><w:u w:val="single"/>
<w:color w:val="FF0000"/>
</w:rPr>
<w:t>text</w:t>
</w:r><w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:eastAsia="SimSun"/>
<w:sz w:val="24"/> <!-- 12磅 = 24半磅 -->
<w:b/><w:i/><w:u w:val="single"/>
<w:color w:val="FF0000"/>
</w:rPr>
<w:t>文本</w:t>
</w:r><!-- Insertion: <w:ins> wraps <w:r> -->
<w:ins w:id="1" w:author="..." w:date="...">
<w:r><w:rPr>...</w:rPr><w:t>text</w:t></w:r>
</w:ins>
<!-- Deletion: <w:del> wraps <w:r> (same pattern as ins!) -->
<w:del w:id="2" w:author="..." w:date="...">
<w:r><w:rPr>...</w:rPr><w:delText>text</w:delText></w:r>
</w:del><w:ins><w:del><w:r><w:delText><w:t><!-- 插入:<w:ins>包裹<w:r> -->
<w:ins w:id="1" w:author="..." w:date="...">
<w:r><w:rPr>...</w:rPr><w:t>文本</w:t></w:r>
</w:ins>
<!-- 删除:<w:del>包裹<w:r>(与ins模式相同!) -->
<w:del w:id="2" w:author="..." w:date="...">
<w:r><w:rPr>...</w:rPr><w:delText>文本</w:delText></w:r>
</w:del><w:ins><w:del><w:r><w:delText><w:t>| Rule | Requirement |
|---|---|
| RSID values | 8-digit uppercase hex: |
| Whitespace | |
| Revision structure | |
references/EditingGuide.md| 规则 | 要求 |
|---|---|
| RSID值 | 8位大写十六进制: |
| 空白字符 | 首尾空格需添加 |
| 修订结构 | |
references/EditingGuide.md