设置mimeType后下载的Google Drive表格仍为0字节损坏?求解决方案
Google Drive导出表格为0字节损坏文件的解决方案
我之前也碰到过一模一样的情况!你写的代码会生成0字节无法打开的文件,核心问题出在回调函数的语法错误,另外也可能和权限范围的配置有关。先给你拆解下错误点:
错误代码的问题分析
- 回调函数位置错误:在你的
grabFileFromDrive函数里,drive.files.export的调用语法完全错了——你用逗号把方法调用和回调函数分开了,导致回调根本没被执行,写入流完全没拿到数据,最终生成空文件。// 错误写法:逗号分隔,回调未传入方法参数 drive.files.export({...}, { responseType: 'stream' }), function(err, res){...} - 权限范围的潜在问题:虽然你用了
https://www.googleapis.com/auth/drive全权限范围,但如果之前的token是用旧范围生成的,可能会导致权限不足,不过这个是次要问题,主要还是语法错误导致的无数据写入。
修复后的可行代码
我重新调整了代码结构,修正了回调的传入方式,同时确保权限流程正常,现在可以导出正常的表格文件(下面示例导出为CSV,你可以换成Excel的MIME类型):
const fs = require('fs'); const readline = require('readline'); const { google } = require('googleapis'); // 如果修改权限范围,请删除token.json重新生成 const SCOPES = 'https://www.googleapis.com/auth/drive'; const TOKEN_PATH = 'token.json'; // 加载本地的客户端密钥文件 fs.readFile('credentials.json', (err, content) => { if (err) return console.log('加载客户端密钥文件出错:', err); // 授权后调用Drive API下载文件 authorize(JSON.parse(content), downloadDriveFile); }); function authorize(credentials, callback) { const { client_secret, client_id, redirect_uris } = credentials.installed; const oAuth2Client = new google.auth.OAuth2( client_id, client_secret, redirect_uris[0]); // 检查是否已有存储的token fs.readFile(TOKEN_PATH, (err, token) => { if (err) return getAccessToken(oAuth2Client, callback); oAuth2Client.setCredentials(JSON.parse(token)); callback(oAuth2Client); }); } function getAccessToken(oAuth2Client, callback) { const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES, }); console.log('请访问此链接授权应用:', authUrl); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('请输入页面上的授权代码: ', (code) => { rl.close(); oAuth2Client.getToken(code, (err, token) => { if (err) return console.error('获取访问令牌出错', err); oAuth2Client.setCredentials(token); // 将token存储到本地供后续使用 fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => { if (err) console.error(err); console.log('Token已存储到', TOKEN_PATH); }); callback(oAuth2Client); }); }); } function downloadDriveFile(auth) { const drive = google.drive({ version: 'v3', auth }); const fileId = 'xxxxxxxxxxxxxxx'; // 替换成你的文件ID const dest = fs.createWriteStream('/tmp/feedback.csv'); // 输出路径 drive.files.export({ fileId: fileId, // 如果要导出Excel,替换为 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' mimeType: 'text/csv' }, { responseType: 'stream' }, function (err, res) { if (err) { console.error('导出文件出错:', err); return; } res.data .on('end', () => { console.log('文件下载完成'); }) .on('error', err => { console.log('数据流出错:', err); }) .pipe(dest); }); }
关键修复点
- 把回调函数正确作为
drive.files.export的第三个参数传入,确保数据流能被正常处理并写入文件 - 增加了错误判断,避免无意义的数据流操作
- 保持了权限流程的完整性,确保token能正确生成和存储
内容的提问来源于stack exchange,提问作者ZADorkMan
相关产品推荐
相关产品推荐

