Django读取Excel数据填充Word书签并导出为PDF的问题求助
现有代码问题梳理
- 技术选型错误:reportlab是直接生成PDF内容的库,无法解析、编辑Word文档结构,也不支持书签替换操作,和需求方向不匹配
- 文档操作逻辑错误:docx是二进制压缩格式,不能直接用
open()以文本模式读写,会直接损坏原文件 - 语法存在多处错误:函数定义嵌套在循环内、括号不匹配、未初始化HttpResponse对象就直接赋值属性、错误使用字典语法包裹代码块
- 逻辑流程错误:跳过表头的逻辑存在疏漏,且循环内直接return会导致仅处理第一行有效数据就终止执行,无法批量生成文件
正确实现步骤
首先安装所需依赖:
pip install openpyxl python-docx docx2pdf
注:docx2pdf用于将填充好的Word文档转为PDF,Windows环境只要安装了Office即可直接使用,Linux/macOS环境需要提前安装LibreOffice支持转换。
修正后代码示例
from django.shortcuts import render from django.http import HttpResponse from django.conf import settings import openpyxl from docx import Document from docx2pdf import convert import io import os def index(request): if request.method == "GET": return render(request, 'letters/index.html', {}) excel_file = request.FILES["excel_file"] # 加载Excel wb = openpyxl.load_workbook(excel_file) excel_data = [] # 这里示例按单条记录生成单个PDF返回,批量生成可以调整逻辑打包返回 output_buffer = io.BytesIO() for sheet_name in wb.sheetnames: sheet = wb[sheet_name] # 跳过表头行,从第二行开始读取数据 for row_idx, row in enumerate(sheet.iter_rows(values_only=True)): if row_idx == 0: continue row_data = [str(cell) if cell is not None else "" for cell in row] excel_data.append(row_data) # 加载Word模板 template_path = os.path.join(settings.MEDIA_ROOT, "template.docx") doc = Document(template_path) # 替换书签逻辑,示例替换两个书签:name、Admission,可根据实际书签数量扩展 bookmark_map = { "name": row_data[0], "Admission": row_data[2] } for bk_name, replace_text in bookmark_map.items(): for bookmark in doc.bookmarks: if bookmark.name == bk_name: runner = bookmark.start.parent runner.text = replace_text break # 先保存填充后的Word到临时缓存 temp_doc_buffer = io.BytesIO() doc.save(temp_doc_buffer) temp_doc_buffer.seek(0) # 转PDF convert(temp_doc_buffer, output_buffer) output_buffer.seek(0) # 返回PDF文件 response = HttpResponse(output_buffer, content_type="application/pdf") response["Content-Disposition"] = f"attachment;filename=Admission_{row_data[0]}.pdf" return response return render(request, 'letters/index.html', {"excel_data": excel_data})
补充说明
如果需要批量生成多个PDF,可以将生成的所有PDF打包为zip文件后返回,不需要每条数据都return;如果服务器环境不方便安装LibreOffice/Office,也可以选择用python-docx生成Word后直接返回Word文件,不需要转PDF的步骤可以直接删掉转换逻辑,返回docx格式即可。
内容的提问来源于stack exchange,提问作者sasvi
相关产品推荐
相关产品推荐

