利用Google Apps Script实现Google Slides形状组复制与占位符递增替换
Google Slides 批量复制形状组并递增占位符序号
问题背景
现有Google Slides文件中存在1个形状组,已通过以下Google Apps Script代码实现按指定数量及位置批量复制该形状组(支持自动分页):
function copyShapes(copyCount) { const presentation = SlidesApp.getActivePresentation(); const slide = presentation.getSlides()[0]; let group = slide.getGroups()[0]; const xIncrement = 10; const yIncrement = 5.5; const initialX = 0.25; const initialY = 1; const maxCopiesPerPage = 10; for (let i = 0; i < copyCount; i++) { if (i % maxCopiesPerPage === 0) { if (i > 0) { group = presentation.appendSlide(SlidesApp.PredefinedLayout.BLANK).insertGroup(group); } } else { const positionIndex = i % maxCopiesPerPage; const row = Math.floor(positionIndex / 2); const col = positionIndex % 2; const x = cmToPoints(initialX + col * xIncrement); const y = cmToPoints(initialY + row * yIncrement); group.duplicate().setLeft(x).setTop(y); } } }
但复制后的形状组内占位符(如{{NAME1}}、{{PRICE1}})不会自动更新序号,需要实现每个副本的占位符序号随复制次数依次递增——例如生成4个副本时,占位符依次为{{NAME1}}、{{NAME2}}、{{NAME3}}、{{NAME4}}及{{PRICE1}}、{{PRICE2}}、{{PRICE3}}、{{PRICE4}}。
解决方案
修改后的代码会在复制形状组后自动遍历组内文本框,替换占位符中的序号:
function copyShapes(copyCount) { const presentation = SlidesApp.getActivePresentation(); const slide = presentation.getSlides()[0]; let originalGroup = slide.getGroups()[0]; const xIncrement = 10; const yIncrement = 5.5; const initialX = 0.25; const initialY = 1; const maxCopiesPerPage = 10; // 确保原始组的占位符为初始序号(可选,防止原始组被修改过) updatePlaceholders(originalGroup, 1); for (let i = 1; i <= copyCount; i++) { let currentGroup; if (i % maxCopiesPerPage === 1) { // 处理分页:非第一页的首个副本,新建空白页后插入原始组副本 if (i > 1) { const newSlide = presentation.appendSlide(SlidesApp.PredefinedLayout.BLANK); currentGroup = newSlide.insertGroup(originalGroup); } else { // 第一页首个是原始组,跳过复制 continue; } } else { // 计算当前副本的位置并复制 const positionIndex = (i - 1) % maxCopiesPerPage; const row = Math.floor(positionIndex / 2); const col = positionIndex % 2; const x = cmToPoints(initialX + col * xIncrement); const y = cmToPoints(initialY + row * yIncrement); currentGroup = originalGroup.duplicate().setLeft(x).setTop(y); } // 更新当前副本的占位符序号 updatePlaceholders(currentGroup, i); } } // 辅助函数:替换组内所有文本框的占位符序号 function updatePlaceholders(group, index) { const shapes = group.getShapes(); shapes.forEach(shape => { const textRange = shape.getText(); if (textRange) { let content = textRange.asString(); // 匹配并替换{{NAME*}}和{{PRICE*}}格式的占位符 content = content.replace(/{{NAME(\d+)}}/g, `{{NAME${index}}}`); content = content.replace(/{{PRICE(\d+)}}/g, `{{PRICE${index}}}`); textRange.setText(content); } }); } // 厘米转Slides点单位的辅助函数(原代码缺失) function cmToPoints(cm) { return cm * 28.3465; }
关键改动说明
- 新增
updatePlaceholders函数:遍历组内所有形状,用正则匹配占位符格式,将序号替换为当前副本的索引值 - 调整循环计数逻辑:从1开始计数,确保每个副本的序号与生成顺序一致
- 补充
cmToPoints函数:原代码调用但未定义,避免运行报错 - 适配分页场景:新建页面插入的组也会自动执行占位符更新
内容的提问来源于stack exchange,提问作者Esat Kurtul
相关产品推荐
相关产品推荐

