Я вставляю список дескрипторов Instagram из Google Sheets в Google Slides с помощью скрипта Google Apps.
handle
.Моя цель — вставить «@Apple» в заполнитель {{handle}} и добавить к нему гиперссылку (https://www.instagram.com/apple/). То есть я хочу добавить гиперссылку к тексту, который я только что вставил/заменил.
Я могу добиться этого с помощью приведенного ниже кода, но это крайне неэффективно. В моем реальном приложении нужно вставить много записей и еще много фигур на слайдах, поэтому мне бы хотелось иметь возможность делать это эффективно. Я готов попробовать и другие методы. Любое руководство приветствуется.
Мой код:
var handle = "@Apple";
// extract username to get url
let regExp = new RegExp("[^@]*$");
var username = regExp.exec(handle)[0];
var url = "https://www.instagram.com/" + username;
// insert the handle at {{handle}} and make it a hyperlink
var allShapes = (currentSlide.getShapes());
allShapes.forEach(function(shape) {
var text = shape.getText();
var n = text.replaceAllText("{{handle}}", handle);
if (n > 0) {
var textRange = text.getTextStyle();
text.find(handle).forEach((v) => {
v.getTextStyle().setLinkUrl(url);
});
}
});
@Saddles Спасибо за ваш комментарий! Я прочитал страницу, на которую вы ссылаетесь, и отредактировал свой вопрос. Теперь стало яснее? P.S. Меня немного смущает то, что вы подразумеваете под «пустышным листом». Должен ли я создать новый лист Google или мне следует создать таблицу здесь, в моем вопросе?
Я считаю, что ваша цель состоит в следующем.
В вашей ситуации как насчет использования Slides API? При использовании Slides API ваш скрипт можно изменить следующим образом. Я предположил, что при использовании Slides API стоимость процесса можно снизить.
В этой модификации, начиная с The Google Sheets contains a list of instagram handles, such as @Apple, @Google, etc.
, предполагается использование нескольких текстов замены. Модифицированный сценарий выглядит следующим образом.
Скопируйте и вставьте следующий скрипт в редактор скриптов Google Slide. И включите Slides API в расширенных сервисах Google.
Сначала установите handles
для вашей реальной ситуации. В этой модификации вы можете использовать несколько замен текста. В этом образце
фигуры с текстом {{handle}}
заменяются на @Apple
.
фигуры с текстом {{handle2}}
заменяются на @Google
. И гиперссылки установлены.
function myFunction() {
// Prepare values.
var handles = [ // Please prepare this object for your actual situation.
{ replaceFrom: "{{handle}}", replaceTo: "@Apple" },
{ replaceFrom: "{{handle2}}", replaceTo: "@Google" },
];
handles.forEach(e => {
let regExp = new RegExp("[^@]*$");
var username = regExp.exec(e.replaceTo)[0];
var url = "https://www.instagram.com/" + username;
e.url = url;
});
// Replace texts and set hyperlinks.
var s = SlidesApp.getActivePresentation();
var sId = s.getId();
var currentSlide = s.getSelection().getCurrentPage();
var pageId = currentSlide.getObjectId();
var obj = Slides.Presentations.Pages.get(sId, pageId);
var requests = handles.map(({ replaceFrom, replaceTo, url }) => {
var temp = [{ replaceAllText: { containsText: { text: replaceFrom }, replaceText: replaceTo, pageObjectIds: [pageId] } }];
obj.pageElements.forEach(e => e.shape.text.textElements.forEach(f => {
var t = f?.textRun?.content;
if (t && t.trim() == replaceFrom) {
temp.push({ updateTextStyle: { style: { link: { url } }, objectId: e.objectId, fields: "link" } });
}
}));
return temp;
});
if (requests.length == 0) return;
Slides.Presentations.batchUpdate({ requests }, sId);
}
handles
одним вызовом API.Из вашего следующего ответа,
но моя ситуация такова: для списка маркеров на моем листе Google (в одном столбце) для каждой строки я 1. создаю новый слайд из шаблона с написанным внутри {{handle}}, 2. замените {{handle}} дескриптор (например, @Apple), 3. вставьте URL. Поэтому вместо обновления нескольких мест на одном слайде я фактически создаю слайд каждый раз, когда читаю новую строку. Можно ли в этой ситуации использовать пакетное обновление?
К сожалению, из вашего ответа я не смог понять номер столбца с in a single column
. Итак, в этом примере сценария предполагается, что это столбец «А» со строкой заголовка. И ещё, к сожалению, я не смогла понять create a new slide from a template
. Итак, в этом примере сценария предполагается, что слайд первой страницы Google Slide является слайдом шаблона. И первый слайд шаблона копируется. Когда это отражено в образце сценария, это выглядит следующим образом.
Скопируйте этот пример сценария и вставьте его в редактор сценариев электронной таблицы Google. И, пожалуйста, установите templateSlideId
и sheetName
. Предполагается, что Google Slide of templateSlideId
имеет шаблон слайда на 1-й странице. Пожалуйста, будьте осторожны с этим.
Этот скрипт использует Slides API. Пожалуйста, будьте осторожны с этим.
function myFunction() {
// Please set your template Google Slide ID.
// In this script, the 1st slide is used by copying.
var templateSlideId = "###";
var sheetName = "Sheet1"; // Please set your sheet name.
// Prepare values.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues().filter(([a]) => a);
var handles = values.map(([a]) => ({ replaceFrom: "{{handle}}", replaceTo: a }))
handles.forEach(e => {
let regExp = new RegExp("[^@]*$");
var username = regExp.exec(e.replaceTo)[0];
var url = "https://www.instagram.com/" + username;
e.url = url;
});
// Duplicate a template slide and replace texts and set hyperlinks.
var topPageId = SlidesApp.openById(templateSlideId).getSlides()[0].getObjectId();
var requests1 = [...Array(handles.length)].map((_, i) => ({ duplicateObject: { objectId: topPageId } }));
Slides.Presentations.batchUpdate({ requests: requests1 }, templateSlideId);
var [, ...obj] = Slides.Presentations.get(templateSlideId).slides;
var requests = handles.map(({ replaceFrom, replaceTo, url }, i) => {
var temp = [{ replaceAllText: { containsText: { text: replaceFrom }, replaceText: replaceTo, pageObjectIds: [obj[i].objectId] } }];
obj[i].pageElements.forEach(e => e.shape.text.textElements.forEach(f => {
var t = f?.textRun?.content;
if (t && t.trim() == replaceFrom) {
temp.push({ updateTextStyle: { style: { link: { url } }, objectId: e.objectId, fields: "link" } });
}
}));
return temp;
});
if (requests.length == 0) return;
Slides.Presentations.batchUpdate({ requests }, templateSlideId);
}
При запуске этого сценария копируется первая страница (слайд-шаблон) слайда Google. При этом текст {{handle}}
заменяется с использованием каждой строки ячеек «A2:A» и установки гиперссылок.
Спасибо за подробный ответ. Прошу прощения за то, что не уточнил это в своем первоначальном вопросе, но моя ситуация такова: для списка дескрипторов на моем листе Google (в одном столбце) для каждой строки я 1. создам новый слайд из шаблон, внутри которого написано {{handle}}, 2. замените {{handle}} дескриптор (например, @Apple), 3. вставьте URL-адрес. Поэтому вместо обновления нескольких мест на одном слайде я фактически создаю слайд каждый раз, когда читаю новую строку. Можно ли в этой ситуации использовать пакетное обновление?
@steak Спасибо за ответ. Во-первых, я прошу прощения за то, что не смог понять ваш фактический ожидаемый результат от вашего опубликованного вопроса из-за моего плохого знания английского языка. Судя по вашему ответу, угадав ваш реальный ожидаемый результат, я добавил еще один пример сценария. Пожалуйста, подтвердите это. Если я снова неправильно понял ваш фактический ожидаемый результат, я еще раз извиняюсь.
Вы также можете использовать этот код для достижения того, чего хотите:
const myFunction = () => {
const handles = ["@Apple", "@Google", "@Microsoft"];
const slides = SlidesApp.getActivePresentation().getSlides();
slides.forEach((slide, i) => {
const handle = handles[i];
const shapes = slide.getShapes();
shapes.forEach((shape) => {
const text = shape.getText();
const n = text.replaceAllText("{{handle}}", handle);
if (n > 0) {
const regExp = new RegExp("[^@]*$");
const username = regExp.exec(handle)[0];
const url = "https://www.instagram.com/" + username;
text.find(handle).forEach((v) => {
v.getTextStyle().setLinkUrl(url);
});
}
});
});
}
Вы уже получаете то, что хотите, это было сделано для того, чтобы просмотреть все слайды и заменить все {{handle}}
тем, что вы поместите в массив handles
.
Поскольку вы будете использовать электронную таблицу, вы можете изменить это:
const handles = ["@Apple", "@Google", "@Microsoft"];
К:
const ss = SpreadsheetApp.openById("abc1234567").getSheetByName("Sheet1");
const handles = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();
Примечание. Как и в случае с обновленным ответом @Танаике, я также предполагаю, что ваши дескрипторы в Instagram включены
A2:A
.
Полный код будет выглядеть так:
const myFunction = () => {
const ss = SpreadsheetApp.openById("abc1234567").getSheetByName("Sheet1");
const handles = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();
const slides = SlidesApp.getActivePresentation().getSlides();
slides.forEach((slide, i) => {
const handle = handles[i];
const shapes = slide.getShapes();
shapes.forEach((shape) => {
const text = shape.getText();
const n = text.replaceAllText("{{handle}}", handle);
if (n > 0) {
const regExp = new RegExp("[^@]*$");
const username = regExp.exec(handle)[0];
const url = "https://www.instagram.com/" + username;
text.find(handle).forEach((v) => {
v.getTextStyle().setLinkUrl(url);
});
}
});
});
}
Не стесняйтесь уточнить, если я неправильно понял вашу цель. Буду рад помочь чем смогу!
Можете ли вы поделиться минимальным, воспроизводимым примером, который сообщество сможет использовать, чтобы увидеть, что вы хотите сделать? Как макет листа, чтобы мы могли визуализировать и воспроизвести то, что у вас есть. Вы также можете включить в него желаемый результат.