Skip to content

This is a Google Apps Script library for managing PDFs.

License

Notifications You must be signed in to change notification settings

tanaikech/PDFApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PDFApp

MIT License

Overview

This is a Google Apps Script library for managing PDFs.

Description

Google Apps Script is one of the most powerful tools for cloud computing. When Google Apps Script is used, the result can be obtained even when the user doesn't stay in front of the PC and mobile phone by the triggers. One day, there might be a case where it is required to manage PDF data using Google Apps Script. The combination of Google Docs (Document, Spreadsheet, and Slide) and PDFs is useful for various situations. However, unfortunately, there are no built-in methods for directly managing PDFs using Google Apps Script. Fortunately, it seems that pdf-lib of the Javascript library can be used with Google Apps Script. By this, PDF data can be managed with Google Apps Script using this library. This Google Apps Script library manages PDFs by using it as a wrapper between Google Apps Script and pdf-lib.

I have already published the following posts.

I created this library to more efficiently manage PDFs with a simple script by summarising the scripts of these posts.

Library's project key

1Xmtr5XXEakVql7N6FqwdCNdpdijsJOxgqH173JSB0UOwdb0GJYJbnJLk

Usage

1. Install library

In order to use this library, please install the library as follows.

  1. Create a GAS project.

    • You can use this library for the GAS project of both the standalone and container-bound script types.
  2. Install this library.

    • Library's project key is 1Xmtr5XXEakVql7N6FqwdCNdpdijsJOxgqH173JSB0UOwdb0GJYJbnJLk.

Scopes

This library uses the following 3 scopes.

  • https://www.googleapis.com/auth/script.external_request
  • https://www.googleapis.com/auth/drive
  • https://www.googleapis.com/auth/presentations

Methods

Methods Description
setPDFBlob Give the source PDF blob. This method is used with other methods.
useStandardFont When you want to use the standard font, please use this method. This method is used with other methods.
useCustomFont When you want to use the custom font, please use this method. This method is used with other methods.
exportPages Export specific pages from a PDF blob.
getMetadata Get PDF metadata from a PDF blob.
udpateMetadata Update PDF metadata of a PDF blob.
reorderPages Reorder pages of a PDF blob.
mergePDFs Merge multiple PDF files in a single PDF.
convertPDFToPng Convert PDF pages to PNG images.
getValuesFromPDFForm Get values from PDF Form.
setValuesToPDFForm Set values to PDF Form.
createPDFFormBySlideTemplate Create PDF Form By Google Slide template.
embedObjects Embed objects into PDF blob.
insertHeaderFooter Add custom header and footer to PDF blob.
splitPDF Split each page of a PDF to an individual PDF file.
addPageNumbers Add page numbers to PDF.

setPDFBlob

Give the source PDF blob. This method is used with other methods.

In this sample script, the PDF metadata is retrieved.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

PDFApp.setPDFBlob(blob).getMetadata()
  .then(res => console.log(res))
  .catch(err => console.log(err));

useStandardFont

When you want to use the standard font, please use this method. This method is used with other methods.

In this sample script, a value is put into a field of PDF Form with "TimesRoman".

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const object = {
  values: [
    { "name": "textbox.sample1.sample1.page1", "value": "sample update text" }
  ],
};

PDFApp
.setPDFBlob(blob)
.useStandardFont("TimesRoman")
.setValuesToPDFForm(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));

useCustomFont

When you want to use the custom font, please use this method. This method is used with other methods.

In this sample script, a value is put into a field of PDF Form with a custom font.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const object = {
  values: [
    { "name": "textbox.sample1.sample1.page1", "value": "sample update text" }
  ],
};

PDFApp
.setPDFBlob(blob)
.useCustomFont(DriveApp.getFileById("###fileId of font file###).getBlob())
.setValuesToPDFForm(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));

exportPages

Export specific pages from a PDF blob.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const pageNumbers = [2, 4, 6, 8];

PDFApp.setPDFBlob(blob).exportPages(pageNumbers)
  .then(blob => DriveApp.createFile(blob))
  .catch(err => console.log(err));

getMetadata

Get PDF metadata from a PDF blob.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

PDFApp.setPDFBlob(blob).getMetadata()
  .then(res => console.log(res))
  .catch(err => console.log(err));
  • When this script is run, the metadata is retrieved from the inputted PDF blob.

  • When I tested this script, I noticed that the values of modificationDate and producer might be a bug in pdf-lib. modificationDate returns the execution time. producer always returns pdf-lib (https://github.com/Hopding/pdf-lib). I guessed that this might be a bug in pdf-lib. And, I would like to believe that this will be resolved in the future update.

  • This is from my post "Management of PDF Metadata using Google Apps Script".

udpateMetadata

Update PDF metadata of a PDF blob.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

const object = {
  title: ["sample title", { showInWindowTitleBar: true }], // This property is an array.
  subject: "sample subject",
  author: "sample author",
  creator: "sample creator",
  creationDate: new Date("2023-08-01T00:00:00"), // This value is date object.
  modificationDate: new Date("2023-08-01T10:00:00"), // This value is date object.
  keywords: ["sample keyword 1", "sample keyword 2", "sample keyword 3"], // This property is an array.
  producer: "sample producer",
};

PDFApp.setPDFBlob(blob).udpateMetadata(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));

reorderPages

Reorder pages of a PDF blob.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

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 = true; // 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.

PDFApp.setPDFBlob(blob).reorderPages({ newOrderOfpages, ignoreSkippedPages })
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • 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.

  • This is from my post "Changing Order of Pages in PDF file using Google Apps Script".

mergePDFs

Merge multiple PDF files in a single PDF.

const blob1 = DriveApp.getFileById("###fileId of PDF file 1###").getBlob();
const blob2 = DriveApp.getFileById("###fileId of PDF file 2###").getBlob();
const pdfBlobs = [blob1, blob2];

PDFApp.mergePDFs(pdfBlobs)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));

convertPDFToPng

Convert PDF pages to PNG images.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

PDFApp.setPDFBlob(blob).convertPDFToPng()
  .then(imageBlobs => imageBlobs.forEach(b => DriveApp.createFile(b)))
  .catch(err => console.log(err));

getValuesFromPDFForm

Get values from PDF Form.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

PDFApp.setPDFBlob(blob).getValuesFromPDFForm()
  .then(res => console.log(res))
  .catch(err => console.log(err));

Limitations

In the current stage, the fields of the textbox, the checkbox, the dropdown list, and the radio button of the PDF Form can be used.

setValuesToPDFForm

Set values to PDF Form.

Limitations

In the current stage, the fields of the textbox, the checkbox, the dropdown list, and the radio button of the PDF Form can be used.

Sample 1

In this sample, the default font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

const object = {
  values: [
    { "name": "textbox.sample1.sample1.page1", "value": "sample update text" },
    { "name": "dropdownlist.sample2.sample1.page1", "value": "sample option5" },
    { "name": "checkbox.sample3.checkbox1.page1", "value": true },
    { "name": "checkbox.sample3.checkbox2.page1", "value": false },
    { "name": "checkbox.sample3.checkbox3.page1", "value": true },
    { "name": "radiobutton.sample4.page1", "value": "radiobutton.sample4.radiobutton2.page1" }
  ],
};

const PDFA = PDFApp.setPDFBlob(blob);
PDFA.setValuesToPDFForm(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • When this script is run, the values of object are put into each field of PDF form and a new PDF blob is returned.

  • About the names of each field of PDF form, they can be retrieved by "getValuesFromPDFForm" method.

  • This is from my post "Retrieving and Putting Values for PDF Forms using Google Apps Script".

  • The detailed information about the format of name and each properties can be seen in this post.

Sample 2

In this sample, the standard font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

const object = {
  values: [
    { "name": "textbox.sample1.sample1.page1", "value": "sample update text" },
    { "name": "dropdownlist.sample2.sample1.page1", "value": "sample option5" },
    { "name": "checkbox.sample3.checkbox1.page1", "value": true },
    { "name": "checkbox.sample3.checkbox2.page1", "value": false },
    { "name": "checkbox.sample3.checkbox3.page1", "value": true },
    { "name": "radiobutton.sample4.page1", "value": "radiobutton.sample4.radiobutton2.page1" }
  ],
};

const PDFA = PDFApp.setPDFBlob(blob).useStandardFont("TimesRoman");
PDFA.setValuesToPDFForm(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • When this script is run, the values of object are put into each field of PDF form and a new PDF blob is returned. At that time, "TimesRoman" is used from the standard font.

  • The font names of the standard font can be obtained from https://pdf-lib.js.org/docs/api/enums/standardfonts.

  • The detailed information about the format of name and each properties can be seen in this post.

Sample 3

In this sample, the custom font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

const object = {
  values: [
    { "name": "textbox.sample1.sample1.page1", "value": "サンプルテキスト1" },
    { "name": "dropdownlist.sample2.sample1.page1", "value": "sample option5" },
    { "name": "checkbox.sample3.checkbox1.page1", "value": true },
    { "name": "checkbox.sample3.checkbox2.page1", "value": false },
    { "name": "checkbox.sample3.checkbox3.page1", "value": true },
    { "name": "radiobutton.sample4.page1", "value": "radiobutton.sample4.radiobutton2.page1" }
  ],
};

const PDFA = PDFApp.setPDFBlob(blob).useCustomFont(DriveApp.getFileById("###fileId of font file###").getBlob());
PDFA.setValuesToPDFForm(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • When this script is run, the values of object are put into each field of PDF form and a new PDF blob is returned. At that time, the custom font is used. For example, when you want to put Japanese language, the custom font is required to be used.

  • About the custom font, TTF and OTF files can be used.

  • The detailed information about the format of name and each properties can be seen in this post.

createPDFFormBySlideTemplate

Create PDF Form By Google Slide template.

About methods property in the object, the method name can be confirmed at the official document. Ref

For example, when you want to create a textbox, when { shapeTitle: "textbox.sample1.sample1", methods: [{ method: "setText", value: "sample text1" }]} is used, a textbox including sample text1 is created to the shape with the shape title of textbox.sample1.sample1.

Limitations

In the current stage, the fields of the textbox, the checkbox, the dropdown list, and the radio button of the PDF Form can be created.

Preparation

In this case, first, please create a Google Slide as a template as follows.

In the template slide, please set shapes and please set the shape titles. The shape title is required to be the unique value in the slide. Please be careful about this. The following script converts the template shapes to the fields of the PDF form using the shape titles. The flow of this is as follows.

  1. Create a new Google Slide.

  2. Put texts and shapes on the slide.

  3. Texts are used as the text in PDF.

  • Shapes are converted to the fields in PDF form.
  • Set the ID to the shape title (Alt Text).
  1. There is a rule regarding the format of ID. Please check the section “Rule of shape title (Alt Text)”.

Rule of shape title (Alt Text)

The format of ID (shape title (Alt Text)) is as follows.

{field type}.{group name}.{field name}

When the above sample Google Slide template is used, the IDs of fields of PDF form are as follows.

  • Textbox
    • textbox.sample1.sample1
    • textbox.sample1.sample2
  • Checkbox
    • checkbox.sample2.checkbox1
    • checkbox.sample2.checkbox2
    • checkbox.sample2.checkbox3
  • Dropdown
    • dropdownlist.sample4.sample1
  • Radiobutton
    • radiobutton.sample5.radiobutton1
    • radiobutton.sample5.radiobutton2
    • radiobutton.sample5.radiobutton3

In the case of radiobutton.sample5.radiobutton1, radiobutton is a type of field. sample5 is a group of fields. radiobutton1 is a unique name of the group. radiobutton.sample5 has 3 fields of radiobutton.sample5.radiobutton1, radiobutton.sample5.radiobutton2, and radiobutton.sample5.radiobutton3.

Sample 1

In this sample, the default font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const templateId = "###"; // Please set the file ID of your Google Slide template.

const object = {
  values: [
    {
      shapeTitle: "textbox.sample1.sample1",
      methods: [{ method: "setText", value: "sample text1" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox2",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox3",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "textbox.sample1.sample2",
      methods: [
        { method: "setText", value: "sample text2" },
        { method: "enableMultiline" },
        { method: "setFontSize", value: "12" },
      ],
    },
    {
      shapeTitle: "dropdownlist.sample4.sample1",
      methods: [
        {
          method: "setOptions",
          value: [
            "sample option1",
            "sample option2",
            "sample option3",
            "sample option4",
            "sample option5",
          ],
        },
        { method: "enableEditing" },
        { method: "enableMultiselect" },
        { method: "select", value: "sample option3" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton2",
      methods: [
        { method: "enableRequired" },
        { method: "select", value: "radiobutton.sample5.radiobutton2" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton3",
      methods: [{ method: "enableRequired" }],
    },
  ],
};

const templateSlide = DriveApp.getFileById(templateId);
const folder = templateSlide.getParents().next();
const temp = templateSlide.makeCopy("temp", folder);
const tempId = temp.getId();
PDFApp.createPDFFormBySlideTemplate(tempId, object)
  .then(newBlob => {
    folder.createFile(newBlob);
    temp.setTrashed(true);
  })
  .catch(err => console.log(err));
  • When this script is run, a PDF form is created from Google Slide template.

  • shapeTitle: Shape title (Alt Text).

  • method in methods: Method names of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • value in methods: Arguments of the methods of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • This is from my post "Creating PDF Forms from Google Slide Template using Google Apps Script".

  • The detailed information about the format of name and each properties can be seen in this post.

Sample 2

In this sample, the standard font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const templateId = "###"; // Please set the file ID of your Google Slide template.

const object = {
  values: [
    {
      shapeTitle: "textbox.sample1.sample1",
      methods: [{ method: "setText", value: "sample text1" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox2",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox3",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "textbox.sample1.sample2",
      methods: [
        { method: "setText", value: "sample text2" },
        { method: "enableMultiline" },
        { method: "setFontSize", value: "12" },
      ],
    },
    {
      shapeTitle: "dropdownlist.sample4.sample1",
      methods: [
        {
          method: "setOptions",
          value: [
            "sample option1",
            "sample option2",
            "sample option3",
            "sample option4",
            "sample option5",
          ],
        },
        { method: "enableEditing" },
        { method: "enableMultiselect" },
        { method: "select", value: "sample option3" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton2",
      methods: [
        { method: "enableRequired" },
        { method: "select", value: "radiobutton.sample5.radiobutton2" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton3",
      methods: [{ method: "enableRequired" }],
    },
  ],
};

const templateSlide = DriveApp.getFileById(templateId);
const folder = templateSlide.getParents().next();
const temp = templateSlide.makeCopy("temp", folder);
const tempId = temp.getId();
const PDFA = PDFApp.useStandardFont("TimesRoman"); // https://pdf-lib.js.org/docs/api/enums/standardfonts
PDFA.createPDFFormBySlideTemplate(tempId, object)
  .then(newBlob => {
    folder.createFile(newBlob);
    temp.setTrashed(true);
  })
  .catch(err => console.log(err));
  • shapeTitle: Shape title (Alt Text).

  • method in methods: Method names of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • value in methods: Arguments of the methods of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • When the standard font of pdf-lib, please modify the above script as follows. The value can be known at here. For example, when you want to use "TimesRoman", please set { standardFont: "TimesRoman" }.

  • This is from my post "Creating PDF Forms from Google Slide Template using Google Apps Script".

  • The detailed information about the format of name and each properties can be seen in this post.

Sample 3

In this sample, the custom font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const templateId = "###"; // Please set the file ID of your Google Slide template.
const fileIdOfFontFile = "###"; // Please set the file ID of the custom font. TTF and OTF.

const object = {
  values: [
    {
      shapeTitle: "textbox.sample1.sample1",
      methods: [{ method: "setText", value: "sample text1" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox2",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "checkbox.sample2.checkbox3",
      methods: [{ method: "enableRequired" }, { method: "check" }],
    },
    {
      shapeTitle: "textbox.sample1.sample2",
      methods: [
        { method: "setText", value: "sample text2" },
        { method: "enableMultiline" },
        { method: "setFontSize", value: "12" },
      ],
    },
    {
      shapeTitle: "dropdownlist.sample4.sample1",
      methods: [
        {
          method: "setOptions",
          value: [
            "sample option1",
            "sample option2",
            "sample option3",
            "sample option4",
            "sample option5",
          ],
        },
        { method: "enableEditing" },
        { method: "enableMultiselect" },
        { method: "select", value: "sample option3" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton1",
      methods: [{ method: "enableRequired" }],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton2",
      methods: [
        { method: "enableRequired" },
        { method: "select", value: "radiobutton.sample5.radiobutton2" },
      ],
    },
    {
      shapeTitle: "radiobutton.sample5.radiobutton3",
      methods: [{ method: "enableRequired" }],
    },
  ],
};

const templateSlide = DriveApp.getFileById(templateId);
const folder = templateSlide.getParents().next();
const temp = templateSlide.makeCopy("temp", folder);
const tempId = temp.getId();
const PDFA = PDFApp.useCustomFont(DriveApp.getFileById(fileIdOfFontFile).getBlob());
PDFA.createPDFFormBySlideTemplate(tempId, object)
  .then(newBlob => {
    folder.createFile(newBlob);
    temp.setTrashed(true);
  })
  .catch(err => console.log(err));
  • When this script is run, a PDF form is created from Google Slide template.

  • shapeTitle: Shape title (Alt Text).

  • method in methods: Method names of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • value in methods: Arguments of the methods of Class PDFCheckBox, PDFDropdown, PDFRadioGroup, and PDFTextField.

  • In order to use the custom font, please prepare the font you want to use. TTF and OTF files can be used.

  • This is from my post "Creating PDF Forms from Google Slide Template using Google Apps Script".

  • The detailed information about the format of name and each properties can be seen in this post.

embedObjects

Embed objects into PDF blob.

Limitations

In the current stage, the objects of texts and images can be embedded in a PDF.

Sample 1

In this sample, the default font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const object = {
  page1: [
    { text: "sample text1", x: 150, y: 635, size: 30 },
    { text: "sample text2", x: 390, y: 602, size: 16 },
    { imageFileId: "### file ID of image file ###", x: 175, y: 340, scale: 0.35 },
  ],
};
PDFApp.setPDFBlob(blob).embedObjects(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • When this script is run, 2 texts and 1 image are embedded to the 1st page of the PDF file with the default font.

    • From

    • To

  • In this case, object is constructed as follows. By this, you can set the objects for each page.

const object = {
  page1: [
    { text: "sample text1", x: 150, y: 635, size: 30 },
    { text: "sample text2", x: 390, y: 602, size: 16 },
    { imageFileId: "### file ID of image file ###", x: 175, y: 340, scale: 0.35 },
  ],
  page2: [,,,],
  page3: [,,,],
  ,
  ,
  ,
};

Sample 2

In this sample, the standard font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const object = {
  page1: [
    { text: "sample text1", x: 150, y: 635, standardFont: "Helvetica", size: 30 },
    { text: "sample text2", x: 390, y: 602, standardFont: "TimesRoman", size: 16 },
    { imageFileId: "### file ID of image file ###", x: 175, y: 340, scale: 0.35 },
  ],
};
PDFApp.setPDFBlob(blob).embedObjects(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));

Sample 3

In this sample, the custom font is used.

const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
const object = {
  page1: [
    { text: "sample text1", x: 150, y: 635, customFont: DriveApp.getFileById("### file ID of custom font file ###").getBlob(), size: 30 },
    { text: "sample text2", x: 390, y: 602, standardFont: "TimesRoman", size: 16 },
    { imageFileId: "### file ID of image file ###", x: 175, y: 340, scale: 0.35 },
  ],
};
PDFApp.setPDFBlob(blob).embedObjects(object)
  .then(newBlob => DriveApp.createFile(newBlob))
  .catch(err => console.log(err));
  • When this script is run, 2 texts and 1 image are embedded to the 1st page of the PDF file with the custom font. For example, when you want to use the Japanese language, it is required to use the custom font.

  • This is from my post "Embedding Objects in PDF using Google Apps Script".

  • The detailed information about the format of name and each properties can be seen in this post.

insertHeaderFooter

Add custom header and footer to PDF blob.

When this method is used, the result showin in my blog can be obtained. Ref

Sample script 1

In this sample, the default font is used.

function sample() {
  const object = {
    header: {
      left: { height: 30, alignment: "Center", text: "sample text h1" },
      center: { height: 30, alignment: "Center", text: "sample text h2" },
      right: { height: 30, alignment: "Center", text: "sample text h3" },
    },
    footer: {
      left: { height: 30, alignment: "Center", text: "sample text f1" },
      center: { height: 30, alignment: "Center", text: "sample text f2" },
      right: { height: 30, alignment: "Center", text: "sample text f3" },
    },
  }

  const blob = SpreadsheetApp.getActiveSpreadsheet().getBlob()
  const PDFA = PDFApp.setPDFBlob(blob)
  PDFA.insertHeaderFooter(object)
    .then(blob => DriveApp.createFile(blob))
    .catch(err => console.log(err));
}

Sample script 2

In this sample, the standard font is used.

function sample() {
  const object = {
    header: {
      left: { height: 30, alignment: "Center", text: "sample text h1" },
      center: { height: 30, alignment: "Center", text: "sample text h2" },
      right: { height: 30, alignment: "Center", text: "sample text h3" },
    },
    footer: {
      left: { height: 30, alignment: "Center", text: "sample text f1" },
      center: { height: 30, alignment: "Center", text: "sample text f2" },
      right: { height: 30, alignment: "Center", text: "sample text f3" },
    },
  }

  const blob = SpreadsheetApp.getActiveSpreadsheet().getBlob();
  const PDFA = PDFApp.setPDFBlob(blob).useStandardFont("TimesRoman");
  PDFA.insertHeaderFooter(object)
    .then(blob => DriveApp.createFile(blob))
    .catch(err => console.log(err));
}

Sample script 3

In this sample, the custom font is used.

function sample2() {
  const object = {
    header: {
      left: { height: 30, alignment: "Center", text: "sample text h1" },
      center: { height: 30, alignment: "Center", text: "sample text h2" },
      right: { height: 30, alignment: "Center", text: "sample text h3" },
    },
    footer: {
      left: { height: 30, alignment: "Center", text: "sample text f1" },
      center: { height: 30, alignment: "Center", text: "sample text f2" },
      right: { height: 30, alignment: "Center", text: "sample text f3" },
    },
  }

  const fileIdOfFontFile = "###"; // File ID of font file (TTF and OTF)
  const blob = SpreadsheetApp.getActiveSpreadsheet().getBlob();
  const PDFA = PDFApp.setPDFBlob(blob).useCustomFont(DriveApp.getFileById(fileIdOfFontFile).getBlob());
  PDFA.insertHeaderFooter(object)
    .then(blob => DriveApp.createFile(blob))
    .catch(err => console.log(err));
}

splitPDF

Split each page of a PDF to an individual PDF file.

Sample script

function sample() {
  const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();
  PDFApp.setPDFBlob(blob).splitPDF()
    .then(blobs => {
      console.log(blobs.length);
      blobs.forEach(blob => DriveApp.createFile(blob));
    })
    .catch(err => console.log(err));
}
  • When this script is run, each page of the source PDF file is created each PDF file.

addPageNumbers

Add page numbers to PDF.

Sample script

function sample() {
  const blob = DriveApp.getFileById("###fileId of PDF file###").getBlob();

  const object = { size: 10, x: "center", y: 10 };
  PDFApp.setPDFBlob(blob).addPageNumbers(object)
    .then(newBlob => DriveApp.createFile(newBlob))
    .catch(err => console.log(err));
}

The sample demonstration script is as follows. When the following script is run, a new Google Document is created and the page numbers are added to each page of the PDF.

function sample() {
  // Create a sample Google Document.
  const tempDoc = DocumentApp.create("tempDoc");
  const body = tempDoc.getBody();
  for (let p = 0; p < 5; p++) {
    body.appendParagraph(`sample text ${p + 1}`).appendPageBreak();
  }
  tempDoc.saveAndClose();
  const blob = tempDoc.getBlob();

  const object = { size: 10, x: "center", y: 10 };
  PDFApp.setPDFBlob(blob).addPageNumbers(object)
    .then(newBlob => DriveApp.createFile(newBlob))
    .catch(err => console.log(err));
}
  • When this script is run, the page numbers are put to the center of the bottom of each page.
  • You can simply customize the page numbers by modifying const object = { size: 10, x: "center", y: 10 }. The value of x can be selected as one of "left", "center", and "right".
  • In this method, a simple format like { size: 10, x: "center", y: 10 } is used for the page numbers. Here, the page numbers are put to only "left", "center", and "right" of the bottom of the page. The page numbers can be customized variously. So, when you want to customize more, I would like to recommend using the script on my blog by modifying.
  • When a number is used to the property x instead of "left", "center", and "right", the inputted number is directly used. For example, you can also use const object = { size: 10, x: 10, y: 10 }; instead of const object = { size: 10, x: "center", y: 10 };.

Licence

MIT

Author

Tanaike

Donate

Update History

  • v1.0.0 (August 17, 2023)

    1. Initial release.
  • v1.0.1 (August 18, 2023)

    1. About the method of "getMetadata", pageInfo is added to the retrieved metadata. By this, each page size can be obtained.
  • v1.0.2 (August 21, 2023)

    1. A new method of insertHeaderFooter was added. Ref When this method is used, the custom header and footer can be added when a Google Spreadsheet is exported as PDF.
  • v1.0.3 (November 26, 2023)

    1. From this discussion, I changed the logic of the method mergePDFs. The method for using mergePDFs and the output are not changed. With this modification, the large PDF data can be merged.
  • v1.0.4 (February 5, 2024)

    1. From this discussion, I changed the logic of copyPages.
  • v1.0.5 (February 5, 2024)

    1. A new method of "splitPDF" was added. Ref This method splits each page of a PDF to an individual PDF file.
  • v1.0.6 (May 15, 2024)

    1. A new method of "addPageNumbers" was added. Ref This method adds the page numbers to each page of the PDF.
  • v1.0.7 (May 15, 2024)

    1. The method of "addPageNumbers" was updated. Ref When a number is used to the property x instead of "left", "center", and "right", the inputted number is directly used.

TOP