关于 docx-svg
docx-svg 是一项为 Word 文档添加原生 SVG 图片支持的技能,面向以程序方式生成 DOCX 的用户。它优先使用 officecli,并提供基于 Python 的备用方案,避免插入前将图像栅格化。
主要功能
- 01通过 officecli 插入 SVG 图片
- 02为 python-docx 和 docxtpl 添加 SVG 支持
- 03设置图片尺寸、位置和文字环绕
- 04从 SVG 属性或 viewBox 读取尺寸
适用场景
- 01在 Word 报告中插入矢量图表
- 02在 docxtpl 模板中填充 SVG 图片
- 03为 DOCX 图片设置尺寸和版面属性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jr2804/ prompts --skill docx-svg安装后在 Claude Code 中输入/docx-svg确认已加载。
附带文件scripts/svg.py
详细介绍
DOCX SVG——为 Word 文档提供 SVG 图像支持
策略:零转换(强制要求)
在插入到 .docx 之前,绝不将 SVG 文件转换为 PNG、JPEG 或任何栅格格式。
现代版 Word(2016+)通过 asvg:svgBlip OOXML 扩展原生支持 SVG。转换为 PNG 会破坏矢量图的优势(可缩放、文件体积小、清晰度高)。
- 不要将栅格格式作为“最佳实践”推荐,除非用户明确要求兼容旧版。
- 不要声称直接处理 OOXML“过于复杂”——本技能提供了处理此复杂问题的工具(
officecli或scripts/svg.py)。 - 始终直接使用 SVG 作为源文件。
- 如果请求要求将 SVG 转换为 PNG/JPEG 以插入 .docx,请拒绝转换步骤,改为直接插入 SVG。
概述
Microsoft Word 支持 OOXML 格式中的 SVG 图像,但常见的编程工具(python-docx、docxtpl)默认无法识别。本技能提供了两种方案,按优先级排列:
| 优先级 | 工具 | 使用时机 |
|---|---|---|
| 1. 首选 | officecli | 只要环境中可用,就始终使用 |
| 2. 备用方案 | Python monkey-patch(scripts/svg.py) | 未安装 officecli、无法访问 officecli,或版本检查未通过时 |
如果存在 officecli,但版本低于 v1.0.64,请勿使用。应改用 Python 备用方案。不要尝试使用不完整或过时的 officecli 安装。
策略:先检查 officecli
选择方案之前,先确认 officecli 是否可用:
officecli --version
如果返回的版本为 v1.0.64 或更高版本:使用 officecli(见下文第 1 节)。 如果未找到,或版本低于 v1.0.64:使用 Python 备用方案(见下文第 2 节)。
技术背景:工作原理(OOXML)
插入 SVG 时,Word 要求在 a:blip 元素中包含 a:ext 块。officecli 和 scripts/svg.py 都会自动生成此结构。
结构参考(供了解):
<a:blip r:embed="rId1">
<a:extLst>
<a:ext uri="{96DAC541-0531-4A20-96AC-8D759B1F206D}">
<asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG" r:embed="rId2"/>
</a:ext>
</a:extLst>
</a:blip>
rId1指向 PNG/JPEG 备用图像(现代版 Word 中为可选项;如有需要,officecli会处理)。rId2指向word/media/中实际的.svg文件。
第 1 节:首选方案——officecli
officecli 原生支持 docx 图片中的 SVG。无需 monkey-patch、无需额外依赖,也无需 Python。
添加行内 SVG 图像
officecli add report.docx /body --type picture --prop file=chart.svg
添加并指定尺寸
officecli add report.docx /body --type picture --prop file=chart.svg --prop width=10cm --prop height=6cm
在特定段落之后添加
officecli add report.docx '/body/p[2]' --type picture --prop file=chart.svg --prop width=12cm
添加浮动图像并设置文字环绕
# Insert as floating image, then set wrap and position
officecli add report.docx /body --type picture --prop file=hero.svg --prop width=8cm
# Use the returned picture path to set wrap mode
officecli set report.docx '/body/pic[1]' --prop wrap=square
设置图像属性
添加图片后,使用 officecli set 进行调整:
officecli set report.docx '/body/p[3]/picture[1]' --prop alt="Sales chart Q4"
officecli set report.docx '/body/p[3]/picture[1]' --prop brightness=10 --prop contrast=-5
officecli set report.docx '/body/p[3]/picture[1]' --prop hposition=2cm --prop hrelative=page
查看可用的图片属性
不确定属性名称时,请运行帮助系统:
officecli help docx image
officecli help docx picture
第 2 节:备用方案——Python monkey-patch
仅在 officecli 不可用时使用此方案。模块 scripts/svg.py 会对 python-docx 和 docxtpl 执行 monkey-patch,以添加 SVG 支持。
导入模块后会自动应用补丁——安装依赖项后无需手动设置。
安装依赖项
uv run python scripts/svg.py
脚本通过 PEP 723 内联元数据声明依赖项(python-docx>=1.1.2、docxtpl>=0.19.0),因此 uv run 会自动解析并安装这些依赖项。
直接使用 python-docx
import docx
from scripts import svg # noqa: F401 # <- patch activates on import
from docx.shared import Mm
doc = docx.Document()
doc.add_paragraph("Below is an SVG chart:")
doc.add_picture("chart.svg", width=Mm(120))
doc.save("report.docx")
导入 scripts.svg 会对 python-docx 进行全局 monkey-patch。现在,add_picture 除了接受 PNG/JPEG 文件外,也会接受 .svg 文件。
**重要:**即使使用 Python 备用方案,也不要转换为 PNG。该补丁会处理原生 SVG 嵌入。
docxtpl 模板用法
from docxtpl import DocxTemplate
from scripts.svg import SvgInlineImage
from docx.shared import Mm
tpl = DocxTemplate("template.docx")
img = SvgInlineImage(tpl, "chart.svg", width=Mm(100))
tpl.render({"chart": img})
tpl.save("output.docx")
在模板的段落中放入 {{ chart }}。SvgInlineImage
会自动检测 SVG 文件,并通过修补后的处理流程处理。
自动调整尺寸
如果同时省略 width 和 height,图片将填满可用页面宽度 (页面宽度减去左右页边距):
img = SvgInlineImage(tpl, "wide-chart.svg") # auto-sizes to page width
实用工具:检查文件是否为 SVG
from scripts.svg import is_svg
assert is_svg("icon.svg")
Python 回退方案的工作原理
-
导入时进行 Monkey patch —— 模块会注册三个 SVG 字节签名 (
<?xml、<svg、<!DOCTYPE svg),将image/svg+xml添加到 python-docx 的 MIME 类型常量中,并替换_ImageHeaderFactory,使其扫描 256 字节(而不是默认的 64 字节)。 -
提取 SVG 尺寸 ——
Svg._dimensions_from_stream会读取width/height属性(去除 pt、cm、mm、% 等单位),并在这些属性缺失时回退到viewBox。 -
docxtpl 辅助工具 ——
SvgInlineImage是InlineImage的子类, 会先将Path描述符转换为BytesIO,再传递给上游,以便修补后的工厂解析 SVG。
限制
- 在 Word 中渲染 SVG:Microsoft Word 会将 SVG 渲染为静态图像。 OOXML 格式不支持交互功能(悬停、动画、嵌入式 JavaScript)。
- 回退图像(仅 Python 方案):当前实现不会在 OOXML 包中添加 PNG 回退图像。较旧版本的 Word (2016 年之前)可能无法显示 SVG。如果需要兼容,请预先将 SVG 转换为 PNG。
- 尺寸单位(仅 Python 方案):解析器会以 72 DPI 将所有单位标准化为像素。若要实现适合打印的精确尺寸,请通过
docx.shared.Mm/Inches/Cm显式指定width/height。