Search code examples
htmlgoogle-apps-scriptgoogle-sheets

Upload image from device to google folder and create image URL in google sheet active cell


I have a google sheet, I found a script to upload image from the device to google folder, and then create an image URL in the active cell. Below is the script:

Code.gs

function addImage() {
  var filename = 'Row';
  var htmlTemp = HtmlService.createTemplateFromFile('Index');
  htmlTemp.fName = filename;
  htmlTemp.position = 2;
  var html = htmlTemp.evaluate().setHeight(96).setWidth(415);
  var ui = SpreadsheetApp.getUi();
  ui.showModalDialog(html, 'Upload');
}

function upload(obj, rowNum) {
  var newFileName = obj[2];
  var blob = Utilities.newBlob(...obj);
  var upFile = DriveApp.getFolderById('[folder_id]').createFile(blob).setName(newFileName);
  var fileUrl = upFile.getUrl();
  var urlCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1').getRange(rowNum, 5);
  urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
  return "Done.";
}

Index.html

<!DOCTYPE html>
<html>
<head>
  <base target="_center">
  <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
</head>
<body>
  <form id="myForm">
    Please upload an image below.<br /><br />
    <input type="hidden" name="fname" id="fname" value="<?= fName ?>"/>
    <input type="hidden" name="position" id="position" value="<?= position ?>"/>
    <input type="file" name="file" id="file" accept="image/jpeg,.pdf" />
    <input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
    <input type="button" value="Close" onclick="google.script.host.close()" />
  </form>
  <script>
    // Disable the default submit action using “func1”
    window.onload = func1;
    function func1() {
      document.getElementById('myForm').addEventListener('submit', function(event) {
        event.preventDefault();
      });
    }

    function formData(obj) {
      const file = obj.file.files[0];
      const fr = new FileReader();
      fr.readAsArrayBuffer(file);
      fr.onload = f =>
        google.script.run.withSuccessHandler(closeIt).upload([[...new Int8Array(f.target.result)], file.type, obj.fname.value], obj.position.value);
    }

    function closeIt(e) {
      console.log(e);
      google.script.host.close();
    }
  </script>
</body>
</html>

When I ran the addImage() function, a dialog box popped up in which I uploaded an image from the device, but when I clicked on the submit button, it did not do anything and stuck there. How should I fix the script so that the "Submit" button will function as what I want? Any help or advise will be greatly appreciated!

This is my google sheet link: https://docs.google.com/spreadsheets/d/1D-umFA8pnWJlXipuBOIPkE7fXB3TID3zbHUWSZANeIs/edit#gid=0


Solution

  • When I saw your showing script in your question and your current script in your provided Spreadsheet, I noticed that the file ID is used as [folder_id] of var upFile = DriveApp.getFolderById('[folder_id]').createFile(blob).setName(newFileName);. I guessed that the reason for your current issue might be due to this. In this case, [folder_id] cannot be used. Please modify [folder_id] to folder_id. So, please modify your script in your Spreadsheet as follows.

    From:

    var upFile = DriveApp.getFolderById('[1mAE###]').createFile(blob).setName(newFileName);
    

    To:

    var upFile = DriveApp.getFolderById('1mAE###').createFile(blob).setName(newFileName);
    
    • When I tested your script by modifying this, I confirmed that the script works and the file could be uploaded, and the file link is put into column "E".

    Note:

    • As additional information, when you confirm the error message from the Google Apps Script side, you can use withFailureHandler as follows. Ref

      google.script.run
        .withFailureHandler(err => console.log(err.message))
        .withSuccessHandler(closeIt)
        .upload([[...new Int8Array(f.target.result)], file.type, obj.fname.value], obj.position.value);
      

    Reference: