0%

使用python批量生成word文档

python-docx

我需要根据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
检查通知
$cname:
根据安排,定于$year年$month月$day日对你公司开展现场检查。
特此通知。

A中心
$_year年$_month月$_day日

  1. 首先,导入一些需要使用的模块:
  • csv:用于读取 CSV 文件。
  • Document:来自 docx 模块,用于处理 Word 文档。
  • Pt:来自 docx.shared 模块,用于设置字体大小。
  • datetimetimedelta:用于处理日期和时间
    1
    2
    3
    4
    import csv
    from docx import Document
    from docx.shared import Pt
    from datetime import datetime, timedelta
  1. 从 CSV 文件中读取数据。使用 open() 函数打开名为 sample.csv 的文件,指定编码为 UTF-8。然后使用 csv.reader() 函数创建一个读取器对象 reader 来读取文件的内容。next(reader) 跳过了文件的第一行,即标题行。接下来,通过迭代 reader,逐行读取文件中的数据。

    1
    2
    3
    with open('sample.csv', 'r', encoding='utf-8') as file:
    reader = csv.reader(file)
    next(reader) # 跳过标题行
  2. 对于每一行数据,首先使用 datetime.strptime() 函数将日期字符串转换为日期对象。它使用 %Y/%m/%d 格式解析 row[0] 中的日期字符串,并将其存储在 date 变量中。然后,将 row[3] 的值存储在 unit 变量中。

    1
    2
    3
    4
    for row in reader:
    # 读取CSV文件中的数据
    date = datetime.strptime(row[0], '%Y/%m/%d')
    unit = row[3]
  3. 读取 Word 文件模板。使用 Document() 函数从名为 sample.docx 的模板文件创建一个 doc 对象。

    1
    2
    # 读取word文件模板
    doc = Document('sample.docx')
  4. 填充 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))
  5. 最后,保存填充后的 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
41
import 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')