Search code examples
formsfile-uploadgoogle-apps-scriptfile-rename

How do I rename files uploaded to an apps script web app form?


I've made a little web app form by splicing together some code I found. It works nearly perfectly for me, allowing me to upload files to a Google Drive folder, logging the data submitted in the form in a spreadsheet and emailing me when a file is uploaded.

However, what I really want to be able to do is to rename the files that are uploaded according to the form data. For example, if the inputted manufacturer value = "Sony" and the date value = 12-04-2016, then make the filename "Sony_12-04-2016.pdf"

From looking it up as best I can it seems I need to pass the submitted values into the createFile() function but I'm quite new to coding and not really sure what I'm doing here..

Here's what I have so far:

.gs

var TO_ADDRESS = "my email address";

function doGet(e) {
    return HtmlService.createTemplateFromFile('index')
    .evaluate()
    .setTitle('Price List Upload Form')
}

function processForm(theForm) {
  var fileBlob = theForm.fileUpload;

  Logger.log("fileBlob Name: " + fileBlob.getName())
  Logger.log("fileBlob type: " + fileBlob.getContentType())
  Logger.log('fileBlob: ' + fileBlob);

  var fldrSssn = DriveApp.getFolderById('my Google Drive folder id');
    fldrSssn.createFile(fileBlob);

  return true;
}

function formatMailBody(obj) {
  var result = "";
  for (var key in obj) {
    result += "<h4 style='text-transform: capitalize; margin-bottom: 0'>" + key + "</h4><div>" + obj[key] + "</div>";
  }
  return result;
}

function doPost(e) {

  try {
    Logger.log(e);
    record_data(e);

    var mailData = e.parameters;

    MailApp.sendEmail({
      to: TO_ADDRESS,
      subject: "New Price List Uploaded",
      htmlBody: formatMailBody(mailData)
   });

    return ContentService
          .createTextOutput(
            JSON.stringify({"result":"success",
                            "data": JSON.stringify(e.parameters) }))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(error) {
    Logger.log(error);
    return ContentService
          .createTextOutput(JSON.stringify({"result":"error", "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}

function record_data(e) {
  Logger.log(JSON.stringify(e));
  try {
    var doc     = SpreadsheetApp.getActiveSpreadsheet();
    var sheet   = doc.getSheetByName('responses');
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1;
    var row     = [ new Date() ];
    for (var i = 1; i < headers.length; i++) {
      if(headers[i].length > 0) {
        row.push(e.parameter[headers[i]]);
      }
    }
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}

.html

<form id="gform" autocomplete="on" method="POST" class="pure-form pure-form-stacked"
action="script url" onsubmit="picUploadJs(this)">

<fieldset class="pure-group">
  <input name="fileUpload" type="file" />
</fieldset>

<fieldset class="pure-group">
  <label for="manufacturer">Manufacturer: </label>
  <input id="manufacturer" name="manufacturer" type="text" placeholder="Manufacturer Name" required/>
</fieldset>

<fieldset class="pure-group">
  <label for="issueDate">Date Issued: </label>
  <input id="issueDate" name="issueDate" type="date" required />
</fieldset>

<fieldset class="pure-group">
  <label for="info">Additional Info: </label>
  <input id="info" name="info" type="text" placeholder="Any Additional Information"/>
</fieldset>

<fieldset class="pure-group">
  <input id="email" name="email" type="hidden" value="[email protected]"/>
</fieldset>

<button class="button-success pure-button button-xlarge">
  Upload</button>

  <div style="display:none;" id="thankyou_message">
  <div id="status" style="display: none">
  <h2>Uploading. Please wait...</h2>
    </div>
  </div>

function picUploadJs(frmData) {

document.getElementById('status').style.display = 'inline';

  google.script.run
.withSuccessHandler(updateOutput)
.processForm(frmData)
};

function updateOutput() {

var outputDiv = document.getElementById('status');
outputDiv.innerHTML = "<h2>File successfully uploaded!</h2><button class=\"pure-button\"><a href=\"page url" style=\"text-decoration: none;\">Upload another</a></button>";
  }

The original code comes from here

and here


Solution

  • I probably don't have all the lingo correct, but you have to turn the form submission fields into variables to be able to use them in your .gs script. Once you turn them into variables, you can "build" a filename to your liking, and use it when writing the fileBlob to a file. Given your code above, you should be able to just modify the processForm function as follows:

    function processForm(theForm) {
      var fileBlob = theForm.fileUpload;
      var manufacturer = theForm.manufacturer;
      var issueDate = theForm.issueDate;
      var myNewFilename = manufacturer + '_' + issueDate + '.pdf';
      fileBlob.setName(myNewFilename);  //set Name of the blob
      var fldrSssn = DriveApp.getFolderById('my Google Drive folder id');
      fldrSssn.createFile(fileBlob);  // create a file with the blob, name of the file will be the same as set by setName method
      return true;
    }
    

    Let me also note something that may be helpful for future visitors--how to write a timestamp into the filename. Set a new variable using the Utilities.formatDate function, and then you can concatenate this variable into a filename like in the example above. Here's how to set the variable:

    var myTS = Utilities.formatDate (new Date(), Session.getScriptTimeZone(), "yyyyMMdd_HHmmss--") ;
    

    Format is completely flexible--just look up the function for details.