写了个小网页,实现的功能是:
- 1.在前端网页选择项中选择指定内容;
- 2.传送给后端服务器,查询数据库找出相应的内容;
- 3.并把这些内容存放Excel表格后,把下载链接提供回前端页面上显示。
然后下载数据文件。
在Windows系统中测试的时候没有任何问题。
然后把项目部署到Docker(Linux),然后发现Linux系统中不行了,因为Excel数据文件名也是中文,然后就有了编码问题。
搜了下后,发现用 urllib.parse
库的 quote(编码), unquote(解码)来解决。
其间还碰到一个小问题,就是:
1 2 3 4 5 6
| 在Windows系统中,文件路径使用反斜杠(\)作为路径分隔符。 而在Linux系统中,文件路径使用正斜杠(/)作为路径分隔符。
因此,在Windows系统中,filename的值为static\ex_data\数据.xlsx,而在Linux系统中,filename的值为static/ex_data/数据.xlsx。
在进行URL编码时,正斜杠(/)不会被编码,而反斜杠(\)会被编码为%5C。
|
解决方法案例
编码前的关键代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ... @app.route('/download', methods=['GET', 'POST']) def download(): ... if request.method == 'POST': ... filename = write_to_excel(data, ex_filename) download_url = url_for('download_file', filename=filename) ...
@app.route('/download_file/<path:filename>', methods=['GET']) def download_file(filename): return send_file(filename, as_attachment=True) ...
def write_to_excel(data, ex_filename): df = pd.DataFrame(data) ex_path = os.path.join('static', 'ex_data') if not os.path.exists(ex_path): os.makedirs(ex_path) file_path = os.path.join(ex_path, f'{ex_filename}.xlsx') df.to_excel(file_path, index=False) return file_path
|
编码后的关键代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| from urllib.parse import quote, unquote ... @app.route('/download', methods=['GET', 'POST']) def download(): ... if request.method == 'POST': ... filename = write_to_excel(data, ex_filename) encoded_filename = urllib.parse.quote(filename) download_url = url_for('download_file', filename=encoded_filename) ...
@app.route('/download_file/<path:filename>', methods=['GET']) def download_file(filename): decoded_filename = urllib.parse.unquote(filename) return send_file(decoded_filename, as_attachment=True) ...
def write_to_excel(data, ex_filename): df = pd.DataFrame(data) ex_path = os.path.join('static', 'ex_data') if not os.path.exists(ex_path): os.makedirs(ex_path) file_path = os.path.join(ex_path, f'{ex_filename}.xlsx') df.to_excel(file_path, index=False) return file_path
|