You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Drive API返回200成功但未导出PDF文件的问题

问题:调用Google Drive API v3导出GDOC为PDF返回HTTP 200,但本地未生成目标文件

问题详情

用户通过Node.js脚本调用Google Drive API v3导出GDOC文件为PDF,脚本执行后返回HTTP 200状态码,但本地未生成目标PDF文件。期望实现与手动下载PDF一致的效果,此前导出纯文本的方式已失效。

原因分析

HTTP 200状态码说明API请求已成功,Google Drive服务端已经返回了PDF的二进制数据,但当前脚本仅发起了导出请求并打印了状态码,没有将响应中的PDF数据写入本地文件,因此看不到生成的文件。

修复后的脚本

修改exportPdf函数,添加文件写入逻辑,将API返回的二进制数据保存到本地:

// File export test: Authorization code: https://gist.github.com/LindaLawton/76bef3ab760f335d43eccaf481e0b4d0 
// Google Ref https://github.com/googleworkspace/node-samples/blob/main/drive/snippets/drive_v3/file_snippets/export_pdf.js

const fs = require('fs');
const fsp = fs.promises;

const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive'];
// File id of the file to download = ocrTransfer folder in My Drive
const FILEID = '1_h-GsdKAqmu0hmZAmGslfqvE7W9ppMlt2WNGhi9diYk';

// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = path.join(process.cwd(), 'DownloadFileToken.json');
const CREDENTIALS_PATH = 'C:\\googleDriveDev\\credentials.json';

/**
 * Reads previously authorized credentials from the save file.
 *
 * @return {Promise<OAuth2Client|null>}
 */
async function loadSavedCredentialsIfExist() {
    try {
        const content = await fsp.readFile(TOKEN_PATH);
        const credentials = JSON.parse(content);
        return google.auth.fromJSON(credentials);
    } catch (err) {
        return null;
    }
}

/**
 * Serializes credentials to a file compatible with GoogleAUth.fromJSON.
 *
 * @param {OAuth2Client} client
 * @return {Promise<void>}
 */
async function saveCredentials(client) {
    const content = await fsp.readFile(CREDENTIALS_PATH);
    const keys = JSON.parse(content);
    const key = keys.installed || keys.web;
    const payload = JSON.stringify({
        type: 'authorized_user',
        client_id: key.client_id,
        client_secret: key.client_secret,
        refresh_token: client.credentials.refresh_token,
    });
    await fsp.writeFile(TOKEN_PATH, payload);
}

/**
 * Load or request or authorization to call APIs.
 *
 */
async function authorize() {
    let client = await loadSavedCredentialsIfExist();
    if (client) {
        return client;
    }
    client = await authenticate({
        scopes: SCOPES,
        keyfilePath: CREDENTIALS_PATH,
    });
    if (client.credentials) {
        await saveCredentials(client);
    }
    return client;
}


/**
 * Download a Document file in PDF format
 * @param{string} fileId file ID
 * @return{obj} file status
 * */

async function exportPdf(authClient) {
  
  const service = google.drive({version: 'v3', auth: authClient});

  try {
    
    const result = await service.files.export({
      fileId: FILEID,
      mimeType: 'application/pdf',
      responseType: 'stream' // 指定响应类型为流,更适合处理大文件
    });

    // 将响应流写入本地文件
    const writeStream = fs.createWriteStream('exported.pdf');
    result.data.pipe(writeStream);

    return new Promise((resolve, reject) => {
      writeStream.on('finish', () => {
        console.log('PDF文件已成功生成');
        resolve(result);
      });
      writeStream.on('error', (err) => {
        reject(err);
      });
    });

  } catch (err) {
    throw err;
  }
}

authorize().then(exportPdf).catch(console.error);

关键修改点

  1. 添加responseType: 'stream'参数:指定API响应以流的形式返回,更高效处理PDF这类可能较大的文件,避免内存占用过高。
  2. 创建文件写入流:使用fs.createWriteStream创建本地文件的写入流,将API返回的数据流通过pipe方法写入文件。
  3. 监听流的完成/错误事件:确保文件写入完成后再返回结果,同时处理写入过程中的异常。

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:14:52