求助:Python+Jinja2实现CSV数据写入Word模板表格的代码问题
问题:使用Python将CSV数据写入Word模板表格
我正尝试使用Python的docxtpl、pandas、csv库,将CSV文件中的数据写入已有的Word模板表格中。
CSV数据(制表符分隔)
user.dst device.ip count(user.dst) user1 192.168.102.128 475 user2 192.168.102.128 113 user3 192.168.102.128 43 user4 192.168.102.128 23 user5 192.168.102.128 3 user6 192.168.102.128 2
现有代码
from docxtpl import DocxTemplate import docx as doc import pandas as pd import csv doc = DocxTemplate("daily report.docx") csvfn = "csv_file.csv" ############################## Read Csv File Data ##################### with open (csvfn,"r") as csvf: op = csvf.readlines() Dbusertbl = [] user_source=[] session_count=[] for i in op[0:]: user_source = i.split(",")[0] Session_count = i.split(",")[1] Dbusertbl.append({"user_name":user_source,"session_count":Session_count}) print(Dbusertbl) ################################# Context ############################################ context = { "DbTblRows":Dbusertbl } doc.render(context) doc.save("newword.docx")
模板情况
已在Word模板中添加Jinja2语法,表格内使用了循环标签(如{% for row in DbTblRows %})和变量占位符(如{{ row.user_name }}、{{ row.session_count }})。
代码问题分析与修正
核心问题
- 分隔符错误:你的CSV实际是制表符分隔(不是逗号),用
split(",")无法正确拆分数据,会导致取值错误。 - 表头未跳过:循环包含了第一行表头数据,会把表头当成普通数据写入模板。
- 变量覆盖与冗余导入:导入
docx as doc后,又用doc = DocxTemplate(...)覆盖了变量,且未实际使用docx库;导入了pandas但未利用其便捷的CSV读取功能。 - 换行符未处理:手动
readlines()读取的行末尾带有\n,直接拆分后会残留换行符,导致数据不干净。 - 不必要的变量初始化:
user_source和session_count被初始化为列表,后续又赋值为字符串,属于冗余操作。
修正方案(两种可选)
方案1:使用csv模块正确读取制表符分隔的数据
from docxtpl import DocxTemplate import csv # 初始化模板 doc = DocxTemplate("daily report.docx") csvfn = "csv_file.csv" Dbusertbl = [] # 使用csv模块读取制表符分隔的文件 with open(csvfn, "r", newline="") as csvf: reader = csv.DictReader(csvf, delimiter="\t") for row in reader: # 提取需要的字段,对应模板中的变量名 Dbusertbl.append({ "user_name": row["user.dst"], "session_count": row["count(user.dst)"] }) # 渲染模板 context = {"DbTblRows": Dbusertbl} doc.render(context) doc.save("newword.docx")
方案2:使用pandas简化读取(更简洁)
from docxtpl import DocxTemplate import pandas as pd doc = DocxTemplate("daily report.docx") csvfn = "csv_file.csv" # 用pandas读取制表符分隔的文件,直接转换为字典列表 df = pd.read_csv(csvfn, sep="\t") Dbusertbl = df.apply(lambda x: { "user_name": x["user.dst"], "session_count": x["count(user.dst)"] }, axis=1).tolist() context = {"DbTblRows": Dbusertbl} doc.render(context) doc.save("newword.docx")
模板注意事项
确保Word模板中的Jinja2标签位置正确:
{% for row in DbTblRows %}要放在表格行的起始位置(通常是行的第一个单元格内){% endfor %}要放在循环行的结束位置(通常是行的最后一个单元格内)- 变量占位符
{{ row.user_name }}、{{ row.session_count }}要对应表格的列位置
内容的提问来源于stack exchange,提问作者Maysara Anani
相关产品推荐
相关产品推荐

