2017-06-30 16 views
0

Djangoのビューでは、メモリ内にいくつかのcsvファイルを作成し、それらを圧縮してダウンロードします。Pythonエンコーディングの問題:zip csv buffers(Django)

私は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ファイルを作成することができますが、その後、コードのジップ部分は失敗します。

'ascii' codec can't decode byte 0xd4 in position 10: ordinal not in range(128) 

ここで間違って何が起こっているのか、任意の説明をいただければ幸いです!

編集:誤植 編集2:追加ジップエラーメッセージの代わりにStringIO

答えて

0

をリセットする必要はありません、私は明示的にそうように持つZipInfoメソッドを使用してzipファイルにcsvファイルのファイル名を定義することによってそれを解決:

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

それは奇跡的に働いた! UTFファイル名をサポートしていないzipfileと関係しているかもしれません。しかし、エラーを投げるのではなく、圧縮されたファイル自体を駄目です。

1

、バイトに二番目の引数を変換しようとするZIPファイルのwritestrとしてBytesIOを使用しています。

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) 

また私から余分な2セントは次のとおりです。

  • は、変数名としてfileは使用しないでください。これはPythonモジュールです。
  • あなたがgetvalueを使用することができますので、あなたがseek(0)毎回
+0

回答ありがとうございますが、myfile = StringIO( "")の場合、エラーが発生します。StringIOインスタンスには属性 'getValue'がありません。 myfile = StringIO()の場合、圧縮は機能しますが、csvファイルは読み取れません。 – DeBaze

関連する問題