一次性学会Django项目开发中常见的文件导出需求

文章目录


大家在开发过程中,应该都遇到过 从网页中导出各种格式的文件吧,例如 csv,doc,pdf等,我们接下来就一一介绍这几种格式的文件如从导出为文件。
以下代码都是在django框架中实现,主要是视图层的代码 即views.py

CSV

参考文章
https://docs.djangoproject.com/zh-hans/2.2/howto/outputting-csv/

import csv
from django.http import HttpResponse
from django.template import loader

def export_model_as_csv(request):
	response = HttpResponse(content_type='text/csv')
	response['Content-Disposition'] = 'attachment;filename=export.csv'
	writer = csv.writer(response)
	# 这里可以从model中查询出数据 
	data = ['First row', 'Foo', 'Bar', 'Baz']
	writer.writerrow(data)
	return response

代码和注释应该是不言自明的,但是有几件事值得提一下:

  • 响应指定了特殊的 MIME 类型 text/csv。这告诉浏览器该文档是一个 CSV 文件,而不是一个 HTML 文件。如果你没这么干,浏览器可能会将输出视作 HTML,这会在浏览器窗口展示丑陋的,恐怖的官样文章。

  • 相应还包括一个额外的 Content-Disposition 头,其中包含了 CSV 文件的名称。文件名是任意的;随便你怎么叫。它会被浏览器在 “保存为……” 对话框中用到。

  • 接入生成 CSV API 非常简单:仅需将 response 作为第一个参数传给 csv.writer。 csv.writer 函数期望一个类文件对象,而 HttpResponse 对象满足该要求。

  • 要按行输出 CSV 文件,调用 writer.writerrow,传入一个 iterable 参数。

  • CSV 模块为你处理了引号,所以你无需担心包含引号或逗号的字符串的转义问题。只需为 writerow() 传入原始字符串,它为你处理好一切。

输出超大CSV文件时使用 StreamingHttpResponse

import csv

from django.http import StreamingHttpResponse

class Echo:
    """An object that implements just the write method of the file-like
    interface.
    """
    def write(self, value):
        """Write the value by returning it, instead of storing in a buffer."""
        return value

def some_streaming_csv_view(request):
    """A view that streams a large CSV file."""
    # Generate a sequence of rows. The range is based on the maximum number of
    # rows that can be handled by a single sheet in most spreadsheet
    # applications.
    rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)
    response = StreamingHttpResponse((writer.writerow(row) for row in rows),
                                     content_type="text/csv")
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
    return response

使用模板的系统

from django.http import HttpResponse
from django.template import loader

def some_view(request):
    # Create the HttpResponse object with the appropriate CSV header.
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'

    # The data is hard-coded here, but you could load it from a database or
    # some other source.
    csv_data = (
        ('First row', 'Foo', 'Bar', 'Baz'),
        ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
    )

    t = loader.get_template('my_template_name.txt')
    c = {'data': csv_data}
    response.write(t.render(c))
    return response

模板文件

{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
{% endfor %}

PDF

参考文章
https://docs.djangoproject.com/zh-hans/2.2/howto/outputting-pdf/

# 安装reportlab
pip install reportlab

编写视图
利用 Django 动态生成 PDF 的关键是 ReportLab API 作用于类文件对象,而 Django 的 FileResponse 对象接收类文件对象。

import io
from django import FileResponse
from reportlab.pdfgen import canvas

def export_model_as_pdf(request):
	buffer = io.BytesIO()
	p = canvas.Canvas(buffer)
	p.drawString(100, 100, "Hello world.")
	p.save()
	return FileResponse(buffer, as_attachment=True,filename='hello,pdf')
	
  • 响应会自动基于文件扩展名将 MIME 类型设置为 application/pdf。这告诉浏览器该文档是个 PDF 文件,而不是 HTML 文件或普通的 application/octet-stream 二进制内容。

  • as_attachment=True 传递给 FileResponse 时,它会设置合适的 Content-Disposition 头,这将告诉 Web 浏览器弹出一个对话框,提示或确认如何处理该文档,即便设备已配置默认行为。若省略了 as_attachment 参数,浏览器会用已配置的用于处理 PDF 的程序或插件来处理该 PDF。

  • 你也可以提供可选参数 filename。浏览器的“另存为…”对话框会用到它。
    使用 ReportLab API 非常简单:作为第一个参数传递给 canvas.Canvas的缓冲区也能传递给 FileResponse类。

  • 注意,所有后续生成 PDF 的方法都是在 PDF 对象上调用的(本例中是 p)——而不是在 buffer 上调用。

  • 最后,牢记在 PDF 文件上调用 showPage() 和 save()。

DOC/DOCX

参考文章:
https://blog.csdn.net/weixin_40389301/article/details/80853528
https://blog.csdn.net/qianbin3200896/article/details/81974010
https://www.cnblogs.com/wumingxiaoyao/p/8317548.html

注意:想要导出word文档是需要模板文件的

pip install docxtpl
from docxtpl import DocxTemplate

def read_file(file_name, size):
    with open(file_name, mode='rb') as fp:
        while True:
            c = fp.read(size)
            if c:
                yield c
            else:
                break


def export_model_as_word(request):
    # from docx import Document
    from docxtpl import DocxTemplate
    base_path = os.getcwd() + '/files/'		# 文件的保存路径
    asset_url = base_path + 'test.docx'     # 模板文件
    template = DocxTemplate(asset_url)      # 创建docx模板
    context = {				# 数据
        'name': '需要填进去的数据'
    }
    template.render(context)
    template.save(base_path + 'test1.docx') # 生成word文件

    # 浏览器下载文件
    response = StreamingHttpResponse(read_file(os.path.join(os.getcwd() + '/files/test1.docx'), 512))
    response['Content-Type'] = 'application/msword'
    response['Content-Disposition'] = 'attachment;filename="{}"'.format('test1.docx')
    return response
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值