Django 流式響應中文csv樣例

在Django裏,流式響應StreamingHttpResponse是個好東西,能夠快速、節省內存地產生一個大型文件。python

目前項目裏用於流式響應的一個是Eventsource,用於改善跨系統通信時用戶產生的慢速的感受。這個不細說了。web

還有一個就是生成一個大的csv文件。django

當Django進程處於gunicorn或者uwsgi等web容器中時,若是響應超過必定時間沒有返回,就會被web容器終止掉,雖然咱們能夠經過加長web容器的超時時間來繞過這個問題,可是畢竟仍是治標不治本。要根本上解決這個問題,Python的生成器、Django框架提供的StreamingHttpResponse這個流式響應頗有幫助框架

而在csv中,中文的處理也相當重要,要保證用excel打開csv不亂碼什麼的。。爲了節約空間,我就把全部代碼貼到一塊兒了。。實際使用按照項目的規劃放置哈excel

上代碼:code

pythonfrom __future__ import absolute_import
import csv
import codecs
import cStringIO


class Echo(object):

    def write(self, value):
        return value

class UnicodeWriter:

    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([handle_column(s) for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        value = self.stream.write(data)
        # empty queue
        self.queue.truncate(0)
        return value

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)






from django.views.generic import View
from django.http.response import StreamingHttpResponse

class ExampleView(View):
    headers=['一些','表頭']
    def get(self,request):
        result = [['第一行','數據1'],
                  ['第二行','數據2']]
        echoer = Echo()
        writer = UnicodeWriter(echoer)
        def csv_itertor():
                yield codecs.BOM_UTF8
                yield writer.writerow(self.headers)
                for column in result:
                    yield writer.writerow(column)

        response = StreamingHttpResponse(
            (row for row in csv_itertor()),
            content_type="text/csv;charset=utf-8")
        response['Content-Disposition'
                 ] = 'attachment;filename="example.csv"'
        return response
相關文章
相關標籤/搜索