我需要根据csv文件中的数据,更新word模板批量生成word文件。
csv文件如下所示:1
2
3
4日期,单位,类型,企业
2023/12/1,A中心,日常检查,A公司
2023/11/30,A中心,日常检查,B公司
...
Word模板内容如下所示(略去格式):1
2
3
4
5
6
7检查通知
根据安排,定于$year年$month月$day日对你公司开展现场检查。
特此通知。
A中心
$_year年$_month月$_day日
- 首先,导入一些需要使用的模块:
csv
:用于读取 CSV 文件。Document
:来自docx
模块,用于处理 Word 文档。Pt
:来自docx.shared
模块,用于设置字体大小。datetime
和timedelta
:用于处理日期和时间1
2
3
4import csv
from docx import Document
from docx.shared import Pt
from datetime import datetime, timedelta
从 CSV 文件中读取数据。使用
open()
函数打开名为sample.csv
的文件,指定编码为 UTF-8。然后使用csv.reader()
函数创建一个读取器对象reader
来读取文件的内容。next(reader)
跳过了文件的第一行,即标题行。接下来,通过迭代reader
,逐行读取文件中的数据。1
2
3with open('sample.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
next(reader) # 跳过标题行对于每一行数据,首先使用
datetime.strptime()
函数将日期字符串转换为日期对象。它使用%Y/%m/%d
格式解析row[0]
中的日期字符串,并将其存储在date
变量中。然后,将row[3]
的值存储在unit
变量中。1
2
3
4for row in reader:
# 读取CSV文件中的数据
date = datetime.strptime(row[0], '%Y/%m/%d')
unit = row[3]读取 Word 文件模板。使用
Document()
函数从名为sample.docx
的模板文件创建一个doc
对象。1
2# 读取word文件模板
doc = Document('sample.docx')填充 Word 文件模板。通过迭代
doc.paragraphs
,遍历文档中的每一段落。对于每个段落,通过迭代paragraph.runs
,遍历段落中的每个文本。如果文本中不包含字符串'药品生产监督检查通知'
,则设置字体名称为'仿宋_GB2312'
,字体大小为 16 磅。然后,通过替换字符串的方式,将$cname
替换为unit
,将$year
替换为date.year
,将$month
替换为date.month
,将$day
替换为date.day
。如果文本中包含'$_year'
、'$_month'
或'$_day'
,则计算出notification_date
,它是date
减去一天得到的结果,然后将'$_year'
、'$_month'
和'$_day'
替换为相应的日期值。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 填充word文件模板
for paragraph in doc.paragraphs:
for run in paragraph.runs:
if not '检查通知' in run.text: # 标题不改变格式
run.font.name = '仿宋_GB2312' # 设置字体名称为仿宋_GB2312
run.font.size = Pt(16) # 设置字体大小为16磅
if '$cname' in run.text:
run.text = run.text.replace('$cname', unit)
if '$year' in run.text:
run.text = run.text.replace('$year', str(date.year))
if '$month' in run.text:
run.text = run.text.replace('$month', str(date.month))
if '$day' in run.text:
run.text = run.text.replace('$day', str(date.day))
if '$_year' in run.text or '$_month' in run.text or '$_day' in run.text:
notification_date = date - timedelta(days=1)
run.text = run.text.replace('$_year', str(notification_date.year))
run.text = run.text.replace('$_month', str(notification_date.month))
run.text = run.text.replace('$_day', str(notification_date.day))最后,保存填充后的 Word 文件。使用
doc.save()
函数,将填充后的 Word 文件保存在名为./notification/{str(date.year)}_{str(date.month)}_{str(date.day)}_{unit}.docx
的位置。1
doc.save(f'./notification/{str(date.year)}_{str(date.month)}_{str(date.day)}_{unit}.docx')
以下为全部代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41import csv
from docx import Document
from docx.shared import Pt
from datetime import datetime, timedelta
# 读取CSV文件
with open('sample.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
next(reader) # 跳过标题行
for row in reader:
# 读取CSV文件中的数据
date = datetime.strptime(row[0], '%Y/%m/%d')
unit = row[3]
# 读取word文件模板
doc = Document('sample.docx')
# 填充word文件模板
for paragraph in doc.paragraphs:
for run in paragraph.runs:
if not '药品生产监督检查通知' in run.text:
run.font.name = '仿宋_GB2312' # 设置字体名称为仿宋_GB2312
run.font.size = Pt(16) # 设置字体大小为16磅
if '$cname' in run.text:
run.text = run.text.replace('$cname', unit)
if '$year' in run.text:
run.text = run.text.replace('$year', str(date.year))
if '$month' in run.text:
run.text = run.text.replace('$month', str(date.month))
if '$day' in run.text:
run.text = run.text.replace('$day', str(date.day))
if '$_year' in run.text or '$_month' in run.text or '$_day' in run.text:
notification_date = date - timedelta(days=1)
run.text = run.text.replace('$_year', str(notification_date.year))
run.text = run.text.replace('$_month', str(notification_date.month))
run.text = run.text.replace('$_day', str(notification_date.day))
# 保存填充后的word文件
doc.save(f'./notification/{str(date.year)}_{str(date.month)}_{str(date.day)}_{unit}.docx')