Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Created July 27, 2023 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanaikech/9de62573049e72b44a069fc31348524b to your computer and use it in GitHub Desktop.
Save tanaikech/9de62573049e72b44a069fc31348524b to your computer and use it in GitHub Desktop.
Changing Order of Pages in PDF file using Google Apps Script

Changing Order of Pages in PDF file using Google Apps Script

This is a sample script for changing the order of pages in a PDF file using Google Apps Script.

Sample script

Before you run this script, please set the variables in the function main.

/**
 * ### Description
 * Changing order of pages in a PDF file.
 *
 * @param {Object} fileId is file ID of PDF file. newOrderOfpages is new order of pages. About "ignoreSkippedPages", if this is false, when the PDF has 5 pages and "newOrderOfpages" is "[3, 2]", the exported PDF file has 5 pages of 3, 2, 1, 4, 5. If this is true, when the PDF has 5 pages and "newOrderOfpages" is "[3, 2]", the exported PDF file has only 2 pages of 3 and 2.
 * @return {void}
 */
async function changeOrderOfPDFPages_({ fileId, newOrderOfpages, ignoreSkippedPages }) {
  // Load pdf-lib
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load pdf-lib
  const setTimeout = function (f, t) {
    Utilities.sleep(t);
    return f();
  };

  const blob = DriveApp.getFileById(fileId).getBlob();
  const pdfData = await PDFLib.PDFDocument.load(new Uint8Array(blob.getBytes()));
  const numberOfPages = pdfData.getPageCount();
  const maxPage = Math.max(...newOrderOfpages);
  if (numberOfPages < maxPage || numberOfPages < newOrderOfpages.length) {
    throw new Error("Maximum page in the order of pages is over than the maximum page of the original PDF file.");
  }
  let skippedPages = [];
  if (!ignoreSkippedPages && numberOfPages > newOrderOfpages.length) {
    skippedPages = [...Array(numberOfPages)].map((_, i) => i + 1).filter(e => !newOrderOfpages.includes(e));
  }
  const pdfDoc = await PDFLib.PDFDocument.create();
  const pages = await pdfDoc.copyPages(pdfData, [...Array(numberOfPages)].map((_, i) => i));
  [...newOrderOfpages, ...skippedPages].forEach(e => pdfDoc.addPage(pages[e - 1]));
  const bytes = await pdfDoc.save();
  return Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, "sample.pdf");
}

function main() {
  const fileId = "###"; // Please set a file ID of your a PDF file or a file ID of Google Docs files (Document, Spreadsheet, Slide).
  const newOrderOfpages = [3, 1, 2, 5, 4]; // Please set new order of the pages in a PDF file. In this sample, the order of pages of the original PDF file is changed to 3, 1, 2, 5, 4.
  const ignoreSkippedPages = false; // If this is false, when the PDF has 5 pages and "newOrderOfpages" is "[3, 2]", the exported PDF file has 5 pages of 3, 2, 1, 4, 5. If this is true, when the PDF has 5 pages and "newOrderOfpages" is "[3, 2]", the exported PDF file has only 2 pages of 3 and 2.

  changeOrderOfPDFPages_({ fileId, newOrderOfpages, ignoreSkippedPages }).then(blob => {
    DriveApp.createFile(blob.setName("sample.pdf"));
  });
}

When this script is run, a new PDF file is created with the new order of pages.

When the order of pages is changed, I thought that for example, when a PDF file has 5 pages and you want to replace only the 1st page and the 2nd page, the actual exported pages are 2, 1, 3, 4, 5. But, in this script, when ignoreSkippedPages is used as false, this can be achieved by newOrderOfpages of [2, 1]. On the other hand, when ignoreSkippedPages and newOrderOfpages are true and [2, 1], respectively, a new PDF file with only 2 pages of the 2nd page and the 1st page is created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment