2013-02-01 39 views
2

我寫了一個函數,可以隨時生成一些csv文件併發送給用戶進行下載。flask send_file和unicode文件名:在IE中損壞

的代碼如下:

@app.route('/survey/<survey_id>/report') 
def survey_downloadreport(survey_id): 
    survey, bsonobj = survey_get(survey_id) 
    resps = response_get_multi(survey_id) 

    fields = ["_id", "sid", "date", "user_ip"] 
    fields.extend(survey.formfields)  

    csvf = StringIO.StringIO() 
    wr = csv.DictWriter(csvf, fields, encoding = 'cp949') 
    wr.writerow(dict(zip(fields, fields))) 
    for resp in resps : 
     wr.writerow(resp) 

    csvf.seek(0) 

    now = datetime.datetime.now() 
    report_name = survey.name + "(" + \ 
        now.strftime("%Y-%m-%d-%H:%M:%S") +\ 
        ")" + ".csv" 

    report_name = report_name.encode("utf-8") 



    return send_file(csvf, 
       as_attachment = True, 
       attachment_filename = report_name) 

,你可以看到,文件名從Unicode轉換爲字符串,並以UTF-8(準確地,它們在韓語字母)

問題是,當在IE中查看頁面時,文件名完全被破壞(chrome中沒有問題)。

它看起來像頭必須進行編輯,以匹配不同瀏覽器的解析規則,但我不知道如何在瓶中做到這一點。

回答

3

嘗試增加

mimetype = 'text/csv; charset=x-EBCDIC-KoreanAndKoreanExtended' 

到由send_file。

+0

不起作用..仍然得到下載dialougue難以理解的文件名。 – thkang

+0

@thkang:看我的編輯。如果你將CSV編碼爲cp949(爲什麼你不使用UTF-8'?),那麼charset參數應該是x-EBCDIC-KoreanAndKoreanExtended,而不是UTF-8。 –

+0

爲cp949,因爲韓文窗口有點尷尬;據我所知,文件內容存儲在cp949中。我測試了cp949和utf-8,並且只有cp949字符串值是excel可讀的。 :(無論如何,在cp949中對report_name進行編碼並將上面的字符集添加到send_file之後,一切都很完美,謝謝。 – thkang

2

使用Content-Disposition: attachment; filename="..."設置下載文件的名稱 - 這是Flask的send_file的作用 - 對於非ASCII字符不可靠。

在Flask使用的werkzeug.http庫中支持RFC 5987之前,在所有您想要定位的瀏覽器中,這是不可修復的。

同時,更可靠的跨瀏覽器的方法是將UTF-8 URL編碼的文件名中的URI的結尾部分,當你做它的鏈接,即:

IRI path: /survey/1/report/안녕.csv 
URI path: /survey/1/report/%ec%95%88%eb%85%95.csv 

有關背景信息,請參閱How to encode UTF8 filename for HTTP headers? (Python, Django)