关键词搜索

源码搜索 ×
×

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

发布2021-08-29浏览525次

详情内容

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

涉及知识点

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

场景介绍

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

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

本文的功能就是根据模板文档,为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. 示例完整代码

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

示例截图

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

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

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

备注

书愤五首·其一

【作者】陆游 【朝代】宋

早岁那知世事艰,中原北望气如山。

楼船夜雪瓜洲渡,铁马秋风大散(sǎn)关。

塞上长城空自许,镜中衰鬓已先斑。

出师一表真名世,千载谁堪伯仲间。


作者:Alan.hsiang
 

本文版权归作者和博客园共有,写文不易,支持原创,欢迎转载【点赞】,转载请保留此段声明,且在文章页面明显位置给出原文连接,谢谢。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载