文档处理类 Skills 详解
深入解析 Claude 文档能力的核心实现:docx、pdf、pptx、xlsx
本章概览
这四个 Skills 是 Claude 文档处理能力的核心实现,属于"源码可见但非开源"(source-available),仅供参考学习。
| Skill | 用途 | 核心技术 |
|---|---|---|
| docx | Word 文档处理 | docx-js (创建), OOXML (编辑) |
| PDF 文档处理 | pypdf, pdfplumber, reportlab | |
| pptx | PPT 演示文稿处理 | html2pptx, OOXML |
| xlsx | Excel 电子表格处理 | openpyxl, pandas |
1. DOCX Skill(Word 文档处理)
1.1 概述
yaml
name: docx
description: "Comprehensive document creation, editing, and analysis
with support for tracked changes, comments, formatting preservation,
and text extraction. When Claude needs to work with professional
documents (.docx files) for: (1) Creating new documents,
(2) Modifying or editing content, (3) Working with tracked changes,
(4) Adding comments, or any other document tasks"1.2 理解 DOCX 格式
核心概念:.docx 文件本质上是一个 ZIP 压缩包,内含 XML 文件和资源。
document.docx (ZIP 压缩包)
├── word/
│ ├── document.xml # 主文档内容
│ ├── comments.xml # 批注
│ ├── styles.xml # 样式定义
│ └── media/ # 嵌入的图片和媒体
├── [Content_Types].xml # 内容类型定义
└── _rels/ # 关系定义1.3 工作流决策树
用户任务 → 类型是什么?
│
├─ 读取/分析内容
│ ├─ 只需文本 → pandoc 转 markdown
│ └─ 需要批注/格式 → 解包读取 XML
│
├─ 创建新文档 → 使用 docx-js
│
└─ 编辑现有文档
├─ 自己的文档 + 简单修改 → OOXML 直接编辑
└─ 他人文档 / 正式场合 → 红线标记工作流1.4 文本提取
使用 Pandoc
bash
# 转换为 Markdown(保留修订标记)
pandoc --track-changes=all path-to-file.docx -o output.md
# 选项:--track-changes=accept/reject/all解包读取 XML
bash
# 解包
python ooxml/scripts/unpack.py document.docx unpacked/
# 关键文件
# word/document.xml - 主内容
# word/comments.xml - 批注
# 修订标记:<w:ins>(插入)和 <w:del>(删除)1.5 创建新文档(docx-js)
使用 JavaScript/TypeScript 的 docx-js 库:
javascript
import { Document, Packer, Paragraph, TextRun } from "docx";
const doc = new Document({
sections: [{
children: [
new Paragraph({
children: [
new TextRun({ text: "Hello World", bold: true }),
new TextRun({ text: " - This is a document" }),
],
}),
],
}],
});
// 导出为 .docx
const buffer = await Packer.toBuffer(doc);
fs.writeFileSync("output.docx", buffer);1.6 红线标记工作流(Redlining)
适用场景:
- 编辑他人文档
- 法律、学术、商业、政府文档
- 需要追踪修改记录
核心原则:最小化、精确编辑
python
# ❌ 错误 - 替换整个句子
'<w:del><w:delText>The term is 30 days.</w:delText></w:del>'
'<w:ins><w:t>The term is 60 days.</w:t></w:ins>'
# ✓ 正确 - 只标记实际变化的部分
'<w:r><w:t>The term is </w:t></w:r>'
'<w:del><w:delText>30</w:delText></w:del>'
'<w:ins><w:t>60</w:t></w:ins>'
'<w:r><w:t> days.</w:t></w:r>'完整工作流
mermaid
graph TB
A[获取 Markdown 表示] --> B[识别并分组修改]
B --> C[读取文档并解包]
C --> D[分批实现修改]
D --> E[打包文档]
E --> F[最终验证]1.7 转换为图片
bash
# 步骤 1: DOCX → PDF
soffice --headless --convert-to pdf document.docx
# 步骤 2: PDF → JPEG
pdftoppm -jpeg -r 150 document.pdf page
# 生成 page-1.jpg, page-2.jpg, ...2. PDF Skill(PDF 文档处理)
2.1 概述
yaml
name: pdf
description: Comprehensive PDF manipulation toolkit for extracting text
and tables, creating new PDFs, merging/splitting documents, and handling
forms. When Claude needs to fill in a PDF form or programmatically
process, generate, or analyze PDF documents at scale.2.2 Python 库选择
| 任务 | 推荐库 | 用途 |
|---|---|---|
| 基本操作 | pypdf | 合并、拆分、旋转、元数据 |
| 文本/表格提取 | pdfplumber | 带布局的文本、表格数据 |
| 创建 PDF | reportlab | 从头创建专业文档 |
| OCR 扫描件 | pytesseract + pdf2image | 识别扫描文档中的文字 |
2.3 常用操作
合并 PDF
python
from pypdf import PdfWriter, PdfReader
writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("merged.pdf", "wb") as output:
writer.write(output)拆分 PDF
python
reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as output:
writer.write(output)提取表格
python
import pdfplumber
import pandas as pd
with pdfplumber.open("document.pdf") as pdf:
all_tables = []
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
if table:
df = pd.DataFrame(table[1:], columns=table[0])
all_tables.append(df)
# 合并所有表格
combined_df = pd.concat(all_tables, ignore_index=True)
combined_df.to_excel("extracted_tables.xlsx", index=False)创建 PDF
python
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("report.pdf", pagesize=letter)
styles = getSampleStyleSheet()
story = []
# 添加内容
story.append(Paragraph("Report Title", styles['Title']))
story.append(Spacer(1, 12))
story.append(Paragraph("This is the body...", styles['Normal']))
# 构建 PDF
doc.build(story)2.4 命令行工具
bash
# pdftotext - 提取文本
pdftotext -layout input.pdf output.txt
# qpdf - 合并/拆分
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
# pdfimages - 提取图片
pdfimages -j input.pdf output_prefix2.5 快速参考
| 任务 | 工具 | 命令/代码 |
|---|---|---|
| 合并 | pypdf | writer.add_page(page) |
| 拆分 | pypdf | 每页一个文件 |
| 提取文本 | pdfplumber | page.extract_text() |
| 提取表格 | pdfplumber | page.extract_tables() |
| 创建 | reportlab | Canvas 或 Platypus |
| 命令行合并 | qpdf | qpdf --empty --pages ... |
| OCR 扫描件 | pytesseract | 先转图片 |
| 填写表单 | pdf-lib 或 pypdf | 见 forms.md |
3. PPTX Skill(PowerPoint 处理)
3.1 概述
yaml
name: pptx
description: "Presentation creation, editing, and analysis. When Claude
needs to work with presentations (.pptx files) for: (1) Creating new
presentations, (2) Modifying or editing content, (3) Working with layouts,
(4) Adding comments or speaker notes, or any other presentation tasks"3.2 理解 PPTX 格式
与 DOCX 类似,PPTX 也是 ZIP 压缩包:
presentation.pptx (ZIP)
├── ppt/
│ ├── presentation.xml # 演示文稿元数据
│ ├── slides/
│ │ ├── slide1.xml # 各幻灯片内容
│ │ └── slide2.xml
│ ├── notesSlides/ # 演讲者备注
│ ├── slideLayouts/ # 布局模板
│ ├── slideMasters/ # 母版
│ ├── theme/ # 主题和样式
│ └── media/ # 图片和媒体
└── ...3.3 工作流决策
用户任务 → 类型是什么?
│
├─ 读取/分析内容 → markitdown 转 Markdown
│
├─ 从零创建(无模板) → html2pptx 工作流
│
├─ 基于模板创建 → 模板复用工作流
│
└─ 编辑现有演示文稿 → OOXML 编辑工作流3.4 从零创建(html2pptx)
设计原则
关键:在编码前,分析内容并选择合适的设计元素:
- 考虑主题:演示文稿关于什么?暗示什么调性?
- 检查品牌:是否提到公司/组织?考虑品牌色
- 匹配配色:选择反映主题的颜色
- 说明方法:在编码前解释设计选择
配色方案示例
css
/* 经典蓝 */
--navy: #1C2833;
--slate: #2E4053;
--silver: #AAB7B8;
--off-white: #F4F6F6;
/* 青橙珊瑚 */
--teal: #5EA8A7;
--coral: #FE4447;
/* 森林绿 */
--black: #191A19;
--green: #4E9F3D;
--dark-green: #1E5128;
/* 复古彩虹 */
--purple: #722880;
--pink: #D72D51;
--orange: #EB5C18;工作流程
mermaid
graph TB
A[阅读 html2pptx.md] --> B[为每张幻灯片创建 HTML]
B --> C[使用 html2pptx.js 转换]
C --> D[使用 PptxGenJS 添加图表/表格]
D --> E[保存演示文稿]
E --> F[生成缩略图验证]
F --> G{布局正确?}
G -->|否| H[调整 HTML 并重新生成]
G -->|是| I[完成]
H --> B3.5 基于模板创建
完整工作流
bash
# 1. 提取模板内容并创建缩略图
python -m markitdown template.pptx > template-content.md
python scripts/thumbnail.py template.pptx
# 2. 分析模板,保存清单到 template-inventory.md
# 3. 创建内容大纲和模板映射
# template_mapping = [0, 34, 34, 50, 54]
# 4. 重排幻灯片
python scripts/rearrange.py template.pptx working.pptx 0,34,34,50,52
# 5. 提取所有文本
python scripts/inventory.py working.pptx text-inventory.json
# 6. 生成替换文本,保存到 replacement-text.json
# 7. 应用替换
python scripts/replace.py working.pptx replacement-text.json output.pptx清单 JSON 结构
json
{
"slide-0": {
"shape-0": {
"placeholder_type": "TITLE",
"left": 1.5,
"top": 2.0,
"width": 7.5,
"height": 1.2,
"paragraphs": [
{
"text": "Paragraph text",
"bullet": true,
"level": 0,
"alignment": "CENTER",
"font_size": 14.0,
"bold": true
}
]
}
}
}3.6 视觉设计技巧
几何图案
- 对角分割线替代水平线
- 不对称列宽(30/70, 40/60)
- 90° 或 270° 旋转的文本标题
- 圆形/六边形图片框架
边框处理
- 单边粗边框(10-20pt)
- 双线边框,颜色对比
- 角括号替代完整边框
- L 形边框(上+左或下+右)
字体排版
- 极端大小对比(72pt 标题 vs 11pt 正文)
- 全大写标题 + 宽字距
- 等宽字体用于数据/统计
- 压缩字体用于密集信息
4. XLSX Skill(Excel 处理)
4.1 概述
yaml
name: xlsx
description: "Comprehensive spreadsheet creation, editing, and analysis
with support for formulas, formatting, data analysis, and visualization.
When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc)
for: (1) Creating new spreadsheets with formulas and formatting,
(2) Reading or analyzing data, (3) Modify existing spreadsheets while
preserving formulas, (4) Data analysis and visualization in spreadsheets,
or (5) Recalculating formulas"4.2 金融模型规范
零公式错误
每个 Excel 模型必须交付时没有公式错误:
#REF!- 无效引用#DIV/0!- 除零错误#VALUE!- 值类型错误#N/A- 值不可用#NAME?- 未识别的名称
颜色编码标准
| 颜色 | 用途 |
|---|---|
| 蓝色文字 (0,0,255) | 硬编码输入,用户可修改的数字 |
| 黑色文字 (0,0,0) | 所有公式和计算 |
| 绿色文字 (0,128,0) | 从同一工作簿其他工作表拉取的链接 |
| 红色文字 (255,0,0) | 到其他文件的外部链接 |
| 黄色背景 (255,255,0) | 需要关注的关键假设或需更新的单元格 |
数字格式标准
| 类型 | 格式 |
|---|---|
| 年份 | 文本格式("2024" 而非 "2,024") |
| 货币 | $#,##0;在标题中指定单位("收入 ($mm)") |
| 零值 | 使用 "-",包括百分比 |
| 百分比 | 默认 0.0%(一位小数) |
| 倍数 | 0.0x(用于 EV/EBITDA, P/E 等) |
| 负数 | 使用括号 (123) 而非减号 -123 |
4.3 核心原则:使用公式,不要硬编码
python
# ❌ 错误 - 在 Python 中计算并硬编码结果
total = df['Sales'].sum()
sheet['B10'] = total # 硬编码 5000
# ✓ 正确 - 使用 Excel 公式
sheet['B10'] = '=SUM(B2:B9)'
# ❌ 错误 - Python 计算增长率
growth = (df.iloc[-1]['Revenue'] - df.iloc[0]['Revenue']) / df.iloc[0]['Revenue']
sheet['C5'] = growth
# ✓ 正确 - Excel 公式
sheet['C5'] = '=(C4-C2)/C2'4.4 常用工作流
数据分析(pandas)
python
import pandas as pd
# 读取 Excel
df = pd.read_excel('file.xlsx')
all_sheets = pd.read_excel('file.xlsx', sheet_name=None)
# 分析
df.head() # 预览数据
df.info() # 列信息
df.describe() # 统计摘要
# 写入 Excel
df.to_excel('output.xlsx', index=False)创建/编辑(openpyxl)
python
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, PatternFill, Alignment
# 创建新工作簿
wb = Workbook()
sheet = wb.active
# 添加数据
sheet['A1'] = 'Hello'
sheet.append(['Row', 'of', 'data'])
# 添加公式
sheet['B2'] = '=SUM(A1:A10)'
# 格式化
sheet['A1'].font = Font(bold=True, color='FF0000')
sheet['A1'].fill = PatternFill('solid', start_color='FFFF00')
sheet['A1'].alignment = Alignment(horizontal='center')
# 列宽
sheet.column_dimensions['A'].width = 20
wb.save('output.xlsx')编辑现有文件
python
from openpyxl import load_workbook
wb = load_workbook('existing.xlsx')
sheet = wb.active
# 修改单元格
sheet['A1'] = 'New Value'
sheet.insert_rows(2)
sheet.delete_cols(3)
# 添加新工作表
new_sheet = wb.create_sheet('NewSheet')
new_sheet['A1'] = 'Data'
wb.save('modified.xlsx')4.5 公式重新计算
openpyxl 创建的公式不会自动计算,需要使用 LibreOffice:
bash
python recalc.py output.xlsx [timeout_seconds]脚本返回 JSON 格式的结果:
json
{
"status": "success",
"total_errors": 0,
"total_formulas": 42,
"error_summary": {}
}如果有错误:
json
{
"status": "errors_found",
"total_errors": 2,
"error_summary": {
"#REF!": {
"count": 2,
"locations": ["Sheet1!B5", "Sheet1!C10"]
}
}
}4.6 公式验证清单
必要验证
- [ ] 测试 2-3 个样本引用:构建完整模型前验证正确性
- [ ] 列映射:确认 Excel 列匹配(列 64 = BL,不是 BK)
- [ ] 行偏移:Excel 行从 1 开始(DataFrame 行 5 = Excel 行 6)
常见陷阱
- [ ] NaN 处理:用
pd.notna()检查空值 - [ ] 远端列:FY 数据通常在 50+ 列
- [ ] 多重匹配:搜索所有出现,不只是第一个
- [ ] 除零错误:在公式中使用
/前检查分母 - [ ] 引用错误:验证所有单元格引用指向预期单元格
- [ ] 跨工作表引用:使用正确格式(Sheet1!A1)
4.7 库选择指南
| 场景 | 推荐 |
|---|---|
| 数据分析、批量操作 | pandas |
| 复杂格式、公式、Excel 特定功能 | openpyxl |
| 大文件读取 | openpyxl + read_only=True |
| 大文件写入 | openpyxl + write_only=True |
5. 本章小结
文档类 Skills 对比
| Skill | 创建 | 编辑 | 分析 | 核心技术 |
|---|---|---|---|---|
| docx | docx-js | OOXML | pandoc | JavaScript + Python |
| reportlab | pypdf | pdfplumber | Python | |
| pptx | html2pptx | OOXML | markitdown | JavaScript + Python |
| xlsx | openpyxl | openpyxl | pandas | Python |
共同模式
- 底层都是 XML:Office 文档都是 ZIP 压缩的 XML
- 创建与编辑分离:创建用专用库,编辑直接操作 XML
- 验证必不可少:修改后必须验证,特别是公式
- 精确修改原则:只改必要的部分,保留原有格式
工具链总结
文本提取:pandoc (docx) | pdfplumber (pdf) | markitdown (pptx) | pandas (xlsx)
创建文档:docx-js (docx) | reportlab (pdf) | html2pptx (pptx) | openpyxl (xlsx)
编辑文档:OOXML 脚本 (docx/pptx) | pypdf (pdf) | openpyxl (xlsx)
图片转换:soffice + pdftoppm (所有)上一章:创意设计类 Skills
下一章:开发工具类 Skills