Python修改word模板,替换指定的内容

1,需求

  • 客户要求每周出项目运行报告,统计某些重要用户操作情况。给定了一个word模板,现在需要通过查询数据库把相关数据填充替换,实现自动化任务处理。
  • 数据标识字段说明:文档统计时间范围,YEAR、MONTH、DAY1、DAY2;
  • 数据标识字段说明2:SQL查询统计后的用户数量{{USER_COUNT}}、所有用户操作总数量{{USER_LOG_COUNT}}、各模块操作次数统计{{USER_LOG_DETAIL_TABLE}}

2,代码实现

python 复制代码
from docx import Document
from docx.shared import Inches, Pt
from datetime import datetime, timedelta, time
import pandas as pd

# 创建 DataFrame 示例数据(15列)
df = pd.DataFrame({
    'Col1': range(1, 6),
    'Col2': ['A', 'B', 'C', 'D', 'E'],
    'Col3': [10, 20, 30, 40, 50],
    **{f'Col{i}': [i] * 5 for i in range(4, 16)}  # 生成 12 列,总列数为 15
})

# 加载 Word 模板文档
doc = Document("1.docx")

# 1. 定义占位符与目标值的映射关系
# 计算前1天和前7天的日期,提取年、月、日信息
today = datetime.now().date()
# 计算前7天/1天的日期
seven_days_ago_date = today - timedelta(days=7)
one_day_ago_date =    today - timedelta(days=1)
# 构造前7天的 00:00:00, 前1天的 23:59:59
seven_days_ago_start = datetime.combine(seven_days_ago_date, time.min)
one_day_ago_end = datetime.combine(one_day_ago_date, time.max)

replacements = {
    "YEAR":  seven_days_ago_start.year, #"2025",
    "MONTH": seven_days_ago_start.month, #"6",
    "DAY1": seven_days_ago_start.day,   #"10",
    "DAY2": one_day_ago_end.day ,       #"16",
    "{{USER_COUNT}}": "27",
    "{{USER_LOG_COUNT}}": "6789",
}
TABLE_FLAG="{{USER_LOG_DETAIL_TABLE}}"

# 2. 遍历段落并替换占位符
for paragraph in doc.paragraphs:
    for key, value in replacements.items():
        if key in paragraph.text:
            # 替换文本内容(保留原有格式)
            inline = paragraph.runs
            for run in inline:
                run.text = run.text.replace(key, str(value))
                
# 3,自定义函数:在指定段落后插入表格
def insert_table_after( doc,  TABLE_FLAG , df_final):
    """
    将表格插入到指定段落之后。
    """
    # 查找标识 "XX" 并插入表格
    for paragraph in doc.paragraphs:
        if paragraph.text.strip() == TABLE_FLAG:
            # SQL查询的df数据,添加序号列(索引 + 1)导出到word文件
            df_final = df_final.reset_index()
            df_final.insert(0, '序号', df_final['index'] + 1)
            df_final = df_final.drop(columns=['index'])

            
            # 创建表格
            rows = len(df_final) + 1  # 表头 + 数据行
            cols = len(df_final.columns)
            table = doc.add_table(rows=rows, cols=cols)

            # 设置表格边框(兼容新版)
            table.style = 'Table Grid'  # 使用内置样式设置边框

            # 填充表头
            header_cells = table.rows[0].cells
            for i, col_name in enumerate(df_final.columns):
                header_cells[i].text = str(col_name)

            # 填充数据行
            for i, row in df_final.iterrows():
                row_cells = table.rows[i + 1 ].cells #table.rows[i + 1].cells
                for j, val in enumerate(row):
                    row_cells[j].text = str(val)

            # 插入表格到段落之后
            tbl, p = table._tbl, paragraph._element
            p.addnext(tbl)
            
            # 删除原段落
            p = paragraph._element
            p.getparent().remove(p)

            # 设置表格宽度和列宽
            table.autofit = True
            #total_width = Inches(8.5)  # 适配 A4 页面宽度(约 8.5 英寸)
            #table.width = total_width
  
            # 设置字体格式与原文档一致
            default_style = doc.styles['Normal']
            for row in table.rows:
                for cell in row.cells:
                    for paragraph in cell.paragraphs:
                        paragraph.style = default_style
                        # 设置字体大小
                        paragraph.style.font.size = Pt(11)  # 根据需要调整字体大小
                        # 设置自动换行
                        paragraph.alignment = 1  # 左对齐
                        paragraph.paragraph_format.word_wrap = True  # 自动换行

            break  # 只替换第一个匹配项

# 保存修改后的文档
insert_table_after( doc, TABLE_FLAG, df )
doc.save("11.docx")

3,验证结果