Angular接收Python后端传输的Excel文件无法打开,求缺失步骤
问题:传输后的Excel文件无法被Excel打开,缺失哪一步?
我需要将包含图表与数据的Excel表格从Python后端传输至Angular-JavaScript前端。为使用HttpClient,我在后端将二进制数据编码进JSON:
the_data = None with open(output_file_path, mode='rb') as file: output_file = file.read() if output_file: binary_data = base64.encodebytes(output_file).decode('utf-8') the_data = { 'file': binary_data, 'name': 'export.xlsx', 'type': 'file' } dump_str = json.dumps(the_data) js = json.loads(dump_str) return js
随后在前端尝试解码数据并保存为Excel文件:
import * as FileSaver from 'file-saver'; ... this._service.export(request).subscribe((data:{}) => { const name = (data as any)['name'] const b64Data = (data as any)['file']; const byteCharacters = atob(b64Data); const data: Blob = new Blob([byteCharacters], { type: "application/octet-stream" }); FileSaver.saveAs(data, name); });
但生成的export.xlsx无法被Excel打开,请问缺失了哪一步?
解决方案
核心问题是前端将base64解码后的字符串直接转为Blob,字符串编码与二进制文件的字节流不匹配,导致文件损坏。同时后端的base64编码方式存在冗余换行符问题,需同步优化。
1. 前端代码修正
将解码后的字符串转换为Uint8Array(二进制字节数组)后再生成Blob,同时指定正确的Excel文件MIME类型:
import * as FileSaver from 'file-saver'; ... this._service.export(request).subscribe((data:{}) => { const name = (data as any)['name']; const b64Data = (data as any)['file']; const byteCharacters = atob(b64Data); // 将字符串转为Uint8Array二进制数组 const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); // 用二进制数组生成Blob,指定Excel专属MIME类型 const blob = new Blob([byteArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); FileSaver.saveAs(blob, name); });
2. 后端代码优化
base64.encodebytes会在每76个字符后自动添加换行符,这些换行符会被JSON序列化保留,导致前端解码后的字节流包含无效字符。改用base64.b64encode即可避免该问题:
import base64 import json the_data = None with open(output_file_path, mode='rb') as file: output_file = file.read() if output_file: # 使用b64encode替代encodebytes,避免生成冗余换行符 binary_data = base64.b64encode(output_file).decode('utf-8') the_data = { 'file': binary_data, 'name': 'export.xlsx', 'type': 'file' } # 无需先dump再load,直接返回字典即可 return the_data
内容的提问来源于stack exchange,提问作者xymzh
相关产品推荐
相关产品推荐

