摘要:解決辦法如下測試表格我們從引入,首先對文件名進行編碼,然后中作為的參數(shù),這時候能成功下載文件,但是文件名是編碼后的名字,要解碼的話,我們需要在里面聲明編碼格式,即這樣的話,對文件名進行解碼,我們的文件名就是中文了。
在寫 flask 后端的時候,特別是在做數(shù)據(jù)相關(guān)的操作的時候,產(chǎn)品往往需要我們做一個導(dǎo)出數(shù)據(jù)的需求,一般都是導(dǎo)出 excel 格式的文件。
那在 flask 上,如何實現(xiàn)請求連接即可讓瀏覽器下載呢?有兩種思路。
一:
文件在本地磁盤,這時候我們只需要發(fā)送相應(yīng)的地址過去即可。
二:
通過 io 中的 BytesIO, 把文件以二進制的形式發(fā)送過去,這里我們需要使用 flask 自帶的 send_file。
第一種的壞處在于不便于權(quán)限控制,拿到下載鏈接在哪都能下載,第二種方法的缺陷在于只能接收 get 請求,post 請求發(fā)送的文件瀏覽器是不能識別的。
要實現(xiàn) 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() 成數(shù)據(jù)流的形式發(fā)出去,瀏覽器接收到這些數(shù)據(jù)流,回自動進行下載,文件名即是 send_file 參數(shù)中的 attachment_filename, 在我們這里便是 dream.xlsx 。
啟動程序,在瀏覽器中輸入 127.0.0.1:5000/download, 即可下載名為 dream.xlsx 的文件。
我們打開看看:
的確是我們生成的一個 excel 表格。
現(xiàn)在問題來了,這里的文件名是英文的,那我們需要中文怎么辦?直接把 attachment_filename 參數(shù)改成 attachment_filename="測試表格.xlsx"可以么?
我們來試試:
return send_file(out, as_attachment=True, attachment_filename="測試表格.xlsx")
其余代碼不變,僅有此處發(fā)成改變。
運行代碼,瀏覽器訪問下載試試。
瀏覽器沒有任何反應(yīng),代表我們沒有把數(shù)據(jù)流傳給它,看程序,也報錯了,報錯信息:
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 的參數(shù),這時候能成功下載文件,但是文件名是編碼后的名字,要解碼的話,我們需要在 headers 里面聲明編碼格式,即:
rv.headers["Content-Disposition"] += "; filename*=utf-8""{}".format(filename)
這樣的話,對文件名進行 UTF-8 解碼,我們的文件名就是中文了。
如圖:
打開文件,也是我們想要的,如圖:
大功告成!
當(dāng)然實際生產(chǎn)工作中,數(shù)據(jù)量是是非常大的,生成 excel 文件將會特別耗時,我們當(dāng)然不希望我們的程序在此堵塞, 這時候我們可以使用 celery 異步任務(wù),返回前端一個任務(wù) ID, 前端去輪詢這個任務(wù) ID,當(dāng)文件生成好了,即可開始下載。
由于有些時候我們 get 請求無法滿足我們的參數(shù)傳遞,比如有多個嵌套對象作為參數(shù)傳遞,我們必須使用 post 請求,這時候同樣可以采用 celery 異步任務(wù)的方式,返回任務(wù) ID, 輪詢?nèi)蝿?wù)狀態(tài),下載文件。
之后我會寫一篇教程,celery 異步任務(wù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41093.html
摘要:最近由于工作關(guān)系,開始寫程序,同事有用的,有用的。第一種適合及以上版本,因為在版本起,出現(xiàn)了文件,配置可以寫成用文件啟動程序,實測可以觸發(fā)斷點。 最近由于工作關(guān)系,開始寫flask web程序,同事有用Vim的,有用PyCharm的。在調(diào)研了一通python的編輯器,IDE之后,發(fā)現(xiàn)Visual Studio Code相對比較適合我。 VSC有相對較全的功能,比較好看舒服的主題,良好的...
摘要:原創(chuàng)個人網(wǎng)站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區(qū)引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區(qū)作為上傳區(qū)也很簡單點我上傳下面兩行是和的方式實現(xiàn)綁定的例子 原創(chuàng)【個人網(wǎng)站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區(qū) 引入Dropzone.js和d...
摘要:原創(chuàng)個人網(wǎng)站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區(qū)引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區(qū)作為上傳區(qū)也很簡單點我上傳下面兩行是和的方式實現(xiàn)綁定的例子 原創(chuàng)【個人網(wǎng)站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區(qū) 引入Dropzone.js和d...
摘要:原創(chuàng)個人網(wǎng)站歡迎訪問說明后臺用的的框架,后臺對你理解這篇文章沒什么影響,你可以使用作為上傳區(qū)引入和然后使用表單定義一個即可完成第一種上傳第一種上傳效果作為上傳區(qū)作為上傳區(qū)也很簡單點我上傳下面兩行是和的方式實現(xiàn)綁定的例子 原創(chuàng)【個人網(wǎng)站歡迎訪問】說明:后臺用的python的flask框架,后臺對你理解這篇文章沒什么影響,你可以使用php form作為上傳區(qū) 引入Dropzone.js和d...
摘要:鏈接中文翻譯常用庫推薦除了上面提到的之外,也是一個很好的選項。官網(wǎng)中文翻譯如果你要編寫簡單的爬蟲,來爬去互聯(lián)網(wǎng)上的信息,或者調(diào)用一些外部的機遇的接口,使用這個庫再也合適不過了。 作者:安龍 LeanCloud 工程師 引言 :前段時間有同學(xué)反映 Python 的學(xué)習(xí)資源匯總很少。那么學(xué)習(xí)資料哪個質(zhì)量更好,效率更高?Python 有哪些非常值得學(xué)習(xí)的庫?2017 年了學(xué) 2 還是學(xué) 3 ...
閱讀 1694·2019-08-30 15:54
閱讀 3346·2019-08-26 17:15
閱讀 3536·2019-08-26 13:49
閱讀 2589·2019-08-26 13:38
閱讀 2301·2019-08-26 12:08
閱讀 3065·2019-08-26 10:41
閱讀 1378·2019-08-26 10:24
閱讀 3387·2019-08-23 18:35