Автоматически вставлять гиперссылку в слайды с помощью скрипта Google Apps

В настоящее время я работаю над автоматическим созданием Google Slides из файла Sheets. Я создал шаблон, который благодаря скрипту дублируется и заполняется данными, присутствующими в таблицах.

Вот как выглядит шаблон:

Все работает нормально, кроме одной колонки. Действительно, я хотел бы иметь возможность добавить гиперссылку в последнюю часть, и я заблокирован на эту тему. Я искал информацию в Интернете, но не могу адаптировать ее к своему коду.

Действительно, мой код заменяет все мои фигуры гиперссылками, когда мне нужна только одна на слайд.

Если кто-нибудь может помочь мне с этим, я был бы очень признателен.

Это мой код:

function createSlides() {
    // Déclaration des constantes et des variables
    const classeur = SpreadsheetApp.getActiveSpreadsheet();
    const feuille = classeur.getSheetByName("Importrange");
    const feuilleReport = classeur.getSheetByName("Report des données à diffuser");
    var templateSlide, copy, nomSlide, slideFile, slides, gabaritSlide;
    var tEssais = [], tDonneesReportees = [], nbDonneesReportees = 0;
    var lastRow = 0;

    // Récupération du gabarit
    templateSlide = DriveApp.getFileById("1gYf8X40TePUIJJVR32cSPcLGTxRZ__t9ekeuuv27xgA");

    // Création d'une copie et ajout du nom au Slides
    copy = templateSlide.makeCopy();
    nomSlide = (Utilities.formatDate(new Date(),"GMT+1","dd/MM/yyyy")) + " BILAN ESSAIS";
    copy.setName(nomSlide);

    // Ouverture du Slides, récupération des diapositives qui sont à l'intérieur et attribution de la diapositive de référence
    slideFile = SlidesApp.openById(copy.getId());
    slides = slideFile.getSlides();
    gabaritSlide = slides[1];

    // Récupération de l'ensemble des données de l'onglet "Importrange"
    tEssais = feuille.getRange("A2:H").getValues();

    // Récupération du nombre de lignes reportées
    tDonneesReportees = feuilleReport.getRange("A2:H").getValues().filter(d =>d[0] !== '');
    nbDonneesReportees = tDonneesReportees.length;

    // Suppression des anciens essais
    feuilleReport.deleteRows(1,nbDonneesReportees + 1);

    // Pour chaque ligne du tableau tEssais
    for (let i = 0; i < tEssais.length; i ++){
      // Si l'essai est à diffuser
      if (tEssais[i][7]){
        // La reporter dans l'onglet "Report des données à diffuser"
        feuilleReport.appendRow(tEssais[i]);
      }
    }

    // Récupération de la dernière ligne de l'onglet "Report des données à diffuser"
    lastRow = feuilleReport.getDataRange().getValues().length;

    // Tri des données par site et secteur
    feuilleReport.getRange("B1:B"+ (lastRow)).sort({column: 2, ascending: false});
    feuilleReport.getRange("A1:A"+ (lastRow)).sort({column: 1, ascending: false});

    // Récupération des nouveaux essais à reporter dans le Slides
    tDonneesReportees = feuilleReport.getDataRange().getValues().filter(d =>d[0] !== '');

    // Récupération des nouveaux essais à reporter dans le Slides (après ajout si ligne pair ou impair)
    tDonneesReportees = feuilleReport.getDataRange().getValues().filter(d =>d[0] !== '');

    // Pour chaque essai, création d'un slide et report des données
    for (let i = 0; i < tDonneesReportees.length; i ++){
      let slide = gabaritSlide.duplicate();
      slide.replaceAllText("{{Site}}", tDonneesReportees[i][0]);
      slide.replaceAllText("{{Secteur}}", tDonneesReportees[i][1]);
      slide.replaceAllText("{{Nom}}", tDonneesReportees[i][2]);
      slide.replaceAllText("{{Contexte}}", tDonneesReportees[i][3]);
      slide.replaceAllText("{{Objectifs}}", tDonneesReportees[i][4]);
      slide.replaceAllText("{{Statut}}", tDonneesReportees[i][5]);
      slide.replaceAllText("{{Lien}}", "LienURL");

      var elements = slide.getPageElements();
      for (let j = 0; j < elements.length; j ++){
        var element = elements[j];
        if (element.getPageElementType() == "SHAPE" && element.asShape().getText().find("LienURL")){
          var text = element.asShape().getText();
          text.appendText("Lien");
          text.getTextStyle().setLinkUrl("www.google.com")
        }
      }
    };

    // Suppression de la diapositive qui servait de gabarit
    gabaritSlide.remove();
  }

Для меня проблема исходит из этой части:

if (element.getPageElementType() == "SHAPE" && element.asShape().getText().find("LienURL")){

Он не может найти элемент LienURL. Но я не вижу, как еще это сделать. Вот что я получаю в результате:

Я попробовал другое решение, которое увидел в этом посте. Но у меня была ошибка с моим objectID. Это часть кода, который я пробовал:

  for (let i = 0; i < tDonneesReportees.length; i ++){
     let slide = gabaritSlide.duplicate();
     slide.replaceAllText("{{Site}}", tDonneesReportees[i][0]);
     slide.replaceAllText("{{Secteur}}", tDonneesReportees[i][1]);
     slide.replaceAllText("{{Nom}}", tDonneesReportees[i][2]);
     slide.replaceAllText("{{Contexte}}", tDonneesReportees[i][3]);
     slide.replaceAllText("{{Objectifs}}", tDonneesReportees[i][4]);
     slide.replaceAllText("{{Statut}}", tDonneesReportees[i][5]);
     slide.replaceAllText("{{Lien}}", "Lien");
     var elements = slide.getPageElements();
     var requete = [];
     for (let j = 0; j < elements.length; j ++){
       var element = elements[j];
       if (element.getPageElementType() == "SHAPE"){
         var text = element.asShape().getText().find("Lien");
         if (text.length > 0){
           var idObject = element.getObjectId();
           for (let k = 0; k < text.length; k ++){
             var start = text[k].getStartIndex();
             var end = text[k].getEndIndex();
             requete.push({
               updateTextStyle : {
                 objectId : idObject,
                 textRange : {
                   startIndex : start,
                   endIndex : end,
                   type : "FIXED_RANGE"
                 },
                 fields : 'link',
                 style : {
                   link : {
                     url : "www.google.com"
                   }
                 }
               }
             });
             Slides.Presentations.batchUpdate({'requests':requete},copy.getId());
           }
         }
       }
     }
   };

И я получаю эту ошибку:

Заранее спасибо за помощь и извините за мой английский...

------------ РЕДАКТИРОВАТЬ ------------

Это минимальный воспроизводимый пример для лучшего понимания:

function createSlides() {
   const ss = SpreadsheetApp.getActiveSpreadsheet();
   const sheet = ss.getSheetByName("Values");

   // Get Template
   var templateSlide = DriveApp.getFileById("13frZFGs3agqpLnEdXFEcsRadolzZsxeYwgzy2fqOLiw");

   // Create copy of template
   var copy = templateSlide.makeCopy();
   var nameSlide = (Utilities.formatDate(new Date(),"GMT+1","dd/MM/yyyy")) + " - SLIDE";
   copy.setName(nameSlide);

   // Open Slide, get all slide and choose what is the template
   var slideFile = SlidesApp.openById(copy.getId());
   var slides = slideFile.getSlides();
   var template = slides[1];

   // Get values of Sheet
   var tValues = sheet.getRange("A2:D").getValues().filter(d =>d[0] !== '');

   // For each row, create slide
   for (let i = 0; i < tValues.length; i ++){
     // Duplicate template
     let slide = template.duplicate();
     // Add Values
     slide.replaceAllText("{{Site}}", tValues[i][0]);
     slide.replaceAllText("{{Project}}", tValues[i][1]);
     slide.replaceAllText("{{Link}}", "Link");
     // Get all of elements in page
     var elements = slide.getPageElements();
     var request = [];
     for (let j = 0; j < elements.length; j ++){
       var element = elements[j];
       if (element.getPageElementType() == "SHAPE"){
         var text = element.asShape().getText().find("Link");
         if (text.length > 0){
           var idObject = element.getObjectId();
           for (let k = 0; k < text.length; k ++){
             var start = text[k].getStartIndex();
             var end = text[k].getEndIndex();
             request.push({
               updateTextStyle : {
                 objectId : idObject,
                 textRange : {
                   startIndex : start,
                   endIndex : end,
                   type : "FIXED_RANGE"
                 },
                 fields : 'link',
                 style : {
                   link : {
                     url : tValues[i][1]
                   }
                 }
               }
             });
             Slides.Presentations.batchUpdate({'requests':request},copy.getId());
           }
         }
       }
     }
   };
 }

Это мои Таблицы , а это Слайд моего шаблона.

Вы описываете процесс слияния почты. Вы можете попробовать бесплатное дополнение AutoCrat вместо написания собственного кода. AutoCrat позволяет использовать файл Google Slides в качестве шаблона. Используйте опцию Один документ.

doubleunary 08.11.2022 09:55

Спасибо за ваш ответ, но моя компания не принимает дополнения по безопасности...

devMethodes 08.11.2022 10:07

Здравствуйте, можете ли вы предоставить минимальный воспроизводимый пример, включая копию шаблона, над которым вы работаете?

Iamblichus 08.11.2022 10:25

Конечно lamblichus, я отредактировал свой пост. Внизу вы можете найти минимальный воспроизводимый пример и ссылки на мои листы и слайд шаблона.

devMethodes 08.11.2022 10:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я считаю, что ваша цель заключается в следующем.

  • Вы хотите установить гиперссылки, полученные из столбца «C» электронной таблицы, на {{Link}}.

Точки модификации:

  • В вашем шаблоне и сценарии после преобразования Link : {{Link}} вы пытаетесь установить гиперссылку. В этом случае, как насчет замены и установки текста и гиперссылки с помощью {{Link}} в качестве текста поиска? Я думал, что таким образом ваш сценарий может быть немного проще.
  • В вашей электронной таблице кажется, что гиперссылки помещены в столбец «C». Но вы используете tValues[i][1]. В данном случае я подумал, что это tValues[i][2].

Когда эти моменты отразятся в вашем сценарии, как насчет следующей модификации?

В этой модификации изменен ваш нижний скрипт.

Из:

for (let i = 0; i < tValues.length; i ++){
     // Duplicate template
     let slide = template.duplicate();
     // Add Values
     slide.replaceAllText("{{Site}}", tValues[i][0]);
     slide.replaceAllText("{{Project}}", tValues[i][1]);
     slide.replaceAllText("{{Link}}", "Link");
     // Get all of elements in page
     var elements = slide.getPageElements();
     var request = [];
     for (let j = 0; j < elements.length; j ++){
       var element = elements[j];
       if (element.getPageElementType() == "SHAPE"){
         var text = element.asShape().getText().find("Link");
         if (text.length > 0){
           var idObject = element.getObjectId();
           for (let k = 0; k < text.length; k ++){
             var start = text[k].getStartIndex();
             var end = text[k].getEndIndex();
             request.push({
               updateTextStyle : {
                 objectId : idObject,
                 textRange : {
                   startIndex : start,
                   endIndex : end,
                   type : "FIXED_RANGE"
                 },
                 fields : 'link',
                 style : {
                   link : {
                     url : tValues[i][1]
                   }
                 }
               }
             });
             Slides.Presentations.batchUpdate({'requests':request},copy.getId());
           }
         }
       }
     }
   };

К:

for (let i = 0; i < tValues.length; i++) {
  let slide = template.duplicate();
  slide.replaceAllText("{{Site}}", tValues[i][0]);
  slide.replaceAllText("{{Project}}", tValues[i][1]);
  slide.getShapes().some(s => {
    var t = s.getText().find("\\{\\{Link\\}\\}");
    if (t.length == 1) {
      t[0].setText("Link").getTextStyle().setLinkUrl(tValues[i][2]);
      return true;
    }
    return false;
  });
}

Примечание:

  • Когда я протестировал этот модифицированный сценарий, используя предоставленный вами образец электронной таблицы и слайдов, я убедился, что сценарий работает. Когда вы изменяете свою электронную таблицу и слайды, сценарий может быть недоступен для использования. Пожалуйста, будьте осторожны с этим.

Ссылка:

Извините за мой поздний ответ. Это работает отлично. Спасибо большое Танайке!!!!

devMethodes 14.11.2022 11:27

@devMethodes Спасибо за ответ и тестирование. Я рад, что ваша проблема была решена. И тебе спасибо.

Tanaike 14.11.2022 12:24

Другие вопросы по теме