首页 > 解决方案 > 如何使用 Apps 脚本更改每页上打印的幻灯片数量

问题描述

我有一个电子表格,它以编程方式创建包含多张幻灯片的 Google 幻灯片演示文稿。

我想使用应用程序脚本来创建这些幻灯片的 pdf 版本,但每页上有多个幻灯片。

我知道如何使用DriveApp.create(blob)来获取我的幻灯片的 pdf 版本,但这每页只能制作一张幻灯片。

我也知道我可以访问幻灯片中的“打印设置和预览”设置来手动实现此功能。

无论如何,我可以只使用脚本来实现这个目标吗?

亲切的问候,

布雷特

编辑:为清楚起见,我附上了我想要的图像。我知道可以使用 Slides Ui。我想知道是否可以使用应用程序脚本。 描述幻灯片文件的 pdf 导出的图像文件,其中每页显示 6 张幻灯片。

标签: google-apps-scriptgoogle-slides-api

解决方案


  • 您想在一张幻灯片中汇总 6 张幻灯片,并将幻灯片导出为 PDF 文件。
  • 6张幻灯片中的每张幻灯片是每张幻灯片的图像。

如果我的理解是正确的,这个解决方法怎么样?不幸的是,在现阶段,在 SlidesApp 服务和 Slides API 中似乎没有直接实现上述的方法。我找不到这样的方法。因此,需要考虑解决方法。我挑战实现这一目标,因为我认为实现这一目标对我和其他用户也很有用。

此解决方法的流程如下。

流动:

  1. 将原始幻灯片文件复制为临时文件。
  2. 检索所有幻灯片的图像。
    • 当幻灯片文件导出为 PNG 文件时,首页将导出为 PNG 文件。我用过这个。
  3. 将检索到的图像放入并排列到临时文件中。
    • 当图像插入幻灯片时,检索大小并更改大小,然后将图像放置到计算的位置。
  4. 将幻灯片导出为 PDF 文件。
  5. 删除临时文件。
    • 在这种情况下,临时文件将被放入垃圾箱。

示例脚本:

请将此脚本复制并粘贴到脚本编辑器中。并请设置原始幻灯片的文件 ID。在此示例脚本中,colrow分别为 3 和 2。这和你的问题一样。如果您更改图像的大小和分隔,请修改wsizesepwsize是图像的宽度。设置此项后,将计算高度。

function myFunction() {
  // Please set these parameters
  var id = "### file ID ###"; // file ID of original Slides
  var col = 3; // Number of columns
  var row = 2; // Number of rows
  var wsize = 200; // Size of width of each image (pixels)
  var sep = 5; // Space of each image (pexels)


  // Create temporary file
  var originalFile = DriveApp.getFileById(id);
  var tempFile = originalFile.makeCopy();
  var idt = tempFile.getId();

  // Retrieve slides as images
  var s = SlidesApp.openById(idt);
  var slides = s.getSlides();
  var accessToken = ScriptApp.getOAuthToken();
  var baseUrl = "https://docs.google.com/presentation/d/" + idt + "/export/";
  var url = baseUrl + "png?access_token=" + accessToken;
  var blobs = slides.map(function(e) {
    var blob = UrlFetchApp.fetch(url).getBlob();
    slides[0].remove();
    s.saveAndClose();
    s = SlidesApp.openById(idt);
    slides = s.getSlides();
    return blob;
  });

  // Put images 
  var ph = s.getPageHeight();
  var pw = s.getPageWidth();
  var leftOffset = (pw - ((wsize * col) + (sep * (col - 1)))) / 2;
  if (leftOffset < 0) throw new Error("Images are sticking out from a slide.");
  var len = col * row;
  var loops = Math.ceil(blobs.length / (col * row));
  for (var loop = 0; loop < loops; loop++) {
    var ns = s.insertSlide(loop);
    var topOffset, top;
    var left = leftOffset;
    for (var i = len * loop; i < len + (len * loop); i++) {
      if (i === blobs.length) break;
      var image = ns.insertImage(blobs[i]);
      var w = image.getWidth();
      var h = image.getHeight();
      var hsize = h * wsize / w;
      if (i === 0 || i % len === 0) {
        topOffset = (ph - ((hsize * row) + sep)) / 2;
        if (topOffset < 0) throw new Error("Images are sticking out from a slide.");
        top = topOffset;
      }
      image.setWidth(wsize).setHeight(hsize).setTop(top).setLeft(left).getObjectId();
      if (i === col - 1 + (loop * len)) {
        top = topOffset + hsize + sep;
        left = leftOffset;
      } else {
        left += wsize + sep;
      }
    }
  }
  s.saveAndClose();

  // Export PDF file
  var urlPdf = baseUrl + "pdf?access_token=" + accessToken;
  var pdf = UrlFetchApp.fetch(urlPdf).getBlob();
  DriveApp.createFile(pdf.setName(originalFile.getName() + ".pdf"));
  tempFile.setTrashed(true);
}

输入:

这是原始幻灯片。此示例幻灯片有 15 张幻灯片。

在此处输入图像描述

输出:

这是导出的 PDF 文件。

在此处输入图像描述

参考:

编辑:

我在 Slides API上找到了presentations.pages.getThumbnail 。所以我还准备了一个使用它的示例脚本。

使用此脚本时,请在 API 控制台启用 Slides API。

示例脚本:

function myFunction() {
  // Please set these parameters
  var id = "### file ID ###"; // file ID of original Slides
  var col = 3; // Number of columns
  var row = 2; // Number of rows
  var wsize = 200; // Size of width of each image (pixels)
  var sep = 5; // Space of each image (pexels)


  // Retrieve slides as images
  var originalFile = SlidesApp.openById(id);
  var accessToken = ScriptApp.getOAuthToken();
  var pageObjectIds = originalFile.getSlides().map(function(e) {return e.getObjectId()});
  var reqUrls = pageObjectIds.map(function(pageObjectId) {
    return {
      method: "get",
      url: "https://slides.googleapis.com/v1/presentations/" + id + "/pages/" + pageObjectId + "/thumbnail?access_token=" + accessToken,
    };
  });
  var reqBlobs = UrlFetchApp.fetchAll(reqUrls).map(function(e) {
    var r = JSON.parse(e);
    return {
      method: "get",
      url: r.contentUrl,
    };
  });
  var blobs = UrlFetchApp.fetchAll(reqBlobs).map(function(e) {return e.getBlob()});

  // Create a temporary Slides and put images 
  var s = SlidesApp.create("temporarySlides");
  s.getSlides()[0].remove();
  var idt = s.getId();
  var ph = s.getPageHeight();
  var pw = s.getPageWidth();
  var leftOffset = (pw - ((wsize * col) + (sep * (col - 1)))) / 2;
  if (leftOffset < 0) throw new Error("Images are sticking out from a slide.");
  var len = col * row;
  var loops = Math.ceil(blobs.length / (col * row));
  for (var loop = 0; loop < loops; loop++) {
    var ns = s.insertSlide(loop);
    var topOffset, top;
    var left = leftOffset;
    for (var i = len * loop; i < len + (len * loop); i++) {
      if (i === blobs.length) break;
      var image = ns.insertImage(blobs[i]);
      var w = image.getWidth();
      var h = image.getHeight();
      var hsize = h * wsize / w;
      if (i === 0 || i % len === 0) {
        topOffset = (ph - ((hsize * row) + sep)) / 2;
        if (topOffset < 0) throw new Error("Images are sticking out from a slide.");
        top = topOffset;
      }
      image.setWidth(wsize).setHeight(hsize).setTop(top).setLeft(left).getObjectId();
      if (i === col - 1 + (loop * len)) {
        top = topOffset + hsize + sep;
        left = leftOffset;
      } else {
        left += wsize + sep;
      }
    }
  }
  s.saveAndClose();

  // Export PDF file
  var urlPdf = "https://docs.google.com/presentation/d/" + idt + "/export/" + "pdf?access_token=" + accessToken;
  var pdf = UrlFetchApp.fetch(urlPdf).getBlob();
  DriveApp.createFile(pdf.setName(originalFile.getName() + ".pdf"));
  DriveApp.getFileById(idt).setTrashed(true);
}

笔记:

  • 两个脚本都可以获得相同的结果。所以请选择其中之一。我认为第二个可能有点快,因为所有缩略图都是使用 fetchAll 检索的。

推荐阅读