摘要:解決辦法如下測試表格我們從引入,首先對文件名進行編碼,然后中作為的參數,這時候能成功下載文件,但是文件名是編碼后的名字,要解碼的話,我們需要在里面聲明編碼格式,即這樣的話,對文件名進行解碼,我們的文件名就是中文了。
在寫 flask 后端的時候,特別是在做數據相關的操作的時候,產品往往需要我們做一個導出數據的需求,一般都是導出 excel 格式的文件。
那在 flask 上,如何實現請求連接即可讓瀏覽器下載呢?有兩種思路。
一:
文件在本地磁盤,這時候我們只需要發送相應的地址過去即可。
二:
通過 io 中的 BytesIO, 把文件以二進制的形式發送過去,這里我們需要使用 flask 自帶的 send_file。
第一種的壞處在于不便于權限控制,拿到下載鏈接在哪都能下載,第二種方法的缺陷在于只能接收 get 請求,post 請求發送的文件瀏覽器是不能識別的。
要實現 send_file, 是很容易的, 代碼如下(適用于 python 3):
import xlsxwriter from io import BytesIO from flask import Flask, send_file app = Flask(__name__) @app.route("/download", methods=["GET"]) def download(): out = BytesIO() workbook = xlsxwriter.Workbook(out) table = workbook.add_worksheet() table.write(0, 0, "name") table.write(0, 1, "age") workbook.close() out.seek(0) return send_file(out, as_attachment=True, attachment_filename="dream.xlsx") if __name__ == "__main__": app.run(debug=True)
這是一個完整的后端程序,能夠直接跑起來。
其中我們用到了 xlsxwriter 這個庫,用來生成一個 excel 文件, 直接傳給 BytesIO() 成數據流的形式發出去,瀏覽器接收到這些數據流,回自動進行下載,文件名即是 send_file 參數中的 attachment_filename, 在我們這里便是 dream.xlsx 。
啟動程序,在瀏覽器中輸入 127.0.0.1:5000/download, 即可下載名為 dream.xlsx 的文件。
我們打開看看:
的確是我們生成的一個 excel 表格。
現在問題來了,這里的文件名是英文的,那我們需要中文怎么辦?直接把 attachment_filename 參數改成 attachment_filename="測試表格.xlsx"可以么?
我們來試試:
return send_file(out, as_attachment=True, attachment_filename="測試表格.xlsx")
其余代碼不變,僅有此處發成改變。
運行代碼,瀏覽器訪問下載試試。
瀏覽器沒有任何反應,代表我們沒有把數據流傳給它,看程序,也報錯了,報錯信息:
UnicodeEncodeError: "latin-1" codec can"t encode characters in position 43-46: ordinal not in range(256)
編碼問題。
解決辦法如下:
import xlsxwriter from io import BytesIO from flask import Flask, send_file from urllib.parse import quote app = Flask(__name__) @app.route("/download", methods=["GET"]) def download(): out = BytesIO() workbook = xlsxwriter.Workbook(out) table = workbook.add_worksheet() table.write(0, 0, "name") table.write(0, 1, "age") workbook.close() out.seek(0) filename = quote("測試表格.xlsx") rv = send_file(out, as_attachment=True, attachment_filename=filename) rv.headers["Content-Disposition"] += "; filename*=utf-8""{}".format(filename) return rv if __name__ == "__main__": app.run(debug=True)
我們從 urllib.parse 引入 quote, 首先對文件名進行編碼,然后 send_file 中 作為 attachment_filename 的參數,這時候能成功下載文件,但是文件名是編碼后的名字,要解碼的話,我們需要在 headers 里面聲明編碼格式,即:
rv.headers["Content-Disposition"] += "; filename*=utf-8""{}".format(filename)
這樣的話,對文件名進行 UTF-8 解碼,我們的文件名就是中文了。
如圖:
打開文件,也是我們想要的,如圖:
大功告成!
當然實際生產工作中,數據量是是非常大的,生成 excel 文件將會特別耗時,我們當然不希望我們的程序在此堵塞, 這時候我們可以使用 celery 異步任務,返回前端一個任務 ID, 前端去輪詢這個任務 ID,當文件生成好了,即可開始下載。
由于有些時候我們 get 請求無法滿足我們的參數傳遞,比如有多個嵌套對象作為參數傳遞,我們必須使用 post 請求,這時候同樣可以采用 celery 異步任務的方式,返回任務 ID, 輪詢任務狀態,下載文件。
之后我會寫一篇教程,celery 異步任務。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/41093.html
摘要:最近由于工作關系,開始寫程序,同事有用的,有用的。第一種適合及以上版本,因為在版本起,出現了文件,配置可以寫成用文件啟動程序,實測可以觸發斷點。 最近由于工作關系,開始寫flask web程序,同事有用Vim的,有用PyCharm的。在調研了一通python的編輯器,IDE之后,發現Visual Studio Code相對比較適合我。 VSC有相對較全的功能,比較好看舒服的主題,良好的...
摘要:原創個人網站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區作為上傳區也很簡單點我上傳下面兩行是和的方式實現綁定的例子 原創【個人網站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區 引入Dropzone.js和d...
摘要:原創個人網站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區作為上傳區也很簡單點我上傳下面兩行是和的方式實現綁定的例子 原創【個人網站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區 引入Dropzone.js和d...
摘要:原創個人網站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區作為上傳區也很簡單點我上傳下面兩行是和的方式實現綁定的例子 原創【個人網站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區 引入Dropzone.js和d...
摘要:鏈接中文翻譯常用庫推薦除了上面提到的之外,也是一個很好的選項。官網中文翻譯如果你要編寫簡單的爬蟲,來爬去互聯網上的信息,或者調用一些外部的機遇的接口,使用這個庫再也合適不過了。 作者:安龍 LeanCloud 工程師 引言 :前段時間有同學反映 Python 的學習資源匯總很少。那么學習資料哪個質量更好,效率更高?Python 有哪些非常值得學習的庫?2017 年了學 2 還是學 3 ...
閱讀 1689·2019-08-30 15:54
閱讀 3343·2019-08-26 17:15
閱讀 3532·2019-08-26 13:49
閱讀 2588·2019-08-26 13:38
閱讀 2299·2019-08-26 12:08
閱讀 3060·2019-08-26 10:41
閱讀 1376·2019-08-26 10:24
閱讀 3386·2019-08-23 18:35