Python实现Word文档带格式复制追加及批量生成收据问题
解决Python复制Word内容保留格式并批量生成收据的方案
方案一:使用win32com.client(推荐,完整保留格式)
直接调用本地Word应用的接口,依托Word原生功能实现格式完整复制,适配复杂样式场景,批量处理效率高。
核心代码示例
import win32com.client as win32 import os import shutil def append_template_to_target(template_path, target_path): # 启动Word后台进程 word = win32.gencache.EnsureDispatch('Word.Application') word.Visible = False try: # 打开目标文档与模板文档 target_doc = word.Documents.Open(os.path.abspath(target_path)) template_doc = word.Documents.Open(os.path.abspath(template_path)) # 复制模板全部内容 template_doc.Content.Select() word.Selection.Copy() # 定位到目标文档末尾,按原格式粘贴 target_doc.Content.End() word.Selection.PasteAndFormat(16) # 16对应Word的wdFormatOriginalFormatting常量 # 保存并关闭文档 target_doc.Save() target_doc.Close() template_doc.Close() except Exception as e: print(f"处理出错:{e}") finally: word.Quit() # 批量生成收据示例 template_path = "TEMP.docx" base_receipt_path = "基础收据模板.docx" for idx in range(1, 6): # 生成5份收据 target_path = f"收据_{idx}.docx" # 复制基础模板作为新收据的基底 shutil.copy(base_receipt_path, target_path) # 追加带格式的模板内容 append_template_to_target(template_path, target_path)
注意事项
- 需安装依赖库:
pip install pywin32 - 运行环境必须安装Microsoft Word
- 若出现常量找不到的问题,直接用数字16替代
wdFormatOriginalFormatting即可
方案二:优化python-docx的样式复制(适合简单格式)
不依赖Word应用,但仅适配基础格式场景,复杂元素(如表格、图片、多级列表)需额外处理。
核心代码示例
from docx import Document def copy_paragraph_style(src_para, dest_doc): dest_para = dest_doc.add_paragraph() # 复制段落样式与格式 dest_para.style = src_para.style dest_para.alignment = src_para.alignment dest_para.paragraph_format.line_spacing = src_para.paragraph_format.line_spacing # 复制每个文本片段的格式 for src_run in src_para.runs: dest_run = dest_para.add_run(src_run.text) dest_run.font.name = src_run.font.name dest_run.font.size = src_run.font.size dest_run.font.bold = src_run.font.bold dest_run.font.italic = src_run.font.italic dest_run.font.color.rgb = src_run.font.color.rgb def copy_table_style(src_table, dest_doc): dest_table = dest_doc.add_table(rows=len(src_table.rows), cols=len(src_table.columns)) dest_table.style = src_table.style # 复制单元格内容与基础样式 for i, row in enumerate(src_table.rows): for j, cell in enumerate(row.cells): dest_table.cell(i,j).text = cell.text if cell.paragraphs: dest_table.cell(i,j).paragraphs[0].style = cell.paragraphs[0].style def append_docx(src_path, dest_path): src_doc = Document(src_path) dest_doc = Document(dest_path) # 复制段落 for para in src_doc.paragraphs: copy_paragraph_style(para, dest_doc) # 复制表格 for table in src_doc.tables: copy_table_style(table, dest_doc) dest_doc.save(dest_path) # 批量使用示例 template_path = "TEMP.docx" base_receipt_path = "基础收据模板.docx" for idx in range(1, 6): target_path = f"收据_{idx}.docx" shutil.copy(base_receipt_path, target_path) append_docx(template_path, target_path)
局限性
- 无法复制页眉页脚、图片、特殊样式等复杂元素
- 需针对不同元素类型单独编写复制逻辑,代码复杂度较高
单页内容控制建议
- 预先在
TEMP.docx模板中调整排版,确保内容本身不超出单页 - 使用win32com方案时,可在粘贴后检查页面数并自动调整:
# 检查文档页数(2对应wdStatisticPages常量) if target_doc.ComputeStatistics(2) > 1: # 缩小所有段落行间距 for para in target_doc.Content.Paragraphs: para.LineSpacing = para.LineSpacing * 0.9 target_doc.Save()
内容的提问来源于stack exchange,提问作者GiantMind
相关产品推荐
相关产品推荐

