如何使用Django配合Python-Docx将数据库动态数据写入Word文档
实现步骤
1. 核心修改逻辑
你目前的代码缺少两个核心环节:
- 没有从URL中提取传入的产品
pk参数,查询对应单条产品数据 - 没有将查询到的产品数据传入
build_document方法进行动态内容拼接
你猜测的需要将数据转字符串的逻辑是对的,python-docx的文本插入方法只需要传入字符串格式,非字符串类型(数值、日期等)直接用str()转换即可。
2. 修改后的完整代码
import io from django.shortcuts import get_object_or_404 from django.http import StreamingHttpResponse from rest_framework.views import APIView from docx import Document from docx.shared import Inches from .models import Products class ExportDocx(APIView): def get(self, request, *args, **kwargs): # 从URL中获取产品pk,查询对应产品,不存在则返回404 product_pk = kwargs.get('pk') product = get_object_or_404(Products, pk=product_pk) # 传入产品数据构建文档 document = self.build_document(product) # 保存文档到内存流 buffer = io.BytesIO() document.save(buffer) buffer.seek(0) # 构造返回响应 response = StreamingHttpResponse( streaming_content=buffer, content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document' ) # 动态设置导出文件名 response['Content-Disposition'] = f'attachment;filename=产品{product_pk}_详情.docx' response["Content-Encoding"] = 'UTF-8' return response def build_document(self, product, *args, **kwargs): document = Document() # 全局边距设置(原有逻辑保留) sections = document.sections for section in sections: section.top_margin = Inches(0.95) section.bottom_margin = Inches(0.95) section.left_margin = Inches(0.79) section.right_margin = Inches(0.79) # 静态头部内容 document.add_heading("产品导出详情", level=1) # ========== 以下为动态产品数据插入 ========== # 基础信息段落示例 base_info_p = document.add_paragraph() base_info_p.add_run('产品ID:').bold = True base_info_p.add_run(f"{product.id}\n") base_info_p.add_run('产品名称:').bold = True base_info_p.add_run(f"{product.name}\n") # 可根据你Products模型的实际字段自行扩展,比如价格、分类、上架状态等 base_info_p.add_run('产品价格:').bold = True base_info_p.add_run(f"¥{product.price}\n") base_info_p.add_run('上架状态:').bold = True base_info_p.add_run("已上架" if product.is_online else "未上架") # 长文本描述示例 document.add_heading("产品描述", level=2) document.add_paragraph(f"{product.desc if product.desc else '无描述信息'}") # 表格形式展示所有字段示例 document.add_heading("字段汇总", level=2) table = document.add_table(rows=1, cols=2, style="Table Grid") # 表头 hdr_cells = table.rows[0].cells hdr_cells[0].text = '字段名称' hdr_cells[1].text = '字段值' # 遍历需要展示的字段,非字符串类型统一转字符串 show_fields = [ ("ID", product.id), ("名称", product.name), ("价格", product.price), ("库存", product.stock), ("创建时间", product.create_time.strftime('%Y-%m-%d %H:%M') if product.create_time else "无"), ] for field_name, field_val in show_fields: row_cells = table.add_row().cells row_cells[0].text = field_name row_cells[1].text = str(field_val) return document
3. 扩展说明
- 如果需要插入产品的图片字段,可使用
document.add_picture(图片文件路径/流, width=Inches(4))方法插入 - 文本格式可通过
add_run()的属性设置,比如bold=True加粗、italic=True斜体、font.size设置字号等 - 如果需要导出多个产品,可修改URL路由去掉pk参数,查询多个产品实例循环插入到文档中即可
内容的提问来源于stack exchange,提问作者Panderio
相关产品推荐
相关产品推荐

