Create a Google Doc from a template
Make a copy of the template file with DriveApp.getFileById(templateId).makeCopy(name, folder), open the copy with DocumentApp.openById(copy.getId()), call body.replaceText("{{Name}}", value) for each placeholder, then doc.saveAndClose(). Loop sheet rows to create one document per row and write the document URL back into the sheet.
Syntax
DriveApp.getFileById(id).makeCopy(name, folder) then DocumentApp.openById(id).getBody().replaceText(pattern, replacement)| Part | What it is |
|---|---|
makeCopy(name, folder) | New Drive file with that name in the folder; returns the File |
replaceText(pattern, text) | Pattern is a regular expression string, so escape special characters |
doc.saveAndClose() | Commits changes; needed before exporting or emailing |
doc.getAs("application/pdf") | Blob of the document as PDF |
Examples
const template = DriveApp.getFileById("1Tmp...");
const folder = DriveApp.getFolderById("1Out...");
const copy = template.makeCopy("Offer for Ana", folder);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText("{{Name}}", "Ana");
body.replaceText("{{Amount}}", "1,250.00");
doc.saveAndClose();
Logger.log(copy.getUrl());Result: A new doc Offer for Ana with both placeholders replaced; its URL is logged
const sheet = SpreadsheetApp.getActiveSheet();
const rows = sheet.getRange(2, 1, sheet.getLastRow() - 1, 3).getValues();
rows.forEach((r, i) => {
if (r[2]) return; // already has a URL
const copy = template.makeCopy("Letter " + r[0], folder);
const doc = DocumentApp.openById(copy.getId());
doc.getBody().replaceText("{{Name}}", r[0]).replaceText("{{Date}}", Utilities.formatDate(new Date(), "Europe/Amsterdam", "d MMMM yyyy"));
doc.saveAndClose();
sheet.getRange(i + 2, 3).setValue(copy.getUrl());
});Result: One letter per row without a URL; column C receives each document link
const pdf = doc.getAs("application/pdf").setName("Offer for Ana.pdf");
folder.createFile(pdf);
MailApp.sendEmail("ana@example.com", "Your offer", "Attached.", {attachments: [pdf]});Result: PDF saved to the folder and emailed
Call saveAndClose and reopen, or use DriveApp.getFileById(id).getAs, to make sure the PDF has the latest text.
Common mistakes
- Placeholders are not replaced: the text in the Doc is split across formatting runs (for example a typo corrected mid-word); retype the placeholder in one go without formatting changes.
- replaceText with {{Total (USD)}} fails: parentheses are regex characters; escape them as \\( and \\) or keep placeholders to letters and underscores.
- The exported PDF shows the old placeholders: the document was not saved; call doc.saveAndClose() before getAs.
- Hundreds of copies hit the execution limit: process a batch per run and mark done rows, then continue on a trigger.
Practice Create a Google Doc from a template
These drills check your answer on live data, free, no account needed.
- Truncate with an ellipsisIf `s` has at most `max` characters, return it unchanged. Otherwise keep the first `max - 1` characters and add the ellipsis character `"…"`, so the result is exactly `max` characters long. Count characters as Unicode code points, so a character outside the Basic Multilingual Plane, such as 𝒳, is never cut in half. `max` is at least 1.
- Format moneyFormat `amount` as money in the given ISO currency code (like `"USD"` or `"JPY"`) and locale, the way `Intl.NumberFormat` does with `style: "currency"`. Each currency keeps its usual number of decimals, and each locale its own grouping.
- Run tasks in sequence`tasks` is an array of functions; each returns a Promise or a plain value. Run them one at a time, in order, starting each only after the previous one has finished, and resolve with the array of their results. If a task fails, reject and do not start the remaining tasks. Tests run on a fake clock: `setTimeout`, `clearTimeout` and `Date.now` are simulated, so waits are instant and exact.
Questions
Can I replace placeholders in headers, footers and tables?
Tables are part of the body and are covered. Headers and footers are separate: call doc.getHeader().replaceText and doc.getFooter().replaceText too.
Can I do the same with a Slides or Sheets template?
Yes: SlidesApp.openById(id).replaceAllText(find, replace) for Slides; for Sheets, copy the file and write values with setValues.
Related
- List files in DriveList Google Drive files with Apps Script: get a folder by id, iterate getFiles with hasNext and next, read name, URL, size and dates, include subfolders.
- Send email from a sheetSend email from Google Sheets with Apps Script: MailApp.sendEmail and GmailApp.sendEmail with HTML body, cc and attachments, loop a list of recipients, quota.
- Utilities.formatDateFormat dates in Google Apps Script with Utilities.formatDate: the time zone argument, Java pattern letters like yyyy MM dd HH mm, month names, MM versus mm.
- Loop through rowsLoop through rows in Google Sheets with Apps Script: read the data once with getValues, loop the 2D array with for, for...of or forEach, then write back.