Python基础教学:Python的openpyxl和python-docx模块结合Excel和Word模板进行数据写入-由Deepseek产生
我将为您介绍如何使用Python的openpyxl和python-docx模块结合Excel和Word模板进行数据写入。以下是几个具体案例:
案例1:从Excel读取数据并填充到Word模板
1.1 准备工作
首先安装所需模块:
pip install openpyxl python-docx
1.2 Excel数据文件 (data.xlsx)
| 姓名 | 年龄 | 职位 | 部门 | 入职日期 |
|---|---|---|---|---|
| 张三 | 28 | 工程师 | 技术部 | 2020-01-15 |
| 李四 | 32 | 经理 | 市场部 | 2018-05-20 |
1.3 Word模板文件 (template.docx)
在Word中创建包含占位符的模板:
员工信息报告姓名:{姓名}
年龄:{年龄}
职位:{职位}
部门:{部门}
入职日期:{入职日期}报告生成时间:{报告时间}
1.4 Python代码实现
from openpyxl import load_workbook
from docx import Document
from datetime import datetimedef fill_word_from_excel(excel_file, word_template, output_dir):# 加载Excel文件wb = load_workbook(excel_file)ws = wb.active# 获取表头headers = [cell.value for cell in ws[1]]# 遍历每一行数据(从第二行开始)for row in range(2, ws.max_row + 1):# 读取行数据row_data = {}for col, header in enumerate(headers, 1):row_data[header] = ws.cell(row=row, column=col).value# 加载Word模板doc = Document(word_template)# 替换模板中的占位符for paragraph in doc.paragraphs:for key, value in row_data.items():if value is None:value = ""elif isinstance(value, datetime):value = value.strftime('%Y-%m-%d')else:value = str(value)if f'{{{key}}}' in paragraph.text:paragraph.text = paragraph.text.replace(f'{{{key}}}', value)# 替换报告时间if '{报告时间}' in paragraph.text:report_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')paragraph.text = paragraph.text.replace('{报告时间}', report_time)# 保存生成的Word文档output_file = f"{output_dir}/员工信息_{row_data['姓名']}.docx"doc.save(output_file)print(f"已生成: {output_file}")# 使用示例
if __name__ == "__main__":fill_word_from_excel('data.xlsx', 'template.docx', 'output')
案例2:批量生成合同文档
2.1 Excel数据文件 (contract_data.xlsx)
| 合同编号 | 客户名称 | 产品名称 | 金额 | 签订日期 | 有效期 |
|---|---|---|---|---|---|
| CT001 | 甲公司 | 软件服务 | 50000 | 2024-01-10 | 1年 |
| CT002 | 乙公司 | 技术支持 | 30000 | 2024-01-12 | 2年 |
2.2 Word模板 (contract_template.docx)
合同编号:{合同编号}甲方:{客户名称}
乙方:XX科技有限公司产品/服务:{产品名称}
合同金额:人民币{金额}元
签订日期:{签订日期}
合同有效期:{有效期}特此证明生成时间:{生成时间}
2.3 Python代码实现
from openpyxl import load_workbook
from docx import Document
from datetime import datetime
import osdef generate_contracts(excel_file, template_file, output_dir):# 创建输出目录if not os.path.exists(output_dir):os.makedirs(output_dir)# 加载Excel数据wb = load_workbook(excel_file)ws = wb.active# 获取表头映射headers = {}for idx, cell in enumerate(ws[1], 1):headers[cell.value] = idx# 处理每一行数据for row in range(2, ws.max_row + 1):# 构建数据字典data = {}for header, col in headers.items():data[header] = ws.cell(row=row, column=col).value# 加载并处理Word模板doc = Document(template_file)# 替换所有段落中的占位符replace_placeholders_in_paragraphs(doc, data)# 替换表格中的占位符replace_placeholders_in_tables(doc, data)# 保存文档filename = f"合同_{data['合同编号']}_{data['客户名称']}.docx"output_path = os.path.join(output_dir, filename)doc.save(output_path)print(f"合同已生成: {filename}")def replace_placeholders_in_paragraphs(doc, data):"""替换段落中的占位符"""current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')for paragraph in doc.paragraphs:for key, value in data.items():placeholder = f'{{{key}}}'if value is None:value = ""elif isinstance(value, datetime):value = value.strftime('%Y-%m-%d')else:value = str(value)if placeholder in paragraph.text:paragraph.text = paragraph.text.replace(placeholder, value)# 替换生成时间if '{生成时间}' in paragraph.text:paragraph.text = paragraph.text.replace('{生成时间}', current_time)def replace_placeholders_in_tables(doc, data):"""替换表格中的占位符"""current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')for table in doc.tables:for row in table.rows:for cell in row.cells:for paragraph in cell.paragraphs:for key, value in data.items():placeholder = f'{{{key}}}'if value is None:value = ""elif isinstance(value, datetime):value = value.strftime('%Y-%m-%d')else:value = str(value)if placeholder in paragraph.text:paragraph.text = paragraph.text.replace(placeholder, value)# 替换生成时间if '{生成时间}' in paragraph.text:paragraph.text = paragraph.text.replace('{生成时间}', current_time)# 使用示例
if __name__ == "__main__":generate_contracts('contract_data.xlsx', 'contract_template.docx', 'contracts_output')
案例3:生成复杂格式的报告
3.1 Excel数据 (report_data.xlsx)
| 项目名称 | 负责人 | 开始日期 | 结束日期 | 进度 | 状态 | 备注 |
|---|---|---|---|---|---|---|
| 项目A | 王五 | 2024-01-01 | 2024-06-30 | 75% | 进行中 | 按计划进行 |
| 项目B | 赵六 | 2024-02-01 | 2024-08-31 | 30% | 进行中 | 资源紧张 |
3.2 Python代码实现
from openpyxl import load_workbook
from docx import Document
from docx.shared import Inches
from datetime import datetimedef generate_project_report(excel_file, template_file, output_file):# 加载Excel数据wb = load_workbook(excel_file)ws = wb.active# 准备数据projects = []headers = [cell.value for cell in ws[1]]for row in range(2, ws.max_row + 1):project = {}for col, header in enumerate(headers, 1):value = ws.cell(row=row, column=col).valueif isinstance(value, datetime):value = value.strftime('%Y-%m-%d')project[header] = valueprojects.append(project)# 加载Word模板doc = Document(template_file)# 替换基本信息replace_basic_info(doc)# 添加项目表格add_project_table(doc, projects)# 添加总结add_summary(doc, projects)# 保存文档doc.save(output_file)print(f"项目报告已生成: {output_file}")def replace_basic_info(doc):"""替换基本信息"""current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')for paragraph in doc.paragraphs:if '{报告标题}' in paragraph.text:paragraph.text = paragraph.text.replace('{报告标题}', '项目进度报告')if '{生成日期}' in paragraph.text:paragraph.text = paragraph.text.replace('{生成日期}', current_time)if '{报告人}' in paragraph.text:paragraph.text = paragraph.text.replace('{报告人}', '系统自动生成')def add_project_table(doc, projects):"""添加项目表格"""# 在文档末尾添加表格table = doc.add_table(rows=1, cols=6)table.style = 'Light Grid Accent 1'# 添加表头headers = ['项目名称', '负责人', '开始日期', '结束日期', '进度', '状态']hdr_cells = table.rows[0].cellsfor i, header in enumerate(headers):hdr_cells[i].text = header# 添加数据行for project in projects:row_cells = table.add_row().cellsrow_cells[0].text = str(project.get('项目名称', ''))row_cells[1].text = str(project.get('负责人', ''))row_cells[2].text = str(project.get('开始日期', ''))row_cells[3].text = str(project.get('结束日期', ''))row_cells[4].text = str(project.get('进度', ''))row_cells[5].text = str(project.get('状态', ''))def add_summary(doc, projects):"""添加总结部分"""doc.add_paragraph("\n项目总结:")total_projects = len(projects)in_progress = sum(1 for p in projects if p.get('状态') == '进行中')completed = total_projects - in_progresssummary_text = f"""总项目数: {total_projects}进行中项目: {in_progress}已完成项目: {completed}"""doc.add_paragraph(summary_text)# 使用示例
if __name__ == "__main__":generate_project_report('report_data.xlsx', 'report_template.docx', '项目报告.docx')
案例4:高级功能 - 带格式的替换
from openpyxl import load_workbook
from docx import Document
from docx.shared import RGBColor
from datetime import datetimedef advanced_template_filling(excel_file, template_file, output_file):# 加载Excel数据wb = load_workbook(excel_file)ws = wb.active# 读取数据data = {}for row in range(1, ws.max_row + 1):key = ws.cell(row=row, column=1).valuevalue = ws.cell(row=row, column=2).valueif key:data[key] = value# 加载Word模板doc = Document(template_file)# 高级替换(保留格式)replace_placeholders_preserve_formatting(doc, data)doc.save(output_file)print(f"文档已生成: {output_file}")def replace_placeholders_preserve_formatting(doc, data):"""保留格式的占位符替换"""for paragraph in doc.paragraphs:for key, value in data.items():placeholder = f'{{{key}}}'if value is None:value = ""elif isinstance(value, datetime):value = value.strftime('%Y-%m-%d')else:value = str(value)if placeholder in paragraph.text:# 保留原始格式进行替换for run in paragraph.runs:if placeholder in run.text:run.text = run.text.replace(placeholder, value)# 根据值设置颜色if '警告' in value or '紧急' in value:run.font.color.rgb = RGBColor(255, 0, 0) # 红色elif '完成' in value or '正常' in value:run.font.color.rgb = RGBColor(0, 128, 0) # 绿色# 使用示例
if __name__ == "__main__":advanced_template_filling('config_data.xlsx', 'advanced_template.docx', '高级报告.docx')
使用说明
- Excel文件准备:确保第一行是列标题,这些标题将作为Word模板中的占位符名称
- Word模板准备:在Word中使用
{列标题}格式创建占位符 - 运行脚本:根据需要修改文件路径和参数
- 输出:生成的Word文档将保存在指定目录
这些案例涵盖了从简单到复杂的各种场景,您可以根据实际需求进行修改和扩展。
