1

I want that Apps Script to automatically generate a new set of slides using data from a Sheets document which has rows of the different information I want inserted into a Slides template replacing the placeholder tags. I want it to do it instantly for each row inside the table with one action, so if there are 10 rows, 10 sets of Slides documents will be generated.

The text replacement works, however I'm not sure how to replace, for example, a placeholder tag with "{{image}}"

The Image is a generated Qr code in column (N) with an sheet addon (QR Code for Classroom Attendance)and for each row separate. For example 10 rows with different qr codes. This addon writes the generate QR code in the column N. As I said for each I have a different Qr code.

function mailMergeSlidesFromSheets() {
  // Load data from the spreadsheet
  var dataRange = SpreadsheetApp.getActive().getDataRange();
  var sheetContents = dataRange.getValues();

  // Save the header in a variable called header
  var header = sheetContents.shift();

  // Create an array to save the data to be written back to the sheet.
  // We'll use this array to save links to Google Slides.
  var updatedContents = [];

  // Add the header to the array that will be written back
  // to the sheet.
  updatedContents.push(header);

  // For each row, see if the 4th column is empty.
  // If it is empty, it means that a slide deck hasn't been
  // created yet.
  sheetContents.forEach(function(row) {
    if(row[14] === "") {
      // Create a Google Slides presentation using
      // information from the row.
      var slides = createSlidesFromRow(row);
      var slidesId = slides.getId();
   
      // Create the Google Slides' URL using its Id.
      var slidesUrl = `https://docs.google.com/presentation/d/${slidesId}/edit`;

      // Add this URL to the 4th column of the row and add this row
      // to the updatedContents array to be written back to the sheet.
      row[14] = slidesUrl;
      updatedContents.push(row);
    }
  });

  // Write the updated data back to the Google Sheets spreadsheet.
  dataRange.setValues(updatedContents);

}

function createSlidesFromRow(row) {
 // Create a copy of the Slides template
 var deck = createCopyOfSlidesTemplate();

 // Rename the deck using the firstname and lastname of the student
 deck.setName(row[4] + " " + row[9] + row[3]);

 // Replace template variables using the student's information.
    deck.replaceAllText("{{id}}", row[0]);
    deck.replaceAllText("{{tag}}", row[3]);
    deck.replaceAllText("{{besetzung}}", row[4]);
    deck.replaceAllText("{{beginn}}", row[5]);
    deck.replaceAllText("{{ende}}", row[6]);
    deck.replaceAllText("{{halle}}", row[7]);
    deck.replaceAllText("{{stand}}", row[8]);
    deck.replaceAllText("{{firma}}", row[2]);
    deck.replaceAllText("{{veranstaltung}}", row[9]);
    deck.insertImage("{{image}}", row[13]);

 return deck;
}

function createCopyOfSlidesTemplate() {
 //
 var TEMPLATE_ID = "19PKvWoDtbeVHcqm4DnWUxRx1OBO817uG3cL5Ox-dQoo";

 // Create a copy of the file using DriveApp
 var copy = DriveApp.getFileById(TEMPLATE_ID).makeCopy();

 // Load the copy using the SlidesApp.
 var slides = SlidesApp.openById(copy.getId());

 return slides;
}

function onOpen() {
 // Create a custom menu to make it easy to run the Mail Merge
 // script from the sheet.
 SpreadsheetApp.getUi().createMenu("⚙️ Create BWN by Pavlos")
   .addItem("Create Slides","mailMergeSlidesFromSheets")
   .addToUi();
}
 replaces the placeholder tags with the desired text    
      // I am not sure how to insert something similar for images and charts in the code here
      // I've tried variations of the below, none of which have worked
    

        // picture.find("{{image}}").replace(image); 
          //  picture.findText("{{image}}").replace(image);
              //  picture.getText("{{image}}").replaceWithImage(image);        
                 // picture.getText().findText("{{image}}").replace(image);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Pavlos
  • 37
  • 4
  • I think that in your situation, it is required to know your Spreadsheet. Because, from your question, I cannot understand the situation of the images in or on the cells. I apologize for my poor English skill. So, can you provide the sample Spreadsheet? – Tanaike Jan 28 '23 at 00:41
  • Thx for your reply. I putt a link to the sheet so you can see what i mean Thx for your Time https://docs.google.com/spreadsheets/d/14cyHIzdBHSFa4hgj0S0bCIFk7CC-zSw4g3ngI7UNgcQ/edit?usp=sharing – Pavlos Jan 28 '23 at 05:29
  • Thank you for replying and providing the sample Spreadsheet. From your sample Spreadsheet, your images are put over the cells. In this case, unfortunately, the images cannot be retrieved by `getValues`. I think that when [this method](https://stackoverflow.com/a/64040243) is used, the images over the cells can be retrieved. But, in your Spreadsheet, there are a lot of images. So, for example, although I'm not sure about your actual situation, if your QR code is from an URL, how about directly using the URL? – Tanaike Jan 28 '23 at 05:42
  • The Image are so many because I need them. There are abaut 200 rows created and each of the qr code is for each row. I have tried also to create the qr code from =image("https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl="&M2) where M2 has the link insite from the created Qr code. That link directs to the google form . In both cases i dont now how to put the image separate from each row to the merged google slide. As i said the text place holders working fine but no image is transfering automatikally to the slide created for each row. Thx for your Time – Pavlos Jan 28 '23 at 05:57
  • Thank you for replying. If you have the direct link of the QR code, I think that when the URL is used, the script might be simple. Can you add the sample URL of the QR code to your sample Spreadsheet? – Tanaike Jan 28 '23 at 06:01
  • This is the slide i use as template. https://docs.google.com/presentation/d/15l-nn2JA5esDufCwEmONqcLOKPpxnlnwvktuGHGAiIU/edit#slide=id.g1edb1ebc308_0_19 – Pavlos Jan 28 '23 at 06:02
  • https://docs.google.com/spreadsheets/d/14cyHIzdBHSFa4hgj0S0bCIFk7CC-zSw4g3ngI7UNgcQ/edit#gid=1863559289 and this is the Template with the chart.googleapis. Thx again for your time – Pavlos Jan 28 '23 at 06:05
  • Thank you for adding the formula including URL. But, in your script, it seems that when the column "O" `row[14] === ""` is true, the script is run. In your current Spreadsheet, the formula is used for column "O". So, in your actual situation, the column "O" is not your added formula. Is my understanding correct? – Tanaike Jan 28 '23 at 06:17
  • Thx for your reply row 14 must be row 15 to check that no slide is created my wrong. In rw 14 is the image from the qr code. – Pavlos Jan 28 '23 at 06:23
  • Thank you for replying. Your `row 14` and `row 15` are columns "N" and "O"? – Tanaike Jan 28 '23 at 06:26
  • I proposed a modification point in your showing script by guessing that `row[14] === ""` is true. Please confirm it. If that was not useful, I apologize. – Tanaike Jan 28 '23 at 06:34
  • It must be row[15] === "" is true and yes columns are N and O – Pavlos Jan 28 '23 at 06:42
  • Thank you for replying. About `It must be row[15] === "" is true and yes columns are N and O`, please modify it and please reflect my propsoed modification point and test it. – Tanaike Jan 28 '23 at 06:43

1 Answers1

0

I believe your goal is as follows.

  • You want to replace {{Image}} on 1st page of Google Slides with the image.
  • The image can be retrieved by the URL like "https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl="&M2.

In this case, how about directly using the values of column "M" as follows? When your script is modified, please modify it as follows.

From:

deck.insertImage("{{image}}", row[13]);

To:

deck.getSlides()[0].getShapes().find(s => s.getText().asString().trim().toUpperCase() == "{{IMAGE}}").replaceWithImage(`https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=${row[12]}`);

Note:

  • In this modification, it supposes that row[14] === "" is true and the column "M" has the value of https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=${value}. Please be careful about this.

  • It seems that there are a lot of rows you want to process. So, if the maximum execution time (6 minutes) is over, please separate the rows for processing. In your this question, you want to replace {{Image}} with the image. So, this answer is for it. Please be careful about this.

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thx for your Reply and for your time. I wil try id and give a feedback but ihave another Question if possible. How can separate the rows for processing? Thx in advance again for your Time and support. – Pavlos Jan 28 '23 at 06:46
  • @Pavlos Thank you for replying. I have to apologize for my poor English skill. Unfortunately, I cannot understand whether your question was resolved. Can I ask you about the detail of it? – Tanaike Jan 28 '23 at 06:47
  • @Pavlos And, about your new question of `but ihave another Question if possible. How can separate the rows for processing?`, I would like to support you. But the new question is different from your question. So can you post it as new question? Because when your initial question is changed by comment, other users who see your question are confused. By posting it as new question, users including me can think of it. If you can cooperate to resolve your new issue, I'm glad. Can you cooperate to resolve your new question? – Tanaike Jan 28 '23 at 06:51
  • First of all thanyk ou so much for your support It worked with you code. – Pavlos Jan 28 '23 at 06:56
  • I want to try out if i get an error or time out to generate slides. If so i will generate a new question . Thx again!! – Pavlos Jan 28 '23 at 06:59
  • @Pavlos Thank you for replying. From `First of all thanyk ou so much for your support It worked with you code.`, I understood that your issue was resolved. I'm glad your issue was resolved. If your question was solved, please push an accept button. Other people who have the same issue with you can also base your question as a question that can be solved. And I think that your issue and solution will be useful for them. If you don't find the button, feel free to tell me. https://stackoverflow.com/help/accepted-answer – Tanaike Jan 28 '23 at 07:00
  • @Pavlos About `I want to try out if i get an error or time out to generate slides. If so i will generate a new question. Thx again!!`, I would like to support you. When I saw your new question, I will check it. – Tanaike Jan 28 '23 at 07:01
  • I cant find the Button. – Pavlos Jan 28 '23 at 07:12