0

I'm currently working on a code in Google Apps Script that allows a user to fill out a spreadsheet and have the spreadsheet generate printouts for a job board. I'm trying to design this in a way where the user can simply insert a logo image into a row of my Google sheet and have it replace a placeholder in my doc template. I have found lots of answers about how you can take an image and convert it to a blob and insert it from a url or an ID, however, I can't seem to find a way to get the ID or url from the image in the cell. Here's my code currently:

//Creates menu option on spreadsheet
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  const menu = ui.createMenu('AutoFill Docs');
  menu.addItem('Create New Docs', 'createNewGoogleDocs');
  menu.addToUi();

}

//Defines where to get template and info from
function createNewGoogleDocs() {
 
  const googleDocTemplate = DriveApp.getFileById('14MJNd37pn6D-EmNKCQzXXvxJCcOAoB3KS-TlDgZuWMI');
  const destinationFolder = DriveApp.getFolderById('120Sb_CJJlmz5NzJW8W3DB4TNuC4kdD3e');
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('JobBoard');
  const rows = sheet.getDataRange().getValues();
  
  rows.forEach(function(row, index) {
    if (index === 0) return;
    if (row[9]) return;
    const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Printout`, destinationFolder);
    const doc = DocumentApp.openById(copy.getId())
    const body = doc.getBody();
    const friendlyDate = new Date(row[2]).toLocaleDateString();

//Replacing text
    body.replaceText('{{Company}}', row[1]);
    body.replaceText('{{jobTitle}}', row[0]);
    body.replaceText('{{datePosted}}', friendlyDate);
    body.replaceText('{{Description}}', row[3]);
    body.replaceText('{{Qualifications}}', row[5]);
    body.replaceText('{{Wage}}', row[4]);
    body.replaceText('{{Apply}}', row[6]);

//A subfunction to handle replacing the image
  function textToImage() {
  var replaceTextToImage = function(body, searchText, image, width) {
    var next = body.findText(searchText);
    if (!next) return;
    var r = next.getElement();
    r.asText().setText("");
    var img = r.getParent().asParagraph().insertInlineImage(0, image);
    if (width && typeof width == 100) {
      var w = img.getWidth();
      var h = img.getHeight();
      img.setWidth(width);
      img.setHeight(width * h / w);
    }
    return next;
  };

  var documentId = doc;
  var replaceText = "{{Upload Image}}";
  var imageFileId = "### File ID of image ###"; //I don't know how to get this variable
  var body = DocumentApp.openById(documentId).getBody();
  var image = DriveApp.getFileById(imageFileId).getBlob();
  do {
    var next = replaceTextToImage(body, replaceText, image, 200);
  } while (next);
}

//Close and saves new doc
    doc.saveAndClose();
    const url = doc.getUrl();
    sheet.getRange(index + 1, 10).setValue(url)
    
  })

}

I think what might be messing me up is that I have to loop through all my cells right now so that I can create multiple documents at once (meaning each row will have a different doc and different image ID). I'm just not sure how to work around that.

Here's the template and spreadsheet

https://docs.google.com/spreadsheets/d/1cySHogAxcUgzr0hsJoTyPZakKQkM6uIOtmyPzcMoJUM/edit?usp=sharing

https://docs.google.com/document/d/14MJNd37pn6D-EmNKCQzXXvxJCcOAoB3KS-TlDgZuWMI/edit?usp=sharing

Scott Craner
  • 148,073
  • 10
  • 49
  • 81
  • duplicate of https://stackoverflow.com/questions/56733340 - They didn't implement a way to access the content of those images. See the methods available in https://developers.google.com/apps-script/reference/spreadsheet/over-grid-image – Ricardo Aranguren Apr 12 '22 at 16:17

1 Answers1

0

There is a bit of an issue trying to get an image in a specific cell. There's even a Feature Request for that. This year Google released a few classes for image management but there seems to be issues when retrieving those using cellImage class.

I found a related answer (workaround) from user @Tanaike where images are retrieved from Google Sheets, converted to a Blob and inserted into a Google Doc.

Sample code provided was:

const spreadsheetId = "###"; // Google Spreadsheet ID
const res = DocsServiceApp.openBySpreadsheetId(spreadsheetId).getSheetByName("Sheet1").getImages();
console.log(res); // You can check the retrieved images at the log.
if (res.length == 0) return;
const blob = res[0].image.blob; // Here, 1st image of Sheet1 is retrieved. Of course, you can choose the image on the sheet.

let doc = DocumentApp.create("newDocName Goes_Here");
var body = doc.getBody();
var imgPDF = body.appendImage(blob);

Take into consideration that to make the above work you need to:

  1. Install Google Apps Script library. (instructions here)
  2. Enable Drive API.

I tested this and indeed, got the images from the given sheet and inserted them into the Google Doc specified. For some reason, running your code did not show me a newly created file from the template but you can tweak the above accordingly to your case.

Yancy Godoy
  • 582
  • 2
  • 13