I have a spreadsheet that programmatically creates a Google Slides presentation with multiple slides.
I want to use apps script to create a pdf version of these slides but with multiple slides on each page.
I know how to use DriveApp.create(blob)
to get a pdf version of my slides but this only does one slide per page.
I also know that I can access the "Print Settings and Preview" settings within Slides to achieve this functionality manually.
Is there anyway that I can achieve this goal exclusively using a script?
Kind regards,
Brett
EDIT: For clarity I am attaching an image of what I want. I know that it is possible using the Slides Ui. I want to know if it's possible using apps script.
If my understanding is correct, how about this workaround? Unfortunately, in the current stage, it seems that there are no methods for directly achieving above in SlidesApp service and Slides API. I couldn't find such methods. So it is required to think of the workaround. I challenged to achieve this because I thought that achieving this is also useful for me and other users.
The flow of this workaround is as follows.
Please copy and paste this script to the script editor. And please set the file ID of original Slides. In this sample script, col
and row
are 3 and 2, respectively. This is the same with your question. If you change the size of images and separation, please modify wsize
and sep
. wsize
is the width of image. When this is set, the height is calculated.
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);
}
This is the original Slides. This sample Slide has 15 slides.
This is the exported PDF file.
I found presentations.pages.getThumbnail at Slides API. So I also prepared a sample script using it.
When you use this script, please enable Slides API at API console.
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);
}