diff --git a/examples/tiny_example.py b/examples/tiny_example.py index 693bb3a..84289d0 100644 --- a/examples/tiny_example.py +++ b/examples/tiny_example.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ tiny_example.py :copyright: (c) 2015 by C. W. @@ -34,6 +35,12 @@ def export_records(): file_name="export_data") +@app.route("/download_file_named_in_unicode", methods=['GET']) +def download_file_named_in_unicode(): + return excel.make_response_from_array([[1, 2], [3, 4]], "csv", + file_name=u"中文文件名") + + # insert database related code here if __name__ == "__main__": app.run() diff --git a/flask_excel/__init__.py b/flask_excel/__init__.py index b10147a..ee3ca4e 100644 --- a/flask_excel/__init__.py +++ b/flask_excel/__init__.py @@ -8,6 +8,15 @@ :copyright: (c) 2015 by Onni Software Ltd. :license: New BSD License """ +try: + # if in py2 + from urllib import quote + _PY_VERSION = 2 +except ImportError: + # else (aka in py3) + from urllib.parse import quote + _PY_VERSION = 3 + from flask import Flask, Request, Response import pyexcel_webio as webio @@ -38,8 +47,13 @@ def _make_response(content, content_type, status, file_name=None): """ response = Response(content, content_type=content_type, status=status) if file_name: + if _PY_VERSION == 2 and isinstance(file_name, unicode): + file_name = file_name.encode('utf-8') + url_encoded_file_name = quote(file_name) response.headers["Content-Disposition"] = ( - "attachment; filename=%s" % (file_name)) + "attachment; filename=%s;filename*=utf-8''%s" + % (url_encoded_file_name, url_encoded_file_name) + ) return response diff --git a/tests/test_upload_n_download_excel.py b/tests/test_upload_n_download_excel.py index b4bc8e8..80c951c 100644 --- a/tests/test_upload_n_download_excel.py +++ b/tests/test_upload_n_download_excel.py @@ -1,3 +1,10 @@ +# -*- coding: utf-8 -*- + +try: + from urllib import quote +except ImportError: + from urllib.parse import quote + from testapp import app import pyexcel as pe from nose.tools import eq_ @@ -71,8 +78,35 @@ def test_no_file_type(self): def test_override_file_name(self): for file_type in FILE_TYPE_MIME_TABLE.keys(): file_name = 'override_file_name' + url_encoded_file_name = quote(file_name) + response = self.app.post('/file_name/%s/%s' % (file_type, + file_name)) + eq_(response.content_type, FILE_TYPE_MIME_TABLE[file_type]) + eq_(response.headers.get("Content-Disposition", None), + ("attachment; filename=%s.%s;filename*=utf-8''%s.%s" + % (url_encoded_file_name, file_type, + url_encoded_file_name, file_type))) + + def test_unicode_file_name(self): + for file_type in FILE_TYPE_MIME_TABLE.keys(): + file_name = u'中文文件名' + url_encoded_file_name = quote(file_name.encode('utf-8')) + response = self.app.post('/file_name/%s/%s' % (file_type, + file_name)) + eq_(response.content_type, FILE_TYPE_MIME_TABLE[file_type]) + eq_(response.headers.get("Content-Disposition", None), + ("attachment; filename=%s.%s;filename*=utf-8''%s.%s" + % (url_encoded_file_name, file_type, + url_encoded_file_name, file_type))) + + def test_utf8_file_name(self): + for file_type in FILE_TYPE_MIME_TABLE.keys(): + file_name = '中文文件名' + url_encoded_file_name = quote(file_name) response = self.app.post('/file_name/%s/%s' % (file_type, file_name)) eq_(response.content_type, FILE_TYPE_MIME_TABLE[file_type]) eq_(response.headers.get("Content-Disposition", None), - ("attachment; filename=%s.%s" % (file_name, file_type))) + ("attachment; filename=%s.%s;filename*=utf-8''%s.%s" + % (url_encoded_file_name, file_type, + url_encoded_file_name, file_type)))