0

I'm using Google App script to enable users to upload PDF files to one of my Google drive folder. At first sight everything seems to work perfectly but when I go to the folder to check the received PDF files I only get blank PDF !

Did someone already encounter this issue ? If yes, could you help me out please ?

Here are my 2 scripts:

server.gs:

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('form.html');

}

function uploadFiles(form) {

  try {

    var dropbox = "Travaux_T°S";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }

    var blob = form.myFile;    
    var file = folder.createFile(blob);    
    file.setDescription("Uploaded by " + form.myName);

    return "Et hop: une copie de plus à corriger ! :)" ;

  } catch (error) {

    return error.toString();
  }

}

form.html:

<!doctype html>
<style type="text/css">
body {
    background-color: #FFFFFF;
}
</style>
<BR>
<BR>
<BR>
<div align="center">
  <p><img src="https://cdn.pixabay.com/photo/2017/04/25/22/28/despaired-2261021_960_720.jpg" width="50%" height="50%"></p>
  <table width="459" border="0">
    <tbody>
      <tr>
        <td width="462"><div align="center">
          <hr>
        </div>
          <form id="myForm" align="center">
            <input type="text" name="myName" placeholder="NOM_Prenom">
            <input type="file" name="myFile">
            <input type="submit" value="Envoyer le fichier" 
           onclick="this.value='Uploading..';
                    google.script.run.withSuccessHandler(fileUploaded)
                    .uploadFiles(this.parentNode);
                    return false;">
          </form>
          <div id="output"></div>
          <script>
    function fileUploaded(status) {
        document.getElementById('myForm').style.display = 'none';
        document.getElementById('output').innerHTML = status;
    }
          </script>
        <style>
 input { display:block; margin: 20px; }

          </style>
        <hr></td>
      </tr>
    </tbody>
  </table>
  <h3>&nbsp;</h3>
  <p>&nbsp;</p>
</div>

Many thanks in advance ! :)

TheMaster
  • 45,448
  • 6
  • 62
  • 85

1 Answers1

1

Uploading with this.parentNode does not always work well for all file types.

Instead, an elegant and reliable upload procedure is with Filereader.

Sample

Code.gs:

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('form.html');

}

function uploadFiles(blob, name, description) {

  try {

    var dropbox = "Travaux_T°S";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }

    var blob = blob.split(",")
    var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'application/pdf');
    console.log(blob);
    var fileName = blob.setName(name).getName(); 
    var file = folder.createFile(blob); 
    file.setDescription("Uploaded by " + description);    
    return "Et hop: une copie de plus à corriger ! :)" ;

  } catch (error) {

    return error.toString();
  } 
}

form.html:

<!doctype html>
<style type="text/css">
body {
background-color: #FFFFFF;
}
</style>
<BR>
<BR>
<BR>
<div align="center">
<p><img src="https://cdn.pixabay.com/photo/2017/04/25/22/28/despaired-2261021_960_720.jpg" width="50%" height="50%"></p>
<table width="459" border="0">
<tbody>
<tr>
<td width="462"><div align="center">
<hr>
</div>
<form id="myForm" align="center">
<input type="text" name="myName" placeholder="NOM_Prenom">
<input type="file" name="myFile">
<input type="submit" value="Envoyer le fichier" 
onclick="upload()" >
</form>
<div id="output"></div>
<script>   
function upload() {
var file = document.getElementsByName('myFile')[0].files[0];
var description = document.getElementsByName('myName')[0].value;
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
console.log('Sending ' + file.name);
var currFolder = 'Google_Dropbox';
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(content, file.name, description);
return false;
}
reader.readAsDataURL(file);
}   

function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}    
</script>
<style>
input { display:block; margin: 20px; }

          </style>
        <hr></td>
      </tr>
    </tbody>
  </table>
  <h3>&nbsp;</h3>
  <p>&nbsp;</p>
</div>
ziganotschka
  • 25,866
  • 2
  • 16
  • 33
  • Thank you so much @Ziganotschka, "FileReader() did solve my issue ! However I have lost the "uploading message" and the "return message" informing the users that the file have been correctly sent (it gives a blank web page instead). Do you have, by any chance, a quick idea on how to solve this ? –  Mar 24 '20 at 11:51
  • I am not quite sure what is the reason for the blank page is, but a workaround would be: `function fileUploaded(status) {alert(status);}`. – ziganotschka Mar 24 '20 at 20:13
  • It looks that the problem isn't `this.parentNode` but using `` on [tag:V8]. Disabling the new runtime might fix the problem but sometimes the practical solution will be to use `FileReader` instead. – Rubén Sep 08 '20 at 00:11
  • I cannot confirm that "the problem isn't this.parentNode but using `` does not work in v8" - it does in my code above, so if there was a related bug it probably has already been fixed. However, it is likely that there is an issue in v8 with `this.parentNode`. – ziganotschka Sep 08 '20 at 08:01