Google Drive Web API save and download pdf

Viewed 794

I am trying to get a pdf from google drive and download it in the browser (I actually need it as an array buffer or blob to use it with pspdfkit, but this dose the same thing and it's simpler to describe). I tried it in many ways so far and couldn't get a pdf from the response I got from the api.

I want to specify that this is part of an angular 10 app, but I don't think it's to relevant. Also I need to specify that I am using typescript, but I also did a js version to test, same seem to produce the same result.

The doc object comes from the google drive picker google.picker.PickerBuilder

This is the code I use to get the file contents

gapi.client.drive.files
 .get({
  fileId: doc.id,
  alt: 'media',
  // mimeType: 'application/pdf', // <- with or without
  // responseType: 'arraybuffer', // <- with or without
 })
 .then((res) => {
  // manipulate res.body
  window.resb=res.body;
  // HERE <- I continue to call saveFile and debug the response
 });

This is the function I use to test if I can use the response as a pdf file:

function saveFile(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    }, 0)
  }
}

This is another function that I try and parse the string to an arraybuffer

function str2ab(str) {
  var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
  var bufView = new Uint16Array(buf);
  for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

This is how I actually call the download function

saveFile(new Blob([resb],{type: 'application/pdf',}),'a.pdf'); // <- only one that actually produces an openable pdf file, but empty

or

saveFile(new Blob([str2ab(resb)],{type: 'application/pdf',}),'a.pdf');

or

saveFile(new Blob(str2ab(resb),{type: 'application/pdf',}),'a.pdf');

... and a few other methods.

I am fresh out of ideas and I am at a (618).pdf. Please help :)

EDIT: attaching partial console.log(resb); resb

1 Answers

I believe your goal as follows.

  • You want to download a PDF file from Google Drive using Javascript.
  • Your gapi.client can be used for downloading the file.

In this case, I would like to propose to modify the script for converting from the binary data to blob.

Modified script:

A simple modified script is as follows. When you run this script, a PDF file is downloaded and save it to the local PC as a file.

gapi.client.drive.files
 .get({
  fileId: doc.id,
  alt: 'media',
 })
 .then((res) => {
   const filename = "sample.pdf";
   
   // Convert binary data to blob.
   const data = res.body;
   const len = data.length;
   const ar = new Uint8Array(len);
   for (let i = 0; i < len; i++) {
     ar[i] = data.charCodeAt(i);
   }
   const blob = new Blob([ar], {type: 'application/pdf'});
   
   // Save the file.
   const a = document.createElement('a');
   document.body.appendChild(a);
   const url = window.URL.createObjectURL(blob);
   a.href = url;
   a.download = filename;
   a.click();
 });

Reference:

Related