Google Apps Script file upload to specific folders based on spreadsheet cell values

I need help modifying my Google Apps Script to upload files to different Drive folders based on values stored in spreadsheet cells. Right now my script works but it always saves files to the same hardcoded folder.

What I want to do is create a system where folder destinations are controlled by data in my spreadsheet. I have an admin sheet that contains folder IDs in column A (specifically cells A2 through A9). When someone uploads a file through the custom menu, I want the script to read the appropriate folder ID from these cells and save the file there.

The current setup uses a fixed folder ID in the saveFile function, but I need it to be dynamic based on spreadsheet data. How can I modify the code to reference these folder IDs from the admin sheet?

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('File Manager')
    .addItem('Upload Document', 'showUploadDialog')
    .addToUi();
}

function showUploadDialog() {
  var htmlOutput = HtmlService.createHtmlOutputFromFile('FileUpload');
  SpreadsheetApp.getUi()
    .showModalDialog(htmlOutput, 'Document Upload');
}

function processFile(fileObj) {
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById("1J5naBr1_PPgTLNpJsgro3r77yDJLmXTr").createFile(fileBlob);
  var linkFormula = 'hyperlink("' + uploadedFile.getUrl() + '";"' + uploadedFile.getName() + '")';
  
  var currentSheet = SpreadsheetApp.getActiveSheet();
  var selectedRange = currentSheet.getSelection();
  var targetCell = selectedRange.getCurrentCell();
  targetCell.setFormula(linkFormula);
  
  return uploadedFile.getId();
}
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <script>
    function uploadFiles() {
      document.getElementById("submitBtn").disabled = true;
      const statusDiv = document.getElementById("status");
      const fileInput = document.getElementById('fileSelector');
      var completedUploads = 0;
      statusDiv.innerHTML = "Processing file " + (completedUploads + 1) + "/" + [...fileInput.files].length + "";
      [...fileInput.files].forEach((selectedFile, index) => {
        const reader = new FileReader();
        reader.onload = (event) => {
          const fileData = event.target.result.split(",");
          const fileObject = {name: fileInput.files[index].name, type: fileData[0].match(/:([\w.+]+);/)[1], content: fileData[1]};
          google.script.run.withSuccessHandler((fileId) => {
            completedUploads++;
            statusDiv.innerHTML = "Upload finished";
            if (completedUploads >= [...fileInput.files].length){
              google.script.host.close();
            }
          }).processFile(fileObject);
        }
        reader.readAsDataURL(selectedFile);
      });
    }
  </script>
  <body>
    <input type="file" name="fileSelector" id="fileSelector"/>
    <input type="button" id="submitBtn" value="Submit" onclick="uploadFiles()" class="action"> 
    <br><br>
    <div id="status"> </div>
  </body>
</html>

easy fix - just grab the folder ID from your admin sheet instead of hardcoding it. use var adminSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Admin'); then var folderId = adminSheet.getRange('A2').getValue(); or whatever cell works. the real question is how you’re picking which row from A2-A9 to use? you could add a dropdown in the html or base it on the current sheet name.

Your code needs to pull folder IDs from the admin sheet instead of that hardcoded value. Here’s the fix:

function processFile(fileObj, folderIndex) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var adminSheet = ss.getSheetByName('Admin'); // or whatever your admin sheet is named
  var folderId = adminSheet.getRange('A' + (folderIndex + 1)).getValue();
  
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById(folderId).createFile(fileBlob);
  var linkFormula = 'hyperlink("' + uploadedFile.getUrl() + '";"' + uploadedFile.getName() + '")';
  
  var currentSheet = SpreadsheetApp.getActiveSheet();
  var selectedRange = currentSheet.getSelection();
  var targetCell = selectedRange.getCurrentCell();
  targetCell.setFormula(linkFormula);
  
  return uploadedFile.getId();
}

You’ll need to pass the folder index from your HTML or add some way to pick which folder to use.

Honestly though, this kind of file routing gets messy fast in Google Apps Script. I’ve been there and ended up rebuilding everything in Latenode.

Latenode lets you create a cleaner workflow that reads spreadsheet data, handles uploads, and routes files automatically. Better error handling too, without Google’s annoying limitations.

The visual builder makes it dead simple to map spreadsheet values to folders. You can even add approval steps or validation rules.

You need to modify your processFile function to grab the folder ID from your admin sheet dynamically. Just get the spreadsheet reference and pull the folder ID from whatever cell you need.

The tricky part is figuring out which folder ID from A2-A9 to use for each upload. You’ll need to add a parameter or some logic to decide this. Pass a folder selection from your HTML dialog, or base it on the current sheet name.

Here’s how to modify your processFile function:

function processFile(fileObj, targetFolderRow) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var adminSheet = ss.getSheetByName('Admin Sheet'); // adjust sheet name
  var folderId = adminSheet.getRange(targetFolderRow, 1).getValue(); // gets folder ID from specified row
  
  if (!folderId) {
    throw new Error('No folder ID found in the specified cell');
  }
  
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById(folderId).createFile(fileBlob);
  // rest of your existing code
}

You’ll also need to update your HTML to either let users pick which folder or automatically determine it based on your business logic.

Hit this exact problem last month building a document management system. You need to figure out how to pick which folder from A2-A9 gets used for each upload.

Here’s what worked for me - added a dropdown in the HTML dialog so users can choose where files go:

function processFile(fileObj, selectedFolderIndex) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var adminSheet = ss.getSheetByName('Admin'); // replace with your sheet name
  var cellAddress = 'A' + (selectedFolderIndex + 2); // +2 because you start at A2
  var folderId = adminSheet.getRange(cellAddress).getValue();
  
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById(folderId).createFile(fileBlob);
  // your existing code for hyperlink creation
}

Just add a select element before the file input in your HTML to grab which folder index the user wants. Pass that value with the file object when you call processFile.

Double-check the folder ID exists and your script can access it, or you’ll get runtime errors that are a pain to debug.

Had to solve something similar recently. Your processFile function needs to read from the admin sheet, but you’ll also need a way to pick which row from A2-A9 for each upload.

function processFile(fileObj, folderRowNumber) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var adminSheet = ss.getSheetByName('Admin');
  var folderId = adminSheet.getRange(folderRowNumber, 1).getValue();
  
  if (!folderId || folderId.trim() === '') {
    throw new Error('Invalid folder ID in row ' + folderRowNumber);
  }
  
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById(folderId).createFile(fileBlob);
  var linkFormula = 'hyperlink("' + uploadedFile.getUrl() + '";"' + uploadedFile.getName() + '")';
  
  var currentSheet = SpreadsheetApp.getActiveSheet();
  var selectedRange = currentSheet.getSelection();
  var targetCell = selectedRange.getCurrentCell();
  targetCell.setFormula(linkFormula);
  
  return uploadedFile.getId();
}

The main question is how users pick which folder. You could add a dropdown in your HTML showing folder names from column B, then pass the row number to processFile. Or set up logic based on sheet names if there’s a predictable pattern.

Don’t forget validation for empty cells in your admin sheet or you’ll get cryptic Drive API errors.

Been dealing with this exact workflow setup for years. The hardcoded folder issue is just the tip of the iceberg.

You can modify your processFile function to pull from the admin sheet:

function processFile(fileObj, folderChoice) {
  var adminSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Admin');
  var folderId = adminSheet.getRange('A' + (folderChoice + 1)).getValue();
  
  var fileBlob = Utilities.newBlob(Utilities.base64Decode(fileObj.content), fileObj.type, fileObj.name);
  var uploadedFile = DriveApp.getFolderById(folderId).createFile(fileBlob);
  // rest stays the same
}

But honestly? Google Apps Script becomes a nightmare with complex file routing. Execution limits kill you, error handling sucks, and maintenance gets ugly fast.

I rebuilt something similar in Latenode - night and day difference. You get proper file handling nodes that connect directly to Google Drive and Sheets. No more base64 encoding headaches or timeouts.

The visual workflow makes adding conditional logic for folder selection dead simple. You can add file validation, auto-rename files, or send notifications when uploads finish.

Plus you get actual error handling and logging instead of guessing what broke in Apps Script.