生成CSV文件

阅读: 33133     评论:1

CSV (Comma Separated Values),以纯文本形式存储数字和文本数据的存储方式。

CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

CSV经常作为数据分析和机器学习中源数据的载体。

要在Django的视图中生成CSV文件,可以使用Python的CSV库或者Django的模板系统来实现。

一、使用Python的CSV库

Python自带处理CSV文件的标准库csv。

csv模块的CSV文件创建功能类似文件对象的创建。

下面是个例子:

import csv
from django.http import HttpResponse


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

    writer = csv.writer(response)
    writer.writerow(["First row", "Foo", "Bar", "Baz"])
    writer.writerow(["Second row", "A", "B", "C", '"Testing"', "Here's a quote"])

    return response

相关说明:

  • 响应对象的MIME类型设置为text/csv,告诉浏览器,返回的是一个CSV文件而不是HTML文件。
  • 响应对象设置了附加的Content-Disposition协议头,含有CSV文件的名称。文件名随便取,浏览器会在“另存为...”对话框等环境中使用它。
  • 要在生成CSV的API中使用钩子非常简单:只需要把response作为第一个参数传递给csv.writercsv.writer方法接受一个类似文件的对象,而HttpResponse对象正好符合。
  • 对于CSV文件的每一行,调用writer.writerow,向它传递一个可迭代的对象比如列表或者元组。每一个列表是csv文件的一行内容。
  • CSV模板会为你处理各种引用,不用担心没有转义字符串中的引号或者逗号。只需要向writerow传递原始字符串,它会执行正确的操作。

当处理大尺寸文件时,可以使用Django的StreamingHttpResponse类,通过流式传输,避免负载均衡器在服务器生成响应的时候断掉连接,提高传输可靠性。

在下面的例子中,利用Python的生成器来有效处理大尺寸CSV文件的拼接和传输:

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)
    return StreamingHttpResponse(
        (writer.writerow(row) for row in rows),
        content_type="text/csv",
        headers={"Content-Disposition": 'attachment; filename="somefilename.csv"'},
    )

二、使用Django的模板系统

也可以使用Django的模板系统来生成CSV。比起便捷的Python-csv库,这样做比较低级,不建议使用,这里只是展示一下有这种方式而已。

思路是,传递一个项目的列表给你的模板,并且让模板在for循环中输出逗号。下面是一个例子,它像上面一样生成相同的CSV文件:

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",
        headers={"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

然后,创建模板my_template_name.txt,带有以下模板代码:

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

 文件上传和文件对象 生成PDF文件 

评论总数: 1


点击登录后方可评论

打卡