Changing Order of Pages in PDF file using Google Apps Script

Gists

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.

 Share!