node.js - Nodejs 脚本不读取 GDOC 文件扩展名

标签 node.js google-drive-api google-docs

我正在使用 Google Drive for Developers Drive API (V3) Nodejs 快速入门。

我特别关注以下功能。我已将 pageSize 自定义为 1 以进行测试。我正在调用我的 函数 read(file.name);

    /**
 * Lists the names and IDs of up to 10 files.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listFiles(auth) {
  const drive = google.drive({version: 'v3', auth});
  drive.files.list({
    pageSize: 1,   // only find the last modified file in dev folder
    fields: 'nextPageToken, files(id, name)',
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err);
    const files = res.data.files;
    if (files.length) {
      console.log('Files:');
      files.map((file) => {
        console.log(`${file.name} (${file.id})`);
        read(file.name);   // my function here  
      });
    } else {
      console.log('No files found.');
    }
  });
}

// custom code - function to read and output file contents 
function read(fileName) {
  const readableStream = fs.createReadStream(fileName, 'utf8');

  readableStream.on('error', function (error) {
      console.log(`error: ${error.message}`);
  })

  readableStream.on('data', (chunk) => {
      console.log(chunk);
  })
}

此代码从同步的 Google Drive 文件夹中读取文件。我正在使用这个本地文件夹进行开发。我发现 pageSize: 1 参数生成了此本地文件夹中已修改的最后一个文件。因此我的流程是:

  • 编辑 .js 代码文件
  • 对测试文件进行少量编辑(首先是 txt,然后是 gdoc)以确保它是最后修改的
  • 运行代码

我正在针对 GDOC 文件测试文本文件。文件名分别为 atest.txt31832_226114__0001-00028.gdoc。输出结果如下:

    PS C:\Users\david\Google Drive\Technical-local\gDriveDev> node . gdocToTextDownload.js
Files:
atest.txt (1bm1E4s4ET6HVTrJUj4TmNGaxqJJRcnCC)
atest.txt this is a test file!!


PS C:\Users\david\Google Drive\Technical-local\gDriveDev> node . gdocToTextDownload.js
Files:
31832_226114__0001-00028 (1oi_hE0TTfsKG9lr8Wl7ahGNvMvXJoFj70LssGNFFjOg)
error: ENOENT: no such file or directory, open 'C:\Users\david\Google Drive\Technical-local\gDriveDev\31832_226114__0001-00028'

我的问题是: 为什么脚本读取的是文本文件而不是 gdoc?

此时我必须在函数调用中将 gdoc 文件扩展名“硬编码”到文件名,以根据文本文件示例生成所需的输出,例如

read('31832_226114__0001-00028.gdoc');

这显然不是我想做的。

我的目标是生成一个脚本,该脚本将下载大量从 .jpg 文件创建的 gdoc。

------------------------ 下面完成的代码-------------------- -----

/**
 * Lists the names and IDs of pageSize number of files (using query to define folder of files)
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
 function listFiles(auth) {
  const drive = google.drive({version: 'v3', auth});
 
 
  drive.files.list({
    corpora: 'user',  
    pageSize: 100,
    // files in a parent folder that have not been trashed 
    // get ID from Drive > Folder by looking at the URL after /folders/ 
    q: `'11Sejh6XG-2WzycpcC-MaEmDQJc78LCFg' in parents and trashed=false`,    
    fields: 'nextPageToken, files(id, name)',
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err);
    const files = res.data.files;
    if (files.length) {

      var ids = [ ];
      var names = [ ];
      files.forEach(function(file, i) {
        ids.push(file.id);
        names.push(file.name);
      });

      ids.forEach((fileId, i) => {
              fileName = names[i];

      downloadFile(drive, fileId, fileName);
      });

    } 
    else 
    {
      console.log('No files found.');
    }
  });
}

/**
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */ 

function downloadFile(drive, fileId, fileName) {
 
 // make sure you have valid path & permissions. Use UNIX filepath notation.
  
    const filePath = `/test/test1/${fileName}`;

  const dest = fs.createWriteStream(filePath);
  let progress = 0;

  drive.files.export(
    { fileId, mimeType: 'text/plain' },
    { responseType: 'stream' }
  ).then(res => {
    res.data
      .on('end', () => {
        console.log('  Done downloading');

      })  
      .on('error', err => {
        console.error('Error downloading file.');
      })  
      .on('data', d => {
        progress += d.length;
        if (process.stdout.isTTY) {
          process.stdout.clearLine();
          process.stdout.cursorTo(0);
          process.stdout.write(`Downloading ${fileName} ${progress} bytes`);
        }   
      })  
      .pipe(dest);
  }); 
}

最佳答案

My question is: Why does the script read the text file but not the gdoc?

这是因为您正在尝试下载 Google Workspace 文档,只能使用 drive.files.get 方法下载包含二进制内容的文件。对于 Google Workspace 文档,您需要使用 drive.files.exports as documented here

从你的代码中,我看到你只列出了文件,你需要确定你想要下载的文件类型,你可以使用 mimeType 字段来检查你是否需要使用exports 方法与get,例如,Google Doc mime 类型是application/vnd.google-apps.document 同时docx 文件(二进制)将是 application/vnd.openxmlformats-officedocument.wordprocessingml.document

检查以下工作示例:

<表类="s-表"> <头> 从 Google Drive 下载文件 Run in Fusebit
const fs = require("fs");

const getFile = async (drive, fileId, name) => {
    const res = await drive.files.get({ fileId, alt: "media" }, { responseType: "stream" });

    return new Promise((resolve, reject) => {
        const filePath = `/tmp/${name}`;
        console.log(`writing to ${filePath}`);
        const dest = fs.createWriteStream(filePath);
        let progress = 0;
        res.data
            .on("end", () => {
                console.log("🎉 Done downloading file.");
                resolve(filePath);
            })
            .on("error", (err) => {
                console.error("🚫 Error downloading file.");
                reject(err);
            })
            .on("data", (d) => {
                progress += d.length;
                console.log(`🕛 Downloaded ${progress} bytes`);
            })
            .pipe(dest);
    });
};

const fileKind = "drive#file";
let filesCounter = 0;
const drive = googleClient.drive({ version: "v3" });
const files = await drive.files.list();

// Only files with binary content can be downloaded. Use Export with Docs Editors files
// Read more at https://developers.google.com/drive/api/v3/reference/files/get
// In this example, any docx folder will be downloaded in a temp folder.
const onlyFiles = files.data.files.filter(
    (file) =>
        file.kind === fileKind &&
        file.mimeType === "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
);
const numberOfFilesToDownload = onlyFiles.length;
console.log(`😏 About to download ${numberOfFilesToDownload} files`);
for await (const file of onlyFiles) {
    filesCounter++;
    console.log(`📁 Downloading file ${file.name}, ${filesCounter} of ${numberOfFilesToDownload}`);
    await getFile(drive, file.id, file.name);
}


关于node.js - Nodejs 脚本不读取 GDOC 文件扩展名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70502842/

相关文章:

google-apps-script - 如何在 google apps 脚本中使用 DeveloperMetadataVisibility 枚举?

google-drive-api - 使用谷歌选择器打开特定的 MimeTypes

node.js - 逐行扫描谷歌文档

node.js - 从node.js中的mongo db获取最后插入的Id

node.js - 处理来自 EventEmitter 的错误

javascript - 在 javascript 中使用反射来获取失败时测试函数的名称

java - 使用 Google APIs Java 客户端进行连接和授权

javascript - 将包含不同 PDF 的电子邮件发送到不同的电子邮件附件

javascript - 谷歌文档 : click a button or change style with userscript (tampermonkey)

javascript - onclick 函数在 Node js 中不起作用