返回顶部
f

fill-docx-template填充文档模板

当用户需要基于模板填充 Word 文档(.docx)、从模板生成报告、创建包含动态数据的合同,或自动化文档生成时使用此技能。包括替换普通占位符 {name} 替换文本、使用 {name|r:x,c:y} 格式标记的智能表格填充(支持从标记行开始向下填充,保留上方内容)、插入图片、批量生成文档等。如果用户提及 .docx 模板、邮件合并功能或以编程方式填写 Word 表单,请使用此技能。

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.1.2
安全检测
已通过
303
下载量
免费
免费
1
收藏
概述
安装方式
版本历史

fill-docx-template

Word 文档模板填充指南

概述

本指南介绍如何使用 Python 向 Word(.docx)模板填充动态数据。支持:

  • - 普通占位符:{variable_name} 替换文本
  • 智能表格填充:使用 {name|r:x,c:y} 标记在表格左侧任意位置,自动从标记行向下填充,保留上方内容,并自动调整表格行列数

⚠️ 1. 表格自动调整的时机与条件

表格并非总是提前自动扩展 - 这取决于占位符是否被正确识别:

  • - ✅ 会被自动调整的情况:当且仅当 {name|r:x,c:y} 格式完全正确且位于该行的最左侧单元格(第一列)时,表格会在 DocxTemplateFiller 初始化时立即调整为声明的行列数
  • 不会被调整的情况:如果占位符格式错误、包含空格(如 {name | r:5, c:4})、或不在第一列,表格将保持原样,不会自动扩展或收缩

⚠️ 2. 普通占位符一般情况下需要被覆盖!

  • - 除非未提供值时保留原样

❌3. 任何情况下不能修改、覆盖模板文件!

⚠️4. 尽量使用DocxTemplateFiller类的方法实现所有功能!

快速开始

python
from docx import Document
from docx.shared import Inches
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
import re
import os

class DocxTemplateFiller:
def init(self, template_path):
if not os.path.exists(template_path):
raise FileNotFoundError(f模板文件不存在: {template_path})
self.doc = Document(template_path)
self.templatepath = templatepath
self.named_tables = {} # 存储表格信息

# 初始化时扫描表格占位符
self.processtable_placeholders()

def processtable_placeholders(self):

扫描所有表格的每一行第一个单元格,查找 {name|r:x,c:y} 格式
例如:{products|r:5,c:4} 表示从当前行开始,共5行,4列

pattern = re.compile(r\{(\w+)\|r:(\d+),c:(\d+)\})

for table_idx, table in enumerate(self.doc.tables):
for row_idx, row in enumerate(table.rows):
if len(row.cells) == 0:
continue

# 检查每行的第一个单元格(最左侧)
first_cell = row.cells[0]
text = first_cell.text.strip()
match = pattern.search(text)

if match:
name = match.group(1)
target_rows = int(match.group(2))
target_cols = int(match.group(3))

# 保存表格配置信息
self.named_tables[name] = {
table: table,
startrow: rowidx, # 占位符所在行(从此行开始填充)
targetrows: targetrows, # 需要填充的总行数(包括占位符行)
targetcols: targetcols # 目标列数
}

# 调整表格大小:上方保留 rowidx 行,从 rowidx 开始有 target_rows 行
self.resizetable(table, rowidx, targetrows, target_cols)

# 清除占位符文本(可选,因为填充时会覆盖,但清除更干净)
# 保留单元格其他可能的文本(占位符前后文本)
newtext = pattern.sub(, firstcell.text).strip()
if new_text:
firstcell.text = newtext
else:
first_cell.text = # 清空等待填充

def resizetable(self, table, startrow, targetrows, target_cols):
调整表格大小:确保从 startrow 开始有 targetrows 行,总列数为 target_cols
totalneededrows = startrow + targetrows
current_rows = len(table.rows)
current_cols = len(table.columns) if table.columns else 0

# 调整行数
if totalneededrows > current_rows:
# 添加行
for in range(totalneededrows - currentrows):
table.add_row()
elif totalneededrows < current_rows:
# 删除多余行(从末尾删除,保留前面的)
self.deleterowsfromend(table, currentrows - totalneeded_rows)

# 调整列数
if targetcols != currentcols:
self.resizecolumns(table, target_cols)

def deleterowsfromend(self, table, num_rows):
从表格末尾删除指定行数
tbl = table._tbl
for in range(numrows):
if len(table.rows) > 0:
tr = table.rows[-1]._tr
tbl.remove(tr)

def resizecolumns(self, table, target_cols):
调整表格列数
current_cols = len(table.columns)
tbl = table._tbl
tblGrid = tbl.find(qn(w:tblGrid))

if targetcols > currentcols:
# 添加列定义
for in range(targetcols - current_cols):
gridCol = OxmlElement(w:gridCol)
tblGrid.append(gridCol)

# 为每一行添加单元格
for row in table.rows:
for in range(targetcols - current_cols):
tc = OxmlElement(w:tc)
tcPr = OxmlElement(w:tcPr)
tc.append(tcPr)
p = OxmlElement(w:p)
tc.append(p)
row._tr.append(tc)

elif targetcols < currentcols:
# 删除多余列定义
for in range(currentcols - target_cols):
if len(tblGrid) > 0:
tblGrid.remove(tblGrid[-1])

# 从每行删除多余单元格
for row in table.rows:
for in range(currentcols - target_cols):
tcs = row._tr.findall(qn(w:tc))
if len(tcs) > target_cols:
row._tr.remove(tcs[-1])

def fillplaceholders(self, datadict):
替换普通占位符 {key}(不包括表格定义格式)
# 匹配普通占位符,排除表格定义格式
pattern = re.compile(r\{(\w+)\}(?!\|r:\d+,c:\d+))

# 处理段落
for para in self.doc.paragraphs:
self.replaceinparagraph(para, pattern, datadict)

# 处理表格内的普通占位符(排除已识别的表格占位符单元格)
for table in self.doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
self.replaceinparagraph(para, pattern, datadict)

def replaceinparagraph(self, paragraph, pattern, datadict):
在段落中执行替换
text = paragraph.text
matches = pattern.findall(text)

if not matches:
return

new_text = text
for key in matches:
if key in data_dict:
placeholder = f{{{key}}}
value = str(data_dict[key])
newtext = newtext.replace(placeholder, value)

if new_text != text and paragraph.runs:
paragraph.runs[0].text = new_text
for run in paragraph.runs[1:]:
run.text =

def fillnamedtable(self, table_name, data):

填充指定名称的表格
从占位符所在行开始(包括该行)向下填充,保留上方内容

:param table_name: 表格名称(来自占位符 {name|r:x,c:y})
:param data: 二维列表,如 [[产品A, 规格1, 10], [...]]

if tablename not in self.namedtables:
raise KeyError(f未找到名为 {tablename} 的表格,请确保模板中存在 {{{tablename}|r:x,c:y}} 格式的占位符在最左侧单元格)

tableinfo = self.namedtables[table_name]
table = table_info[table]
startrow = tableinfo[start_row]
targetrows = tableinfo[target_rows]
targetcols = tableinfo[target_cols]

# 确保数据不超过声明的行数
if len(data) > target_rows:
data = data[:target_rows]

# 从 start_row 开始填充(包括该行)
for rowoffset, rowdata in enumerate(data):
actualrowidx

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 fill-docx-template-1776072988 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 fill-docx-template-1776072988 技能

通过命令行安装

skillhub install fill-docx-template-1776072988

下载

⬇ 下载 fill-docx-template v1.1.2(免费)

文件大小: 7.59 KB | 发布时间: 2026-4-15 12:44

v1.1.2 最新 2026-4-15 12:44
- Removed the LICENSE.txt file.
- No other functionality or documentation changes.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部