aalv
aalv

Reputation: 75

How to correctly read PDF into nodejs Buffer from Google Drive API's export method?

I'm trying to read a PDF from the Google Drive v2 API export method into a nodejs Buffer so it can be emailed as an attachment or saved, but when I view it, it looks blank, like all whitespace. I'd expect the PDF to appear the same as when exported and viewed through the Google Drive browser app. Namely that something shows, since the content-length: 55243.

I've tried the following:

  var drive = google.drive('v2');
  drive.files.export({
    auth: auth,
    fileId: ...,
    mimeType: 'application/pdf'
  })
  .then(res => {

      let buf = Buffer.from(res.data, 'utf-8');//tried 'latin1', didn't work
      fs.writeFileSync("file.pdf", buf);
  })

The raw HTTP response

    HTTP/1.1 200 
    cache-control: private, max-age=0, must-revalidate, no-transform
    content-encoding: gzip
    content-length: 55243
    content-type: text/plain; charset=UTF-8
    date: Sat, 01 Feb 2020 15:04:46 GMT
    etag: "x2jdlkqYTB8kzPmV7jH2KPtlR68/iXa-VTcVlqvfqgBwCPMhdnUXfUk"
    expires: Sat, 01 Feb 2020 15:04:46 GMT
    server: GSE
    vary: Origin, X-Origin
    Content-Type: application/pdf

    %PDF-1.4
    ...
    ...

What needs to be fixed in my code? Can you show how to read the PDF into the Buffer correctly?

Upvotes: 5

Views: 2724

Answers (1)

Tanaike
Tanaike

Reputation: 201553

  • You want to export Google Docs (Spreadsheet, Document and Slides) as a PDF file using the array buffer from Google Drive.
  • You want to achieve this using Drive API v2 with googleapis of Node.js.
  • You have already been able to get the file using Drive API.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

Pattern 1:

In this pattern, the array buffer is used.

Modified script:

const drive = google.drive({version: "v2"});
drive.files.export(
  {
    auth: auth,
    fileId: "###",  // Please set the file ID of Google Docs.
    mimeType: "application/pdf"
  },
  { responseType: "arraybuffer" },
  (err, res) => {
    if (err) {
      console.log(err);
    } else {
      fs.writeFile("file.pdf", Buffer.from(res.data), function(err) {
        if (err) {
          return console.log(err);
        }
      });
    }
  }
);

Pattern 2:

In this pattern, the stream is used.

Modified script:

const drive = google.drive({version: "v2"});
var dest = fs.createWriteStream("file.pdf");
drive.files.export(
  {
    auth: auth,
    fileId: "###",  // Please set the file ID of Google Docs.
    mimeType: "application/pdf"
  },
  { responseType: "stream" },
  function(err, response) {
    if (err) {
      console.log(err);
      return;
    }
    response.data
      .on("end", function() {
        console.log("Done.");
      })
      .on("error", function(err) {
        console.log("Error during download", err);
        return process.exit();
      })
      .pipe(dest);
  }
);

Note:

  • Please use the latest version of googleapis.
  • And in above script, when const drive = google.drive({version: "v2"}); is modified to const drive = google.drive({version: "v3"});, the Drive API v3 can be also used.

References:

If I misunderstood your question and this was not the direction you want, I apologize.

Upvotes: 4

Related Questions