You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:24:03