docx
当用户需要创建、读取、编辑或处理 Word 文档(.docx)时,使用此技能。触发场景包括提到“Word 文档”、“.docx”,或要求生成带目录、标题、页码、信头等格式的专业文档;也包括提取或重组 .docx 内容、插入或替换图片、在 Word 文件中查找替换、处理修订或批注,以及将内容整理为正式 Word 文档。如果用户要求生成“报告”“备忘录”“信函”“模板”等 Word / .docx 交付物,也应使用此技能。不要用于 PDF、电子表格、Google Docs,或与文档生成无关的一般编程任务。
git clone --depth 1 https://github.com/agentscope-ai/QwenPaw /tmp/docx && cp -r /tmp/docx/src/qwenpaw/agents/skills/docx-zh ~/.claude/skills/docxSKILL.md
> **重要:** 所有 `scripts/` 路径均相对于本技能目录。
> 运行方式: `cd {this_skill_dir} && python scripts/...`
> 或使用 `execute_shell_command` 的 `cwd` 参数。
# DOCX 创建、编辑与分析
## 前置依赖
- **docx** (`npm install -g docx`): 新文档创建
- **LibreOffice** (`soffice`): `.doc` -> `.docx` 转换、修订接受和 PDF 导出
- **pandoc**: 文本提取
- **pdftoppm** (poppler-utils): 文档转图片工作流
- 如果 `pdftoppm` 不可用,Python 备用路径可能使用 `pdf2image`。
- 在 Windows 上,依赖项必须已安装并在 `PATH` 中可用;如缺失,请报告依赖问题并停止(不要反复重试)。
## 概述
.docx 文件是包含 XML 文件的 ZIP 压缩包。
## 快速参考
| 任务 | 方法 |
|------|------|
| 读取/分析内容 | `pandoc` 或解压获取原始 XML |
| 创建新文档 | 使用 `docx-js` - 参见下方"创建新文档" |
| 编辑现有文档 | 解压 → 编辑 XML → 重新打包 - 参见下方"编辑现有文档" |
### 将 .doc 转换为 .docx
旧版 `.doc` 文件必须先转换才能编辑:
```bash
python scripts/office/soffice.py --headless --convert-to docx document.doc
```
### 读取内容
```bash
# 提取包含修订的文本
pandoc --track-changes=all document.docx -o output.md
# 访问原始 XML
python scripts/office/unpack.py document.docx unpacked/
```
### 转换为图片
```bash
python scripts/office/soffice.py --headless --convert-to pdf document.docx
pdftoppm -jpeg -r 150 document.pdf page
```
### 接受修订
生成接受所有修订后的干净文档(需要 LibreOffice):
```bash
python scripts/accept_changes.py input.docx output.docx
```
---
## 创建新文档
使用 JavaScript 生成 .docx 文件,然后进行验证。安装: `npm install -g docx`
### 初始设置
```javascript
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,
Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink,
TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType,
VerticalAlign, PageNumber, PageBreak } = require('docx');
const doc = new Document({ sections: [{ children: [/* content */] }] });
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer));
```
### 验证
创建文件后进行验证。如果验证失败,解压、修复 XML 并重新打包。
```bash
python scripts/office/validate.py doc.docx
```
### 页面尺寸
```javascript
// 关键: docx-js 默认为 A4,而非 US Letter
// 始终显式设置页面尺寸以获得一致的结果
sections: [{
properties: {
page: {
size: {
width: 12240, // 8.5 英寸(DXA 单位)
height: 15840 // 11 英寸(DXA 单位)
},
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } // 1 英寸边距
}
},
children: [/* content */]
}]
```
**常见页面尺寸(DXA 单位,1440 DXA = 1 英寸):**
| 纸张 | 宽度 | 高度 | 内容宽度(1 英寸边距) |
|------|------|------|----------------------|
| US Letter | 12,240 | 15,840 | 9,360 |
| A4(默认) | 11,906 | 16,838 | 9,026 |
**横向方向:** docx-js 在内部会交换宽度/高度,因此传入纵向尺寸并让其处理交换:
```javascript
size: {
width: 12240, // 将短边作为 width 传入
height: 15840, // 将长边作为 height 传入
orientation: PageOrientation.LANDSCAPE // docx-js 会在 XML 中交换它们
},
// 内容宽度 = 15840 - 左边距 - 右边距(使用长边)
```
### 样式(覆盖内置标题)
使用 Arial 作为默认字体(通用支持)。标题保持黑色以确保可读性。
```javascript
const doc = new Document({
styles: {
default: { document: { run: { font: "Arial", size: 24 } } }, // 默认 12pt
paragraphStyles: [
// 重要: 使用精确的 ID 来覆盖内置样式
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 32, bold: true, font: "Arial" },
paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // outlineLevel 是目录所必需的
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
run: { size: 28, bold: true, font: "Arial" },
paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },
]
},
sections: [{
children: [
new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Title")] }),
]
}]
});
```
### 列表(绝对不要使用 Unicode 符号)
```javascript
// ❌ 错误 - 绝不手动插入项目符号字符
new Paragraph({ children: [new TextRun("• Item")] }) // 错误
new Paragraph({ children: [new TextRun("\u2022 Item")] }) // 错误
// ✅ 正确 - 使用 LevelFormat.BULLET 的编号配置
const doc = new Document({
numbering: {
config: [
{ reference: "bullets",
levels: [{ level: 0, format: LevelFormat.BULLET, text: "•", alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
{ reference: "numbers",
levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
]
},
sections: [{
children: [
new Paragraph({ numbering: { reference: "bullets", level: 0 },
children: [new TextRun("Bullet item")] }),
new Paragraph({ numbering: { reference: "numbers", level: 0 },
children: [new TextRun("Numbered item")] }),
]
}]
});
// ⚠️ 每个 reference 创建独立的编号序列
// 相同 reference = 继续编号(1,2,3 然后 4,5,6)
// 不同 reference = 重新开始(1,2,3 然后 1,2,3)
```
### 表格
**关键: 表格需要双重宽度设置** - 必须同时在表格上设置 `columnWidths` 和在每个单元格上设置 `width`。缺少任一设置,表格在某些平台上会渲染不正确。
```javascript
// 关键: 始终设置表格宽度以确保一致的渲染效果
// 关键: 使用 ShadingType.CLEAR(而非 SOLID)以防止黑色背景
const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
const borders = { top: border, bottom: 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, bottom: 80, left: 120, right: 120 }, // 单元格内边距(内部的,不会增加宽度)
children: [new Paragraph({ children: [new TextRun("Cell")] })]
})
]
})
]
})
```
**表格宽度计算:**
始终使用 `WidthType.DXA` -- `WidthType.PERCENTAGE` 在 Google Docs 中会出问题。
```javascript
// 表格宽度 = columnWidths 之和 = 内容宽度
// US Letter 配合 1 英寸边距: 12240 - 2880 = 9360 DXA
width: { size: 9360, type: WidthType.DXA },
columnWidths: [7000, 2360] // 必须加起来等于表格宽度
```
**宽度规则:**
- **始终使用 `WidthType.DXA`** -- 绝不使用 `WidthType.PERCENTAGE`(与 Google Docs 不兼容)
- 表格宽度必须等于 `columnWidths` 之和
- 单元格 `width` 必须与对应的 `columnWidth` 匹配
- 单元格 `margins` 是内部边距阿里云 CLI 中文文档镜像检索与命令辅助:先走章节索引,再下钻正文页面,给出命令前必须有本地文档证据。
用异步 Python 调用 QwenPaw 内置 Browser SDK 驱动真实浏览器。完整参考在下方;上下文压缩后请重新加载此 browser skill。
当用户明确希望连接到已运行的 Chrome 浏览器、扫描本地 CDP 端口、显式指定 `cdp_port`,或让多个 agent / 工具共享同一个浏览器时,使用本 skill。browser 默认不开放调试端口;仅当用户明确希望其他本地工具附加时才显式传入 `cdp_port`。
当用户需要控制 browser 的浏览器启动方式时,使用本 skill。browser 默认由 Playwright 直接管理、不开放调试端口(需让其他本地工具附加时显式传 `cdp_port`);`headed` 控制是否显示窗口,`private_mode` 保留用于兼容、不再改变默认行为,`browser_args` 传入额外的 Chromium 启动参数,`executable_path` 指定自定义浏览器可执行文件路径。
当需要主动向用户、会话或频道单向发送消息时,使用本 skill。通常仅在用户明确要求向某个 channel / 会话发送消息,或需要主动通知时使用。先用 qwenpaw chats list 查询 session,再用 qwenpaw channels send 推送消息。
当你需要咨询其他 agent、寻求帮助,或用户明确要求某个 agent 参与时,使用本 skill。
Use computer_use for live Windows or macOS GUI work that structured tools cannot complete. Discover an approved app and window, act from fresh observations, and verify every requested result.
仅在需要未来定时执行或周期执行任务时,使用本 skill。使用 qwenpaw cron list/create/get/state/update/pause/resume/delete/run 管理任务,并始终显式传入 --agent-id。