Python办公自动化之批量生成文档

在日常工作中,类似合同一样的文档通常都会有固定的模板,如偶尔编辑一两份文档,则可以手动完成。假如同一个模板有一百份或更多文档需要生成呢?如果手工逐个文档的编辑保存,不仅容易出错,还是一项费力不讨好的工作;如果能够根据模板批量生成文档,则会大大提高工作效率,减少出错的几率。本文以一个简单的小例子,简述如何通过Python批量生成文档,仅供学习分享使用,如有不足之处,还请指正。



在日常工作中,类似合同一样的文档通常都会有固定的模板,如偶尔编辑一两份文档,则可以手动完成。假如同一个模板有一百份或更多文档需要生成呢?如果手工逐个文档的编辑保存,不仅容易出错,还是一项费力不讨好的工作;如果能够根据模板批量生成文档,则会大大提高工作效率,减少出错的几率。本文以一个简单的小例子,简述如何通过Python批量生成文档,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

  • xlrd模块,用于Excel文档的读取,其中xldate_as_tuple,主要用于Excel读取时的日期格式处理。
  • python-docx 模块,用于word文档的相关操作。

场景介绍

现有一份简化的合同模板,其中红色箭头所指的地方,均是需要替换的地方,如下所示:

Python办公自动化之批量生成文档_Word

同时有21名员工入职,需要签署这份合同,如下所示:

Python办公自动化之批量生成文档_读取excel_02

本文的功能就是根据模板文档,为21名员工,分别生成合同文档。

核心代码

1. 读取数据

读取Excel的数据,并返回数据列表,将此功能封装成单独的函数,如下所示:



1 def read_data(filename: str = None):
2 """
3 读取Excel文件内容
4 :param fileName:
5 :return:
6 """
7 datas = []
8 work_book = xlrd.open_workbook(filename=filename)
9 sheet = work_book.sheet_by_index(0)
10 for i in range(1, sheet.nrows):
11 # 日期格式转换
12 birthday = xldate_as_tuple(sheet.cell_value(i, 6), 0)
13 birthday2 = '%(year)d-%(month)d-%(day)d' % {'year': birthday[0], 'month': birthday[1], 'day': birthday[2]}
14 bpdate = xldate_as_tuple(sheet.cell_value(i, 15), 0)
15 bpdate2 = '%(year)d-%(month)d-%(day)d' % {'year': bpdate[0], 'month': bpdate[1], 'day': bpdate[2]}
16 data = {
17 'bpCompanyName': sheet.cell_value(i, 0),
18 'bpAddress': sheet.cell_value(i, 1),
19 'bpBoss': sheet.cell_value(i, 2),
20 'bpManager': sheet.cell_value(i, 3),
21 'bpWorker': sheet.cell_value(i, 4),
22 'bpSex': sheet.cell_value(i, 5),
23 'bpBirthday': birthday2,
24 'bpHomeAddress': sheet.cell_value(i, 7),
25 'bpId': sheet.cell_value(i, 8),
26 'bpBeginYear': int(sheet.cell_value(i, 9)), # 整数格式处理
27 'bpBeginMonth': int(sheet.cell_value(i, 10)), # 整数格式处理
28 'bpBeginDay': int(sheet.cell_value(i, 11)), # 整数格式处理
29 'bpEndYear': int(sheet.cell_value(i, 12)), # 整数格式处理
30 'bpEndMonth': int(sheet.cell_value(i, 13)), # 整数格式处理
31 'bpEndDay': int(sheet.cell_value(i, 14)), # 整数格式处理
32 'bpDate': bpdate2,
33 'bpSigner': sheet.cell_value(i, 16)
34 }
35 datas.append(data)
36 return datas


2. 单个合同文档生成

Excel的每一行代表一名员工,生成一份合同文档【遍历每一个段落,以及每一个段落的文本,逐个替换文本中的变量内容,且保持原有的格式不变】,如下所示:



1 def write_docx(data, template):
2 """
3 生成文档
4 :param data:
5 :return:
6 """
7
8 doc = Document(docx=template)
9 paragraphs = doc.paragraphs
10 for paragraph in paragraphs:
11 for run in paragraph.runs:
12 for key in data.keys():
13 run_text = run.text.replace(key, str(data[key]))
14 run.text = run_text
15 doc.save('合同/%s合同.docx' % data['bpWorker'])


3. 批量文档生成

遍历所有的员工信息,逐一生成文档,如下所示:



1 def batch_write_docx(datas, template):
2 """
3 批量操作
4 :param datas:
5 :return:
6 """
7 for data in datas:
8 write_docx(data, template)


4. 综合运用

将以上方法依次调用,就可以生成全部文档,如下所示:



1 excel_file = '合同数据.xls'
2 template = '合同模板.docx'
3 datas = read_data(excel_file)
4 # print(datas)
5 batch_write_docx(datas, template)
6 print('done')


5. 示例完整代码


Python办公自动化之批量生成文档_Word_03Python办公自动化之批量生成文档_Word_04


1 import xlrd
2 from xlrd import xldate_as_tuple
3 from docx import Document
4
5
6 def read_data(filename: str = None):
7 """
8 读取Excel文件内容
9 :param fileName:
10 :return:
11 """
12 datas = []
13 work_book = xlrd.open_workbook(filename=filename)
14 sheet = work_book.sheet_by_index(0)
15 for i in range(1, sheet.nrows):
16 # 日期格式转换
17 birthday = xldate_as_tuple(sheet.cell_value(i, 6), 0)
18 birthday2 = '%(year)d-%(month)d-%(day)d' % {'year': birthday[0], 'month': birthday[1], 'day': birthday[2]}
19 bpdate = xldate_as_tuple(sheet.cell_value(i, 15), 0)
20 bpdate2 = '%(year)d-%(month)d-%(day)d' % {'year': bpdate[0], 'month': bpdate[1], 'day': bpdate[2]}
21 data = {
22 'bpCompanyName': sheet.cell_value(i, 0),
23 'bpAddress': sheet.cell_value(i, 1),
24 'bpBoss': sheet.cell_value(i, 2),
25 'bpManager': sheet.cell_value(i, 3),
26 'bpWorker': sheet.cell_value(i, 4),
27 'bpSex': sheet.cell_value(i, 5),
28 'bpBirthday': birthday2,
29 'bpHomeAddress': sheet.cell_value(i, 7),
30 'bpId': sheet.cell_value(i, 8),
31 'bpBeginYear': int(sheet.cell_value(i, 9)), # 整数格式处理
32 'bpBeginMonth': int(sheet.cell_value(i, 10)), # 整数格式处理
33 'bpBeginDay': int(sheet.cell_value(i, 11)), # 整数格式处理
34 'bpEndYear': int(sheet.cell_value(i, 12)), # 整数格式处理
35 'bpEndMonth': int(sheet.cell_value(i, 13)), # 整数格式处理
36 'bpEndDay': int(sheet.cell_value(i, 14)), # 整数格式处理
37 'bpDate': bpdate2,
38 'bpSigner': sheet.cell_value(i, 16)
39 }
40 datas.append(data)
41 return datas
42
43
44 def write_docx(data, template):
45 """
46 生成文档
47 :param data:
48 :return:
49 """
50
51 doc = Document(docx=template)
52 paragraphs = doc.paragraphs
53 for paragraph in paragraphs:
54 for run in paragraph.runs:
55 for key in data.keys():
56 run_text = run.text.replace(key, str(data[key]))
57 run.text = run_text
58 doc.save('合同/%s合同.docx' % data['bpWorker'])
59
60
61 def batch_write_docx(datas, template):
62 """
63 批量操作
64 :param datas:
65 :return:
66 """
67 for data in datas:
68 write_docx(data, template)
69
70
71 excel_file = '合同数据.xls'
72 template = '合同模板.docx'
73 datas = read_data(excel_file)
74 # print(datas)
75 batch_write_docx(datas, template)
76 print('done')

View Code

示例截图

批量文档生成后,截图如下所示:

Python办公自动化之批量生成文档_Python_05

 

 合同文档内文,如下所示:

Python办公自动化之批量生成文档_Word_06

 

 以上就是批量生成文档的全部内容,可以看出,生成后的文档,格式与模板保持一致。