用 Excel 表格中的数据批量替换 docx 模板中的标记(原创)
# 修改模板文件后,DOC中段落受格式影响,可能导致占位标记被分割成两个段落,出现这种情况可以将模板中
# 全部内容以“无格式文本”粘贴到新文档中,重新设置格式,可纠正错误的段落分割
import docx
import xlwings as xw
import sys
import time
import re
if (len(sys.argv) != 2):
print("Error: Cannot found the argument!")
exit()
path = sys.path[0]
app = xw.App(visible=False, add_book=False)
try:
doc = docx.Document('template.dx')
except:
print('Error: Cannot found template file!')
exit()
try:
print(path + '\\' + sys.argv[1])
wb = app.books.open(path + '\\' + sys.argv[1])
sh = wb.sheets['计算表']
now = time.localtime(time.time())
strDate = "{}年{}月{}日".format(now.tm_year, now.tm_mon, now.tm_mday)
dtMon = sh.range('B2').value
strMon = "{}年{}月".format(dtMon.year, dtMon.month)
for p in doc.paragraphs:
for r in p.runs:
# 取得当前格式段中的替换标记,形如 <AB2>
matched = re.findall("<.*?>", r.text)
for item in matched:
if item == '<DATE>':
r.text = r.text.replace(item, strDate)
elif item == '<MON>':
r.text = r.text.replace(item , strMon)
else:
value = str(sh.range(item[1:-1]).value)
if value == "None":
value = '0'
# 删除末尾的小数点和0
cleaned_num = value.rstrip('0').rstrip('.') if '.' in value else value
r.text = r.text.replace(item , cleaned_num)
try:
strFileName = "方案{}年{:02d}月.docx".format(dtMon.year, dtMon.month)
doc.save(strFileName)
except Exception as r:
#print('Error: Cannot write to a used file!')
print(r)
exit()
except Exception as r:
#print('Error: Cannot open the file!')
print(r)
finally:
wb.close()
app.quit()
使用 docxtpl 库可以进一步简化代码:
# docx 模板中使用 {{AC3}} 形式保存单元格标记
from docxtpl import DocxTemplate
import xlwings as xw
import sys
import datetime
if (len(sys.argv) != 2):
print("Error: Cannot found the argument!")
exit()
path = sys.path[0]
app = xw.App(visible=False, add_book=False)
try:
print(path + '\\' + sys.argv[1])
wb = app.books.open(path + '\\' + sys.argv[1])
sh = wb.sheets['计算表']
context = {}
for cell in sh.used_range:
if type(cell.value) == float:
# 数值类型的单元格都会被读入为 float 类型,在此去除末尾不必要的 0
value = str(cell.value)
#context[cell.get_address(False, False)] = f"{value:g}"
context[cell.get_address(False, False)] = value.rstrip('0').rstrip('.') if '.' in value else value
else:
context[cell.get_address(False, False)] = cell.value
context['D6_S'] = int(context['D6']) - 1
context['SPE'] = float(context['M2']) - float(context['AC8'])
now = datetime.datetime.now()
context['DATE'] = f"{now.year}年{now.month}月{now.day}日"
Mon = sh.range('B2').value
context['MON'] = f"{Mon.year}年{Mon.month}月"
except:
print('Error: Cannot open the file!')
exit()
finally:
wb.close()
app.quit()
doc = DocxTemplate("template.dx")
doc.render(context)
strFileName = f"分配计划{Mon.year}年{Mon.month:02d}月.docx"
doc.save(strFileName)

浙公网安备 33010602011771号