You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Batch Request API批量导出100张Slides为PNG?

解决方案

一、将PNG导出转换为Batch Request

Google Batch API可将多个API请求打包为一个请求发送,减少网络往返次数,规避单次请求过多导致的超时问题。以下是在App Script中实现批量导出幻灯片为PNG的具体步骤:

1. 批量预处理幻灯片

先完成所有幻灯片副本的创建、文本与图片填充,统一收集导出所需参数:

function prepareAllTickets(rows) {
  const templateFile = DriveApp.getFileById(TEMPLATE_SLIDE_ID);
  const parentFolder = templateFile.getParents().next();
  // 提前检查并创建images文件夹,避免重复操作
  let imagesFolder = parentFolder.getFoldersByName('images').hasNext() 
    ? parentFolder.getFoldersByName('images').next() 
    : parentFolder.createFolder('images');
  
  const exportTasks = [];
  
  for (const row of rows) {
    // 复制模板并直接命名,减少后续重命名操作
    const copySlide = templateFile.makeCopy(`Ticket for ${row[2]}`, parentFolder);
    const workingSlides = SlidesApp.openById(copySlide.getId());
    const slide = workingSlides.getSlides()[0];
    
    // 一次遍历完成所有文本与图片替换
    slide.getPageElements().forEach(pageElement => {
      if (pageElement.getPageElementType() === SlidesApp.PageElementType.SHAPE) {
        const shapeText = pageElement.asShape().getText();
        shapeText.replaceAllText("{{FETLIFEHANDLE}}", row[2].toString());
        shapeText.replaceAllText("{{POSITION}}", row[3].toString());
        shapeText.replaceAllText("{{TICKETNO}}", row[0].toString());
      } else if (pageElement.getPageElementType() === SlidesApp.PageElementType.IMAGE) {
        const img = pageElement.asImage();
        if (img.getTitle() === "{{QRCODE}}") {
          img.replace(row[6].toString());
        }
      }
    });
    
    workingSlides.saveAndClose();
    // 收集导出任务参数
    exportTasks.push({
      slidesID: copySlide.getId(),
      slideID: slide.getObjectId(),
      filename: `Ticket-${row[2]}.png`,
      imagesFolder: imagesFolder
    });
    
    // 不需要保留幻灯片副本的话,直接移入回收站
    // copySlide.setTrashed(true);
  }
  
  return exportTasks;
}

2. 构造并发送Batch Request

将所有导出请求打包为Batch API请求发送:

function batchExportPNG(exportTasks) {
  const token = ScriptApp.getOAuthToken();
  const boundary = `batch_${Utilities.getUuid()}`;
  let batchBody = [];
  
  for (const task of exportTasks) {
    const exportUrl = `https://docs.google.com/presentation/d/${task.slidesID}/export/png?id=${task.slidesID}&pageid=${task.slideID}`;
    // 构造单个子请求的头部与内容
    batchBody.push(
      `--${boundary}`,
      "Content-Type: application/http",
      "Content-Transfer-Encoding: binary",
      "",
      `GET ${exportUrl} HTTP/1.1`,
      `Authorization: Bearer ${token}`,
      "Host: docs.google.com",
      ""
    );
  }
  
  // 添加请求结束标记
  batchBody.push(`--${boundary}--`);
  const payload = batchBody.join("\r\n");
  
  const options = {
    method: "POST",
    headers: {
      "Content-Type": `multipart/mixed; boundary=${boundary}`,
      "Authorization": `Bearer ${token}`
    },
    payload: payload,
    muteHttpExceptions: true
  };
  
  const response = UrlFetchApp.fetch("https://www.googleapis.com/batch", options);
  const responseBody = response.getContentText();
  
  // 解析响应并保存每个PNG文件
  const parts = responseBody.split(`--${boundary}`);
  for (let i = 1; i < parts.length - 1; i++) {
    const part = parts[i];
    const [headerPart, bodyPart] = part.split("\r\n\r\n", 2);
    if (!headerPart.includes("200 OK")) continue;
    
    const blob = Utilities.newBlob(Utilities.base64Decode(bodyPart.trim()), "image/png", exportTasks[i-1].filename);
    exportTasks[i-1].imagesFolder.createFile(blob);
  }
}

3. 调用批量处理函数

在主函数中串联两个步骤:

function processBatchTickets(rows) {
  const exportTasks = prepareAllTickets(rows);
  batchExportPNG(exportTasks);
}

二、其他加速代码的方法

除了Batch Request,还可通过以下方式优化性能:

  • 合并Slides操作:原代码每个形状重复调用3次replaceAllText,改为一次遍历完成所有文本替换,减少API调用次数。
  • 用Slides API替代SlidesApp:使用Slides API的batchUpdate方法,一次性提交所有文本替换、图片更新请求,大幅降低网络往返开销。
  • 减少Drive API调用:复制模板时直接指定目标文件夹与名称,避免后续getParents()、setName()的额外操作。
  • 启用V8运行时:确保项目使用V8引擎,它比旧引擎运行更快,支持现代JS语法。
  • 批量清理临时文件:导出PNG后统一删除幻灯片副本,减少Drive操作负载。

内容的提问来源于stack exchange,提问作者Abby Cottontail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 11:13:12