Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python编码问题:zip csv缓冲区(Django)_Python_Django_Python 2.7_Csv - Fatal编程技术网

Python编码问题:zip csv缓冲区(Django)

Python编码问题:zip csv缓冲区(Django),python,django,python-2.7,csv,Python,Django,Python 2.7,Csv,在Django视图中,我想在内存中创建一些csv文件,并将其压缩下载 我正在使用Django 1.11/Python 2.7。我的代码: import csv import zipfile import StringIO files = [] csv_buffer = StringIO.StringIO() writer = csv.writer(csv_buffer) writer.writerow(["val1", "str1"]) csv_buffer.seek(0) files

在Django视图中,我想在内存中创建一些csv文件,并将其压缩下载

我正在使用Django 1.11/Python 2.7。我的代码:

import csv
import zipfile
import StringIO


files = []

csv_buffer = StringIO.StringIO()
writer = csv.writer(csv_buffer)
writer.writerow(["val1", "str1"])

csv_buffer.seek(0)

files.append(csv_buffer)

zipped_file = StringIO.StringIO()

with zipfile.ZipFile(zipped_file, 'w') as zipper:
    for i, file in enumerate(files):
        file.seek(0)
        zipper.writestr("{}.csv".format(i), file.read())

zipped_file.seek(0)

# response = HttpResponse(csv_buffer, content_type='text/csv')
# response['Content-Disposition'] = 'attachment; filename=results.csv'
response = HttpResponse(zipped_file, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=results.zip'
return response
使用此代码,csv编码为utf-8,但我的编辑器抱怨“无效字符”

如果我只是返回csv文件,我会得到一个空的csv。不知道为什么

我认为StringIO缓冲区有一个错误的编码,但我不知道如何使它工作。如果我这样做:

csv_buffer = StringIO.StringIO("")
我可以创建可读的CSV文件,但代码的zip部分失败:

    'ascii' codec can't decode byte 0xd4 in position 10: ordinal not in range(128)
如果您能解释一下这里出了什么问题,我们将不胜感激

编辑:打字错误 编辑2:添加了zip错误消息

而不是StringIO,使用BytesIO作为ZipFile的writest。ZipFile将尝试将第二个参数转换为字节

from io import BytesIO
zipped_file = BytesIO

with zipfile.ZipFile(zipped_file, 'w') as zipper:
    for i, myfile in enumerate(files):
        zipper.writestr("{}.csv".format(i), myfile.getvalue())

zipped_file.seek(0)
另外,我额外的两分钱是:

不要将文件用作变量名。这是一个python模块。 您可以使用getvalue,这样就不必每次都重置seek0
我通过使用ZipInfo方法在zip中显式定义csv的文件名来解决这个问题,如下所示:

zipinfo = zipfile.ZipInfo("{}.csv".format(i))
zipper.writestr(zipinfo, myfile.read())

奇迹般的成功了!可能与zipfile不支持UTF文件名有关。但是,它没有抛出错误,而是弄乱了压缩文件本身。

谢谢你的回答,但是如果myfile=StringIO,我会得到错误:StringIO实例没有“getValue”属性。如果myfile=StringIO,则压缩可以工作,但csv文件不可读。。