Node.js调用Google Sheets API下载win1252编码Excel损坏如何解决
问题根因
文件损坏是代码的两个核心错误导致的:
- axios默认
responseType为json,会将接口返回的二进制Excel流按UTF-8规则解析为字符串,这个过程会直接篡改文件原始字节,后续再用iconv转码也无法还原已损坏的二进制结构。 - xlsx格式本质是zip压缩的二进制复合文档,不能先解码为普通字符串再写入磁盘,必须保留原始字节流写入。
补充:Windows 1252是文本类返回内容的编码,若接口直接返回标准Excel二进制流,不需要手动做编码转换,手动转码反而会破坏文件结构。
可直接运行的正确代码
修改axios请求配置,指定响应为二进制格式,去掉不必要的编码转换逻辑:
const axios = require('axios'); const fs = require('fs'); axios.get(api, { headers: { "Authorization": `Bearer ${token}`, // 删除原来错误的Content-Type:application/json配置,下载文件不需要声明接收json "Accept": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, */*" }, // 核心配置:指定响应类型为数组缓冲区,禁止axios自动将二进制内容解析为字符串 responseType: 'arraybuffer' }) .then(res => { // 直接将原始二进制Buffer写入文件,无需调用iconv解码 fs.writeFile('NodeReport.xlsx', res.data, (writeErr) => { if (writeErr) { console.error('文件写入失败:', writeErr); return; } console.log('Excel文件保存完成,可正常打开'); }); }) .catch(reqErr => { console.error('接口请求失败:', reqErr); });
特殊场景适配
如果接口实际返回的是Windows 1252编码的CSV纯文本(而非xlsx二进制流),可以在拿到Buffer类型的响应数据后再做转码,保存为csv格式:
const iconv = require('iconv-lite'); // 对原始Buffer做win1252转码 const csvText = iconv.decode(res.data, 'win1252'); fs.writeFile('NodeReport.csv', csvText, 'utf8', (writeErr) => { // 写入回调逻辑 });
校验方法:对比Postman保存的正常文件大小,和代码中
res.data.length打印的字节数,二者一致则说明你拿到了完整的原始响应内容,之前的损坏完全是自动字符串解析导致的。
内容的提问来源于stack exchange,提问作者Seth
相关产品推荐
相关产品推荐

