Apps Script求助:幻灯片图片合并报错(已更新代码)
我是Apps Script及编程领域的新手,尝试将Google幻灯片与表格数据合并生成多份演示文稿。现已解决数据调用与文本替换问题,但使用replaceAllShapesWithImage方法时出现如下错误:
GoogleJsonResponseException: API call to slides.presentations.batchUpdate failed with error: Invalid requests[2].replaceAllShapesWithImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats.
图片存储在Google云端硬盘,已设置为「任何人有链接即可访问」,当前代码如下:
const spreadsheetId = '1JSXC0XrfUAtcRLXCgVnB-SAQjwk_-YG7W_kGefowONE'; const thetemplateId = '1Pug2cPiGsPL9iKPEnBAhvBVqfSTMyJERCRaSGkyFOr0'; const dataRange = 'Monthly Top Producers!A2:F'; function generateTopPro(){ var Presentation=SlidesApp.openById(thetemplateId); let values = SpreadsheetApp.openById(spreadsheetId).getRange(dataRange).getValues(); for (let i = 0; i < values.length; ++i) { const row = values[i]; const agent_name = row[0]; // name in column 1 const agent_phone = row[3]; // phone in column 4 const agent_photo = row[4]; // agent photo url column 5 const logo_state = row[5]; // state logo url column 6 // Duplicate the template presentation using the Drive API. const copyTitle = agent_name + ' September'; let copyFile = { "title": copyTitle, "parents": [{"id": 'root'}] }; copyFile = Drive.Files.copy(copyFile, templateId); const presentationCopyId = copyFile.id; // Create the text merge (replaceAllText) requests for this presentation. const requests = [{ "replaceAllText": { "containsText": { "text": '{{agent_name}}', "matchCase": true }, "replaceText": agent_name } }, { "replaceAllText": { "containsText": { "text": '{{agent_phone}}', "matchCase": true }, "replaceText": agent_phone } }, { "replaceAllShapesWithImage": { "imageUrl": agent_photo, "imageReplaceMethod": 'CENTER_INSIDE', "containsText": { "text": '{{agent_photo}}', "matchCase": true } } }, { "replaceAllShapesWithImage": { "imageUrl": logo_state, "imageReplaceMethod": 'CENTER_INSIDE', "containsText": { "text": '{{logo_state}}', "matchCase": true } } }]; // Execute the requests for this presentation. const result = Slides.Presentations.batchUpdate({ "requests": requests }, presentationCopyId); // Count the total number of replacements made. let numReplacements = 0; result.replies.forEach(function(reply) { numReplacements += reply.replaceAllText.occurrencesChanged; }); console.log('Created presentation for %s with ID: %s', agent_name, presentationCopyId); console.log('Replaced %s text instances', numReplacements); } }
修正Drive图片URL格式:Slides API无法直接识别Drive的普通分享链接,需要将表格中的图片链接转换为可直接访问的格式。提取原链接中
d/和/view之间的文件ID,替换为https://drive.google.com/uc?id=文件ID的格式。
示例:原链接https://drive.google.com/file/d/abc123/view转换后为https://drive.google.com/uc?id=abc123。修复变量名拼写错误:代码中定义的模板ID变量是
thetemplateId,但复制文件时误用了templateId,导致复制操作失败。需修改复制代码为:copyFile = Drive.Files.copy(copyFile, thetemplateId);验证图片权限与格式:确认图片已设置「任何人有链接即可查看」权限,且图片格式为JPG、PNG、GIF等Slides支持的格式,文件大小不超过50MB。
const spreadsheetId = '1JSXC0XrfUAtcRLXCgVnB-SAQjwk_-YG7W_kGefowONE'; const thetemplateId = '1Pug2cPiGsPL9iKPEnBAhvBVqfSTMyJERCRaSGkyFOr0'; const dataRange = 'Monthly Top Producers!A2:F'; // 辅助函数:转换Drive链接为可直接访问的图片URL function convertDriveUrl(url) { if (!url) return ''; const fileIdMatch = url.match(/d\/([a-zA-Z0-9_-]+)/); return fileIdMatch ? `https://drive.google.com/uc?id=${fileIdMatch[1]}` : url; } function generateTopPro(){ let values = SpreadsheetApp.openById(spreadsheetId).getRange(dataRange).getValues(); for (let i = 0; i < values.length; ++i) { const row = values[i]; const agent_name = row[0]; const agent_phone = row[3]; const agent_photo = convertDriveUrl(row[4]); const logo_state = convertDriveUrl(row[5]); // 复制模板幻灯片 const copyTitle = agent_name + ' September'; let copyFile = { "title": copyTitle, "parents": [{"id": 'root'}] }; copyFile = Drive.Files.copy(copyFile, thetemplateId); const presentationCopyId = copyFile.id; // 构建更新请求 const requests = [{ "replaceAllText": { "containsText": { "text": '{{agent_name}}', "matchCase": true }, "replaceText": agent_name } }, { "replaceAllText": { "containsText": { "text": '{{agent_phone}}', "matchCase": true }, "replaceText": agent_phone } }, { "replaceAllShapesWithImage": { "imageUrl": agent_photo, "imageReplaceMethod": 'CENTER_INSIDE', "containsText": { "text": '{{agent_photo}}', "matchCase": true } } }, { "replaceAllShapesWithImage": { "imageUrl": logo_state, "imageReplaceMethod": 'CENTER_INSIDE', "containsText": { "text": '{{logo_state}}', "matchCase": true } } }]; // 执行更新 const result = Slides.Presentations.batchUpdate({ "requests": requests }, presentationCopyId); // 统计替换次数 let numReplacements = 0; result.replies.forEach(function(reply) { if (reply.replaceAllText) { numReplacements += reply.replaceAllText.occurrencesChanged; } }); console.log('Created presentation for %s with ID: %s', agent_name, presentationCopyId); console.log('Replaced %s text instances', numReplacements); } }
内容的提问来源于stack exchange,提问作者Chelsea Ziss

