This document provides a comprehensive collection of Google Apps Script examples tailored for Google Docs. Each script is designed to automate common tasks, enhance productivity, and extend the functionality of your documents.
1. Basic Document Access & Creation
These scripts cover the fundamental ways to access existing documents, create new ones, and get references to their main content.
1.1. Open the Active Document
What it achieves: Gets a reference to the Google Doc that the script is currently bound to or running from. This is the most common starting point for Docs scripts.
function getActiveDoc() {
const doc = DocumentApp.getActiveDocument();
Logger.log(‘Active Document Name: ‘ + doc.getName());
}
1.2. Create a New Blank Document
What it achieves: Creates a brand new, empty Google Doc in your Google Drive.
function createNewDoc() {
const newDoc = DocumentApp.create(‘My New Blank Document’);
Logger.log(‘New Document URL: ‘ + newDoc.getUrl());
}
1.3. Open a Document by ID
What it achieves: Opens a specific Google Doc using its unique ID. You can find the ID in the document’s URL (e.g., https://docs.google.com/document/d/YOUR_DOCUMENT_ID/edit).
function openDocById() {
const docId = ‘YOUR_DOCUMENT_ID_HERE’; // Replace with your document ID
const doc = DocumentApp.openById(docId);
Logger.log(‘Opened Document Name: ‘ + doc.getName());
}
1.4. Open a Document by Name
What it achieves: Opens the first Google Doc found in your Drive with a specific name. Be cautious, as this might not be the exact document you intend if multiple documents share the same name.
function openDocByName() {
const docName = ‘My Specific Document’; // Replace with your document name
const files = DriveApp.getFilesByName(docName);
if (files.hasNext()) {
const file = files.next();
const doc = DocumentApp.openById(file.getId());
Logger.log(‘Opened Document Name: ‘ + doc.getName());
} else {
Logger.log(‘Document not found.’);
}
}
1.5. Get Document Body Content
What it achieves: Retrieves the main content area (the body) of the active document. Most text, paragraphs, tables, and images reside within the body.
function getDocBody() {
const body = DocumentApp.getActiveDocument().getBody();
Logger.log(‘Body content type: ‘ + body.getType());
}
1.6. Append Text to Document
What it achieves: Adds a new paragraph of text to the very end of the document’s body.
function appendText() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendParagraph(‘This is new text appended by a script.’);
Logger.log(‘Text appended.’);
}
1.7. Insert Text at Cursor Position
What it achieves: If the script is run from an open document and the user has a cursor active, this inserts text at that specific point.
function insertTextAtCursor() {
const cursor = DocumentApp.getActiveDocument().getCursor();
if (cursor) {
cursor.insertText(‘Text inserted at cursor.’);
Logger.log(‘Text inserted at cursor.’);
} else {
DocumentApp.getUi().alert(‘Please place your cursor in the document before running this script.’);
}
}
1.8. Clear All Document Content
What it achieves: Deletes all content (paragraphs, tables, images, etc.) from the document body, leaving it blank.
function clearAllContent() {
const body = DocumentApp.getActiveDocument().getBody();
body.clear();
Logger.log(‘Document content cleared.’);
}
1.9. Save and Close Document (Not explicitly needed for bound scripts)
What it achieves: While Apps Script automatically saves changes, this example demonstrates how you might conceptually “save” by ensuring operations are complete. saveAndClose() is typically used when opening a document by ID and you want to ensure changes are flushed before closing the programmatic reference.
function saveAndCloseDoc() {
const doc = DocumentApp.getActiveDocument(); // Or DocumentApp.openById(‘ID’)
// Perform some operations here, e.g., doc.getBody().appendParagraph(‘…’);
doc.saveAndClose(); // Flushes changes and closes the programmatic access
Logger.log(‘Document saved and closed (programmatically).’);
}
1.10. Rename the Active Document
What it achieves: Changes the title (name) of the active Google Doc.
function renameDocument() {
const doc = DocumentApp.getActiveDocument();
doc.setName(‘My Renamed Document – ‘ + new Date().toLocaleDateString());
Logger.log(‘Document renamed.’);
}
2. Text & Paragraph Manipulation
These scripts focus on handling text blocks and entire paragraphs within your Google Doc.
2.11. Get All Paragraphs
What it achieves: Retrieves all paragraph elements from the document body.
function getAllParagraphs() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
Logger.log(‘Total paragraphs: ‘ + paragraphs.length);
paragraphs.forEach((paragraph, index) => {
Logger.log(`Paragraph ${index + 1}: ${paragraph.getText().substring(0, 50)}…`);
});
}
2.12. Get Text of a Specific Paragraph
What it achieves: Accesses the text content of a paragraph at a given index.
function getSpecificParagraphText() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const firstParagraphText = paragraphs[0].getText();
Logger.log(‘Text of first paragraph: ‘ + firstParagraphText);
} else {
Logger.log(‘No paragraphs found.’);
}
}
2.13. Set Text of a Specific Paragraph
What it achieves: Replaces the entire text content of a specific paragraph.
function setSpecificParagraphText() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setText(‘This is the new text for the first paragraph.’);
Logger.log(‘First paragraph text updated.’);
} else {
Logger.log(‘No paragraphs found to update.’);
}
}
2.14. Append Text to an Existing Paragraph
What it achieves: Adds text to the end of an existing paragraph without replacing its current content.
function appendToParagraph() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const paragraph = paragraphs[0];
paragraph.appendText(‘ — Appended more text.’);
Logger.log(‘Text appended to first paragraph.’);
} else {
body.appendParagraph(‘Initial paragraph.’);
Logger.log(‘Created initial paragraph as none existed.’);
}
}
2.15. Delete a Specific Paragraph
What it achieves: Removes a paragraph from the document.
function deleteSpecificParagraph() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 1) { // Ensure there’s at least two to delete the second one
const paragraphToDelete = paragraphs[1]; // Delete the second paragraph
paragraphToDelete.removeFromParent();
Logger.log(‘Second paragraph deleted.’);
} else {
Logger.log(‘Not enough paragraphs to delete the second one.’);
}
}
2.16. Insert a Paragraph Before Another
What it achieves: Adds a new paragraph immediately before an existing one.
function insertParagraphBefore() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const targetParagraph = paragraphs[0];
body.insertParagraph(body.getChildIndex(targetParagraph), ‘This paragraph was inserted before the first one.’);
Logger.log(‘Paragraph inserted before the first.’);
} else {
body.appendParagraph(‘First paragraph.’);
Logger.log(‘Created initial paragraph as none existed.’);
}
}
2.17. Set Paragraph Alignment (Left, Center, Right, Justify)
What it achieves: Changes the horizontal alignment of a paragraph.
function setParagraphAlignment() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setAlignment(DocumentApp.HorizontalAlignment.CENTER);
Logger.log(‘First paragraph aligned to center.’);
if (paragraphs.length > 1) {
paragraphs[1].setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
Logger.log(‘Second paragraph aligned to right.’);
}
} else {
body.appendParagraph(‘This is a paragraph to center.’).setAlignment(DocumentApp.HorizontalAlignment.CENTER);
body.appendParagraph(‘This is a paragraph to right align.’).setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
Logger.log(‘Created and aligned new paragraphs.’);
}
}
2.18. Set Paragraph Spacing (Line Spacing)
What it achieves: Adjusts the line spacing (e.g., single, 1.5, double) for a paragraph.
function setParagraphLineSpacing() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setLineSpacing(1.5); // 1.5 line spacing
Logger.log(‘First paragraph line spacing set to 1.5.’);
} else {
body.appendParagraph(‘This paragraph will have 1.5 line spacing.’).setLineSpacing(1.5);
Logger.log(‘Created new paragraph with 1.5 line spacing.’);
}
}
2.19. Set Paragraph Indentation (First Line)
What it achieves: Sets the indentation for the first line of a paragraph.
function setFirstLineIndent() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setFirstLineIndent(36); // 36 points = 0.5 inch
Logger.log(‘First paragraph first line indented by 36 points.’);
} else {
body.appendParagraph(‘This paragraph will have its first line indented.’).setFirstLineIndent(36);
Logger.log(‘Created new paragraph with first line indent.’);
}
}
2.20. Set Paragraph Indentation (Left & Right)
What it achieves: Sets the left and right indentation for an entire paragraph.
function setLeftRightIndent() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setIndentStart(72).setIndentEnd(36); // Left indent 72pt, Right indent 36pt
Logger.log(‘First paragraph left indented by 72 points and right indented by 36 points.’);
} else {
body.appendParagraph(‘This paragraph will have left and right indentation.’).setIndentStart(72).setIndentEnd(36);
Logger.log(‘Created new paragraph with left and right indent.’);
}
}
3. Formatting (Font, Color, Style)
These scripts deal with applying various formatting styles to text.
3.21. Set Font Family
What it achieves: Changes the font of a specific paragraph or text range.
function setFontFamily() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setFontFamily(‘Arial’);
Logger.log(‘First paragraph font set to Arial.’);
} else {
body.appendParagraph(‘This text will be Arial.’).setFontFamily(‘Arial’);
Logger.log(‘Created new paragraph with Arial font.’);
}
}
3.22. Set Font Size
What it achieves: Changes the size of the font.
function setFontSize() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setFontSize(18);
Logger.log(‘First paragraph font size set to 18.’);
} else {
body.appendParagraph(‘This text will be size 18.’).setFontSize(18);
Logger.log(‘Created new paragraph with font size 18.’);
}
}
3.23. Apply Bold Formatting
What it achieves: Makes text bold.
function applyBold() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
// Make the entire first paragraph bold
paragraphs[0].setBold(true);
Logger.log(‘First paragraph set to bold.’);
} else {
body.appendParagraph(‘This text will be bold.’).setBold(true);
Logger.log(‘Created new paragraph with bold text.’);
}
}
3.24. Apply Italic Formatting
What it achieves: Makes text italic.
function applyItalic() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setItalic(true);
Logger.log(‘First paragraph set to italic.’);
} else {
body.appendParagraph(‘This text will be italic.’).setItalic(true);
Logger.log(‘Created new paragraph with italic text.’);
}
}
3.25. Apply Underline Formatting
What it achieves: Underlines text.
function applyUnderline() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setUnderline(true);
Logger.log(‘First paragraph set to underlined.’);
} else {
body.appendParagraph(‘This text will be underlined.’).setUnderline(true);
Logger.log(‘Created new paragraph with underlined text.’);
}
}
3.26. Set Text Color
What it achieves: Changes the color of text.
function setTextColor() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setForegroundColor(‘#FF0000’); // Red color
Logger.log(‘First paragraph text color set to red.’);
} else {
body.appendParagraph(‘This text will be red.’).setForegroundColor(‘#FF0000’);
Logger.log(‘Created new paragraph with red text.’);
}
}
3.27. Set Background Color (Highlight)
What it achieves: Applies a background highlight color to text.
function setBackgroundColor() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setBackgroundColor(‘#FFFF00’); // Yellow highlight
Logger.log(‘First paragraph background color set to yellow.’);
} else {
body.appendParagraph(‘This text will be highlighted yellow.’).setBackgroundColor(‘#FFFF00’);
Logger.log(‘Created new paragraph with yellow highlight.’);
}
}
3.28. Apply Heading Style (Heading 1)
What it achieves: Applies a predefined heading style (e.g., Heading 1) to a paragraph.
function applyHeading1() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraph = body.appendParagraph(‘This is a Main Heading’);
paragraph.setHeading(DocumentApp.ParagraphHeading.HEADING1);
Logger.log(‘New paragraph set as Heading 1.’);
}
3.29. Apply Normal Text Style
What it achieves: Resets a paragraph to the default “Normal text” style.
function applyNormalText() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].setHeading(DocumentApp.ParagraphHeading.NORMAL);
Logger.log(‘First paragraph set to Normal text style.’);
} else {
body.appendParagraph(‘This is normal text.’).setHeading(DocumentApp.ParagraphHeading.NORMAL);
Logger.log(‘Created new paragraph with normal text style.’);
}
}
3.30. Remove All Formatting from a Paragraph
What it achieves: Clears all direct formatting (bold, italic, color, size, etc.) from a paragraph, reverting it to the default style of its parent.
function removeAllFormatting() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
paragraphs[0].clearAttributes();
Logger.log(‘All formatting removed from first paragraph.’);
} else {
body.appendParagraph(‘Formatted text to clear.’).setBold(true).setFontSize(20).setForegroundColor(‘#0000FF’);
body.getParagraphs()[0].clearAttributes();
Logger.log(‘Created and cleared formatting from new paragraph.’);
}
}
4. Lists (Bulleted & Numbered)
Scripts for creating and manipulating bulleted and numbered lists.
4.31. Create a Simple Bulleted List
What it achieves: Adds a new bulleted list to the document.
function createBulletedList() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendListItem(‘Item 1’).setGlyphType(DocumentApp.GlyphType.BULLET);
body.appendListItem(‘Item 2’).setGlyphType(DocumentApp.GlyphType.BULLET);
body.appendListItem(‘Item 3’).setGlyphType(DocumentApp.GlyphType.BULLET);
Logger.log(‘Bulleted list created.’);
}
4.32. Create a Simple Numbered List
What it achieves: Adds a new numbered list.
function createNumberedList() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendListItem(‘First item’).setGlyphType(DocumentApp.GlyphType.NUMBER);
body.appendListItem(‘Second item’).setGlyphType(DocumentApp.GlyphType.NUMBER);
body.appendListItem(‘Third item’).setGlyphType(DocumentApp.GlyphType.NUMBER);
Logger.log(‘Numbered list created.’);
}
4.33. Indent a List Item (Sub-item)
What it achieves: Moves a list item to a lower level of indentation, creating a sub-item.
function indentListItem() {
const body = DocumentApp.getActiveDocument().getBody();
// Ensure there’s a list to work with
body.appendListItem(‘Main Item 1’).setGlyphType(DocumentApp.GlyphType.BULLET);
body.appendListItem(‘Sub Item 1.1’).setGlyphType(DocumentApp.GlyphType.BULLET);
body.appendListItem(‘Main Item 2’).setGlyphType(DocumentApp.GlyphType.BULLET);
const listItems = body.getListItems();
if (listItems.length >= 2) {
listItems[1].setIndentStart(36); // Indent by 36 points (0.5 inch)
Logger.log(‘Second list item indented.’);
} else {
Logger.log(‘Not enough list items to indent.’);
}
}
4.34. Outdent a List Item
What it achieves: Moves a list item to a higher level of indentation.
function outdentListItem() {
const body = DocumentApp.getActiveDocument().getBody();
// Create a list with an indented item
body.appendListItem(‘Main Item’).setGlyphType(DocumentApp.GlyphType.BULLET);
body.appendListItem(‘Sub Item’).setGlyphType(DocumentApp.GlyphType.BULLET).setIndentStart(36);
const listItems = body.getListItems();
if (listItems.length >= 2) {
listItems[1].setIndentStart(0); // Remove indentation
Logger.log(‘Second list item outdented.’);
} else {
Logger.log(‘Not enough list items or no indented item to outdent.’);
}
}
4.35. Change List Glyph Type (e.g., from Bullet to Square)
What it achieves: Changes the visual marker for a bulleted list item.
function changeListGlyph() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendListItem(‘Item with square bullet’).setGlyphType(DocumentApp.GlyphType.SQUARE);
Logger.log(‘New list item with square bullet created.’);
}
5. Tables
Scripts for creating, manipulating, and populating tables.
5.36. Create a Simple Table
What it achieves: Inserts a new table with specified rows and columns into the document.
function createSimpleTable() {
const body = DocumentApp.getActiveDocument().getBody();
const table = body.appendTable([
[‘Header 1’, ‘Header 2’],
[‘Row 1, Col 1’, ‘Row 1, Col 2’],
[‘Row 2, Col 1’, ‘Row 2, Col 2’]
]);
Logger.log(‘Simple table created.’);
}
5.37. Get a Specific Table Cell Content
What it achieves: Retrieves the text from a cell at a given row and column index.
function getTableCellContent() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
const cell = table.getCell(1, 0); // Row 1, Column 0 (second row, first column)
Logger.log(‘Content of cell (1,0): ‘ + cell.getText());
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.38. Set a Specific Table Cell Content
What it achieves: Updates the text content of a specific table cell.
function setTableCellContent() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
const cell = table.getCell(0, 0); // Row 0, Column 0 (first row, first column)
cell.setText(‘Updated Header 1’);
Logger.log(‘Cell (0,0) content updated.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.39. Add a New Row to a Table
What it achieves: Inserts a new row at the end of an existing table.
function addRowToTable() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
table.appendTableRow([‘New Row Col 1’, ‘New Row Col 2’]);
Logger.log(‘New row added to table.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.40. Add a New Column to a Table
What it achieves: Inserts a new column into an existing table. This requires iterating through rows.
function addColumnToTable() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
const numRows = table.getNumRows();
for (let i = 0; i < numRows; i++) {
const row = table.getRow(i);
row.appendTableCell(‘New Column Data’);
}
Logger.log(‘New column added to table.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.41. Delete a Row from a Table
What it achieves: Removes a specific row from a table.
function deleteRowFromTable() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
if (table.getNumRows() > 1) { // Ensure there’s more than one row to delete
table.removeRow(1); // Remove the second row (index 1)
Logger.log(‘Second row deleted from table.’);
} else {
Logger.log(‘Table has only one row, cannot delete.’);
}
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.42. Set Table Border (Width, Color)
What it achieves: Sets the width and color of the table borders.
function setTableBorder() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
table.setBorderWidth(1); // 1 point width
table.setBorderColor(‘#0000FF’); // Blue color
Logger.log(‘Table border set to 1pt blue.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.43. Merge Table Cells
What it achieves: Merges a range of cells into a single cell.
function mergeTableCells() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
// Merge cells from (0,0) to (0,1) – first row, first two columns
table.mergeCells(0, 0, 0, 1); // startRow, startCol, endRow, endCol
Logger.log(‘Cells (0,0) and (0,1) merged.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.44. Unmerge Table Cells
What it achieves: Unmerges previously merged cells.
function unmergeTableCells() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
// This assumes cells (0,0) and (0,1) were previously merged
// You need to know the original structure or check if it’s merged
// For demonstration, let’s assume a merged cell exists at (0,0)
try {
table.getCell(0, 0).asTableCell().unmerge();
Logger.log(‘Cell (0,0) unmerged.’);
} catch (e) {
Logger.log(‘Could not unmerge cell (0,0). It might not be a merged cell or an error occurred: ‘ + e.message);
}
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
5.45. Set Cell Background Color
What it achieves: Changes the background color of a specific table cell.
function setCellBackgroundColor() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
if (tables.length > 0) {
const table = tables[0];
const cell = table.getCell(0, 0);
cell.setBackgroundColor(‘#ADD8E6’); // Light blue
Logger.log(‘Cell (0,0) background color set to light blue.’);
} else {
Logger.log(‘No tables found. Please run createSimpleTable first.’);
}
}
6. Images & Drawings
Scripts for inserting and manipulating images and drawings.
6.46. Insert an Image by URL
What it achieves: Inserts an image into the document using its public URL.
function insertImageFromUrl() {
const body = DocumentApp.getActiveDocument().getBody();
const imageUrl = ‘https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png’; // Example Google logo
try {
const image = UrlFetchApp.fetch(imageUrl).getBlob();
body.appendImage(image);
Logger.log(‘Image inserted from URL.’);
} catch (e) {
Logger.log(‘Error inserting image: ‘ + e.message + ‘. Ensure the URL is valid and publicly accessible.’);
}
}
6.47. Insert an Image from Google Drive by ID
What it achieves: Inserts an image that is already stored in your Google Drive.
function insertImageFromDrive() {
const body = DocumentApp.getActiveDocument().getBody();
const imageFileId = ‘YOUR_IMAGE_FILE_ID_HERE’; // Replace with your image file ID from Drive
try {
const imageBlob = DriveApp.getFileById(imageFileId).getBlob();
body.appendImage(imageBlob);
Logger.log(‘Image inserted from Google Drive.’);
} catch (e) {
Logger.log(‘Error inserting image from Drive: ‘ + e.message + ‘. Ensure the ID is correct and you have permission.’);
}
}
6.48. Set Image Width and Height
What it achieves: Resizes an image within the document.
function setImageSize() {
const body = DocumentApp.getActiveDocument().getBody();
const images = body.getImages();
if (images.length > 0) {
const image = images[0];
image.setWidth(150).setHeight(50); // Set width to 150px, height to 50px
Logger.log(‘First image resized.’);
} else {
Logger.log(‘No images found to resize. Please insert an image first.’);
}
}
6.49. Delete an Image
What it achieves: Removes an image from the document.
function deleteImage() {
const body = DocumentApp.getActiveDocument().getBody();
const images = body.getImages();
if (images.length > 0) {
images[0].removeFromParent();
Logger.log(‘First image deleted.’);
} else {
Logger.log(‘No images found to delete.’);
}
}
6.50. Insert a Drawing (Placeholder)
What it achieves: While Apps Script doesn’t directly create complex drawings, it can insert a placeholder for a drawing or interact with existing ones. This example shows how to add a simple paragraph to represent where a drawing might go. Direct drawing manipulation is limited.
function insertDrawingPlaceholder() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendParagraph(‘— [Drawing Placeholder] —‘);
Logger.log(‘Drawing placeholder added.’);
}
7. Hyperlinks & Bookmarks
Scripts for managing links and internal document navigation.
7.51. Insert a Hyperlink
What it achieves: Inserts text that acts as a clickable link to a URL.
function insertHyperlink() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraph = body.appendParagraph(‘Visit Google’);
paragraph.setLinkUrl(‘https://www.google.com’);
Logger.log(‘Hyperlink inserted.’);
}
7.52. Get Hyperlink URL from Text
What it achieves: Retrieves the URL associated with a piece of linked text.
function getHyperlinkUrl() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const paragraph = paragraphs[0];
const linkUrl = paragraph.getLinkUrl();
if (linkUrl) {
Logger.log(‘Link URL of first paragraph: ‘ + linkUrl);
} else {
Logger.log(‘First paragraph does not contain a hyperlink.’);
}
} else {
Logger.log(‘No paragraphs found.’);
}
}
7.53. Remove a Hyperlink
What it achieves: Removes the link functionality from text, leaving the text itself.
function removeHyperlink() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const paragraph = paragraphs[0];
if (paragraph.getLinkUrl()) {
paragraph.setLinkUrl(null); // Setting URL to null removes the link
Logger.log(‘Hyperlink removed from first paragraph.’);
} else {
Logger.log(‘First paragraph does not have a hyperlink to remove.’);
}
} else {
Logger.log(‘No paragraphs found.’);
}
}
7.54. Create a Bookmark
What it achieves: Adds a named bookmark at the current cursor position or at the end of the document.
function createBookmark() {
const doc = DocumentApp.getActiveDocument();
const cursor = doc.getCursor();
if (cursor) {
const bookmark = doc.addBookmark(cursor);
Logger.log(‘Bookmark created at cursor position with ID: ‘ + bookmark.getId());
} else {
// If no cursor, add at the end of the document
const body = doc.getBody();
body.appendParagraph(‘Bookmark Target’);
const bookmark = doc.addBookmark(body.getChild(body.getNumChildren() – 1).asParagraph().editAsText().getRange());
Logger.log(‘Bookmark created at end of document with ID: ‘ + bookmark.getId());
}
}
7.55. Get All Bookmarks
What it achieves: Lists all bookmarks present in the document.
function getAllBookmarks() {
const doc = DocumentApp.getActiveDocument();
const bookmarks = doc.getBookmarks();
if (bookmarks.length > 0) {
Logger.log(‘Bookmarks in document:’);
bookmarks.forEach((bookmark, index) => {
Logger.log(`- Bookmark ${index + 1} (ID: ${bookmark.getId()})`);
});
} else {
Logger.log(‘No bookmarks found in this document.’);
}
}
8. Headers, Footers & Page Breaks
Scripts for managing document sections, page breaks, and recurring content in headers/footers.
8.56. Add a Header
What it achieves: Adds text to the document’s header section.
function addHeaderContent() {
const header = DocumentApp.getActiveDocument().getHeader();
if (header) {
header.clear(); // Clear existing header content
header.appendParagraph(‘Document Header – ‘ + new Date().toLocaleDateString());
Logger.log(‘Header content updated.’);
} else {
Logger.log(‘No header section found or created by default. You might need to manually add one first.’);
}
}
8.57. Add a Footer
What it achieves: Adds text to the document’s footer section.
function addFooterContent() {
const footer = DocumentApp.getActiveDocument().getFooter();
if (footer) {
footer.clear(); // Clear existing footer content
footer.appendParagraph(‘Page ‘ + DocumentApp.PageNumberType.PAGE_NUMBER); // Example: Add page number
Logger.log(‘Footer content updated with page number.’);
} else {
Logger.log(‘No footer section found or created by default. You might need to manually add one first.’);
}
}
8.58. Insert a Page Break
What it achieves: Inserts a new page break at the current cursor position or at the end of the document.
function insertPageBreak() {
const doc = DocumentApp.getActiveDocument();
const cursor = doc.getCursor();
if (cursor) {
cursor.insertPageBreak();
Logger.log(‘Page break inserted at cursor.’);
} else {
doc.getBody().appendPageBreak();
Logger.log(‘Page break inserted at end of document.’);
}
}
8.59. Insert a Section Break (Next Page)
What it achieves: Inserts a section break that starts the new section on the next page. This allows for different page formatting (e.g., headers/footers) in different sections.
function insertSectionBreakNextPage() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendPageBreak().asPageBreak().setPageBreakType(DocumentApp.PageBreakType.SECTION_BREAK_NEW_PAGE);
Logger.log(‘Section break (next page) inserted.’);
}
8.60. Get Page Number (using footer example)
What it achieves: Demonstrates how to insert dynamic page numbers into the footer. (This is typically done by setting the PageNumberType property of a footer paragraph, as shown in 8.57).
function addPageNumberToFooter() {
const footer = DocumentApp.getActiveDocument().getFooter();
if (footer) {
footer.clear();
const paragraph = footer.appendParagraph(‘Page ‘);
paragraph.appendPageNumber(DocumentApp.PageNumberType.PAGE_NUMBER);
Logger.log(‘Page number added to footer.’);
} else {
Logger.log(‘No footer found. Add one manually first.’);
}
}
9. Comments & Suggestions
Scripts for adding, resolving, and interacting with comments and suggestions.
9.61. Add a Comment to a Text Range
What it achieves: Adds a comment to a specific selection of text.
function addCommentToText() {
const doc = DocumentApp.getActiveDocument();
const body = doc.getBody();
// Ensure some text exists to comment on
if (body.getText().length < 10) {
body.appendParagraph(‘This is some text that will receive a comment.’);
}
const range = doc.newRange().select(body.getChild(0).asParagraph().editAsText().getRange(0, 5)).build(); // Select first 5 chars of first paragraph
doc.addComment(‘This is a new comment from the script.’, range);
Logger.log(‘Comment added to the first 5 characters of the first paragraph.’);
}
9.62. Resolve a Comment
What it achieves: Marks an existing comment as resolved.
function resolveComment() {
const doc = DocumentApp.getActiveDocument();
const comments = doc.getComments();
if (comments.length > 0) {
comments[0].setResolved(true);
Logger.log(‘First comment resolved.’);
} else {
Logger.log(‘No comments found to resolve. Please add one first.’);
}
}
9.63. Reopen a Resolved Comment
What it achieves: Changes a resolved comment back to an open state.
function reopenComment() {
const doc = DocumentApp.getActiveDocument();
const comments = doc.getComments();
if (comments.length > 0) {
comments[0].setResolved(false);
Logger.log(‘First comment reopened.’);
} else {
Logger.log(‘No comments found to reopen. Please add one first.’);
}
}
9.64. Get All Open Comments
What it achieves: Retrieves a list of all unresolved comments in the document.
function getOpenComments() {
const doc = DocumentApp.getActiveDocument();
const comments = doc.getComments();
const openComments = comments.filter(comment => !comment.isResolved());
if (openComments.length > 0) {
Logger.log(‘Open Comments:’);
openComments.forEach((comment, index) => {
Logger.log(`- Comment ${index + 1}: ${comment.getText()}`);
});
} else {
Logger.log(‘No open comments found.’);
}
}
9.65. Add a Suggestion (Not directly supported as a separate object)
What it achieves: Apps Script doesn’t have a direct addSuggestion method like addComment. Suggestions are part of the “Suggesting” editing mode. To simulate, you would typically add a comment and instruct the user to use suggesting mode. This example adds a regular comment as the closest programmatic equivalent.
function addSuggestionComment() {
const doc = DocumentApp.getActiveDocument();
const body = doc.getBody();
if (body.getText().length < 10) {
body.appendParagraph(‘Text for a suggested change.’);
}
const range = doc.newRange().select(body.getChild(0).asParagraph().editAsText().getRange(0, 4)).build();
doc.addComment(‘Consider changing “Text” to “Content”.’, range);
Logger.log(‘Comment added for a “suggestion”. User needs to be in Suggesting mode to apply.’);
}
10. Document Properties & Information
Scripts for accessing and modifying metadata about the document itself.
10.66. Get Document Name
What it achieves: Retrieves the title of the active document.
function getDocName() {
const doc = DocumentApp.getActiveDocument();
Logger.log(‘Document Name: ‘ + doc.getName());
}
10.67. Get Document ID
What it achieves: Retrieves the unique identifier of the active document.
function getDocId() {
const doc = DocumentApp.getActiveDocument();
Logger.log(‘Document ID: ‘ + doc.getId());
}
10.68. Get Document URL
What it achieves: Retrieves the web URL of the active document.
function getDocUrl() {
const doc = DocumentApp.getActiveDocument();
Logger.log(‘Document URL: ‘ + doc.getUrl());
}
10.69. Get Document Owner
What it achieves: Retrieves the email address of the document owner.
function getDocOwner() {
const doc = DocumentApp.getActiveDocument();
const owner = doc.getOwner();
if (owner) {
Logger.log(‘Document Owner: ‘ + owner.getEmail());
} else {
Logger.log(‘Could not determine document owner.’);
}
}
10.70. Get Last Updated Time
What it achieves: Retrieves the timestamp of the last modification to the document.
function getLastUpdatedTime() {
const doc = DocumentApp.getActiveDocument();
const lastUpdated = doc.getLastUpdated();
Logger.log(‘Last Updated: ‘ + lastUpdated.toLocaleString());
}
11. Search & Replace
Scripts for finding and replacing text within the document.
11.71. Simple Search and Replace (First Occurrence)
What it achieves: Finds the first occurrence of a string and replaces it.
function simpleSearchReplace() {
const body = DocumentApp.getActiveDocument().getBody();
const foundElement = body.findText(‘old text’);
if (foundElement) {
foundElement.getElement().asText().setText(‘new text’);
Logger.log(‘First occurrence of “old text” replaced with “new text”.’);
} else {
Logger.log(‘”old text” not found.’);
}
}
11.72. Global Search and Replace (All Occurrences)
What it achieves: Finds all occurrences of a string and replaces them.
function globalSearchReplace() {
const body = DocumentApp.getActiveDocument().getBody();
let foundElement = body.findText(‘search_term’);
let count = 0;
while (foundElement) {
foundElement.getElement().asText().setText(‘replacement_text’);
count++;
foundElement = body.findText(‘search_term’); // Find next after replacement
}
Logger.log(`Replaced “search_term” with “replacement_text” ${count} times.`);
}
11.73. Search and Replace with Regular Expressions
What it achieves: Uses regular expressions for more complex search patterns.
function regexSearchReplace() {
const body = DocumentApp.getActiveDocument().getBody();
// Example: Replace all numbers with ‘NUMBER’
let foundElement = body.findText(‘\\d+’); // Regex to find one or more digits
let count = 0;
while (foundElement) {
foundElement.getElement().asText().setText(‘NUMBER’);
count++;
foundElement = body.findText(‘\\d+’);
}
Logger.log(`Replaced numbers with “NUMBER” ${count} times.`);
}
11.74. Get All Occurrences of a Word
What it achieves: Finds and logs the text of all elements containing a specific word.
function getAllOccurrences() {
const body = DocumentApp.getActiveDocument().getBody();
const searchTerm = ‘example’;
const foundElements = body.findAll(searchTerm);
if (foundElements.length > 0) {
Logger.log(`Found “${searchTerm}” in the following elements:`);
foundElements.forEach((element, index) => {
Logger.log(`- Match ${index + 1}: ${element.getElement().getText().substring(0, 100)}…`);
});
} else {
Logger.log(`”${searchTerm}” not found.`);
}
}
11.75. Replace Text in a Specific Paragraph
What it achieves: Limits search and replace to a single paragraph.
function replaceInSpecificParagraph() {
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
if (paragraphs.length > 0) {
const targetParagraph = paragraphs[0];
const originalText = targetParagraph.getText();
const newText = originalText.replace(/old/g, ‘new’); // Replace all ‘old’ with ‘new’
targetParagraph.setText(newText);
Logger.log(‘Replaced “old” with “new” in the first paragraph.’);
} else {
Logger.log(‘No paragraphs found.’);
}
}
12. Content Extraction
Scripts for pulling out specific types of content from the document.
12.76. Get All Document Text
What it achieves: Extracts all visible text content from the document.
function getAllDocumentText() {
const body = DocumentApp.getActiveDocument().getBody();
const fullText = body.getText();
Logger.log(‘Full Document Text (first 500 chars): \n’ + fullText.substring(0, 500) + ‘…’);
}
12.77. Get All Tables as Data (Array of Arrays)
What it achieves: Extracts data from all tables in the document into a JavaScript array of arrays.
function getTablesAsData() {
const body = DocumentApp.getActiveDocument().getBody();
const tables = body.getTables();
const allTableData = [];
tables.forEach((table, tableIndex) => {
const tableData = [];
const numRows = table.getNumRows();
for (let i = 0; i < numRows; i++) {
const row = table.getRow(i);
const rowData = [];
const numCells = row.getNumCells();
for (let j = 0; j < numCells; j++) {
rowData.push(row.getCell(j).getText());
}
tableData.push(rowData);
}
allTableData.push({ tableIndex: tableIndex, data: tableData });
Logger.log(`Table ${tableIndex + 1} Data: ${JSON.stringify(tableData)}`);
});
if (tables.length === 0) {
Logger.log(‘No tables found in the document.’);
}
return allTableData;
}
12.78. Get All Images (URLs or IDs if from Drive)
What it achieves: Lists information about all images in the document.
function getAllImagesInfo() {
const body = DocumentApp.getActiveDocument().getBody();
const images = body.getImages();
if (images.length > 0) {
Logger.log(‘Images in document:’);
images.forEach((image, index) => {
Logger.log(`- Image ${index + 1}:`);
Logger.log(` Width: ${image.getWidth()}, Height: ${image.getHeight()}`);
// Note: Apps Script doesn’t directly expose the original URL for inserted images.
// If inserted from Drive, you might be able to infer the ID if you stored it.
// For images, you typically get a Blob.
});
} else {
Logger.log(‘No images found.’);
}
}
12.79. Extract Specific Section by Heading
What it achieves: Extracts text content between two specific headings.
function extractSectionByHeading() {
const body = DocumentApp.getActiveDocument().getBody();
const elements = body.getNumChildren();
let inSection = false;
let sectionContent = [];
const startHeadingText = ‘Introduction’; // Replace with your start heading
const endHeadingText = ‘Conclusion’; // Replace with your end heading
for (let i = 0; i < elements; i++) {
const element = body.getChild(i);
if (element.getType() === DocumentApp.ElementType.PARAGRAPH) {
const paragraph = element.asParagraph();
const text = paragraph.getText().trim();
const heading = paragraph.getHeading();
if (text === startHeadingText && heading !== DocumentApp.ParagraphHeading.NORMAL) {
inSection = true;
continue; // Don’t include the start heading itself
}
if (text === endHeadingText && heading !== DocumentApp.ParagraphHeading.NORMAL) {
inSection = false;
break; // Stop after finding the end heading
}
if (inSection) {
sectionContent.push(text);
}
}
}
if (sectionContent.length > 0) {
Logger.log(`Content between “${startHeadingText}” and “${endHeadingText}”:`);
Logger.log(sectionContent.join(‘\n’));
} else {
Logger.log(‘Section not found or empty.’);
}
}
12.80. Get Number of Words in Document
What it achieves: Counts the total number of words in the document.
function getWordCount() {
const body = DocumentApp.getActiveDocument().getBody();
const text = body.getText();
// Simple word count: split by whitespace and filter out empty strings
const words = text.split(/\s+/).filter(word => word.length > 0);
Logger.log(‘Word Count: ‘ + words.length);
}
13. Sharing & Permissions
Scripts for managing who can access and edit your document.
13.81. Share Document with Editor Permissions
What it achieves: Grants editing access to a specific email address.
function shareAsEditor() {
const doc = DocumentApp.getActiveDocument();
const email = ‘user@example.com’; // Replace with the email address
doc.addEditor(email);
Logger.log(`Document shared with ${email} as editor.`);
}
13.82. Share Document with Viewer Permissions
What it achieves: Grants viewing access to a specific email address.
function shareAsViewer() {
const doc = DocumentApp.getActiveDocument();
const email = ‘user@example.com’; // Replace with the email address
doc.addViewer(email);
Logger.log(`Document shared with ${email} as viewer.`);
}
13.83. Remove Permissions for a User
What it achieves: Revokes access for a specific user.
function removeUserPermissions() {
const doc = DocumentApp.getActiveDocument();
const email = ‘user@example.com’; // Replace with the email address
const users = doc.getEditors().concat(doc.getViewers());
users.forEach(user => {
if (user.getEmail() === email) {
doc.removeEditor(user); // Try removing as editor
doc.removeViewer(user); // Try removing as viewer
Logger.log(`Permissions removed for ${email}.`);
return;
}
});
Logger.log(`No active permissions found for ${email} to remove.`);
}
13.84. Make Document Public (Anyone with Link can View)
What it achieves: Changes the document’s sharing settings so anyone with the link can view it.
function makePublicViewable() {
const doc = DocumentApp.getActiveDocument();
doc.setSharing(DocumentApp.Access.ANYONE_WITH_LINK, DocumentApp.Permission.VIEW);
Logger.log(‘Document sharing set to “Anyone with the link can view”.’);
}
13.85. Make Document Private (Only Specific Users)
What it achieves: Changes the document’s sharing settings back to private, meaning only explicitly added users can access it.
function makePrivate() {
const doc = DocumentApp.getActiveDocument();
doc.setSharing(DocumentApp.Access.PRIVATE, DocumentApp.Permission.NONE);
Logger.log(‘Document sharing set to “Private”.’);
}
14. Custom Menus & UI
Scripts for adding custom menu items to the Google Docs interface.
14.86. Add a Simple Custom Menu
What it achieves: Creates a new top-level menu in the Docs UI with a single item that runs a function.
function onOpen() {
DocumentApp.getUi()
.createMenu(‘My Custom Menu’)
.addItem(‘Run My Function’, ‘mySimpleFunction’)
.addToUi();
}
function mySimpleFunction() {
DocumentApp.getUi().alert(‘Custom Function’, ‘You clicked the custom menu item!’, DocumentApp.getUi().ButtonSet.OK);
}
To run this, save the script, close the document, and reopen it. A new menu “My Custom Menu” will appear.
14.87. Add a Sub-Menu
What it achieves: Creates a menu with nested sub-menus for better organization.
function onOpen() {
DocumentApp.getUi()
.createMenu(‘Docs Tools’)
.addItem(‘Show Alert’, ‘showAlert’)
.addSeparator() // Adds a horizontal line
.addSubMenu(DocumentApp.getUi().createMenu(‘Formatting’)
.addItem(‘Make Bold’, ‘makeSelectedTextBold’)
.addItem(‘Make Italic’, ‘makeSelectedTextItalic’))
.addToUi();
}
function showAlert() {
DocumentApp.getUi().alert(‘Hello’, ‘This is an alert from Docs Tools!’, DocumentApp.getUi().ButtonSet.OK);
}
function makeSelectedTextBold() {
const selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
const elements = selection.getRangeElements();
elements.forEach(element => {
if (element.isPartial()) {
element.getRange().setTextAttribute(DocumentApp.Attribute.BOLD, true);
} else {
element.getElement().asParagraph().setBold(true);
}
});
DocumentApp.getUi().alert(‘Success’, ‘Selected text made bold.’, DocumentApp.getUi().ButtonSet.OK);
} else {
DocumentApp.getUi().alert(‘Error’, ‘No text selected.’, DocumentApp.getUi().ButtonSet.OK);
}
}
function makeSelectedTextItalic() {
const selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
const elements = selection.getRangeElements();
elements.forEach(element => {
if (element.isPartial()) {
element.getRange().setTextAttribute(DocumentApp.Attribute.ITALIC, true);
} else {
element.getElement().asParagraph().setItalic(true);
}
});
DocumentApp.getUi().alert(‘Success’, ‘Selected text made italic.’, DocumentApp.getUi().ButtonSet.OK);
} else {
DocumentApp.getUi().alert(‘Error’, ‘No text selected.’, DocumentApp.getUi().ButtonSet.OK);
}
}
To run this, save the script, close the document, and reopen it.
14.88. Show a Custom Dialog (HTML Service)
What it achieves: Displays a custom HTML-based dialog window within Google Docs.
function showCustomDialog() {
const htmlOutput = HtmlService.createHtmlOutputFromFile(‘DialogPage’)
.setWidth(400)
.setHeight(300);
DocumentApp.getUi().showModalDialog(htmlOutput, ‘My Custom Dialog’);
}
// Create a new HTML file named `DialogPage.html` in the same Apps Script project:
/*
<!DOCTYPE html>
<html>
<head>
<base target=”_top”>
<style>
body { font-family: ‘Inter’, sans-serif; padding: 20px; }
h1 { color: #4285F4; }
</style>
</head>
<body>
<h1>Welcome to the Dialog!</h1>
<p>This is content from an HTML file.</p>
<button onclick=”google.script.host.close()”>Close</button>
</body>
</html>
*/
You need to create a new HTML file named DialogPage.html in your Apps Script project for this to work.
14.89. Show a Sidebar (HTML Service)
What it achieves: Opens a custom HTML-based sidebar on the right side of the Google Docs interface.
function showCustomSidebar() {
const htmlOutput = HtmlService.createHtmlOutputFromFile(‘SidebarPage’)
.setTitle(‘My Custom Sidebar’);
DocumentApp.getUi().showSidebar(htmlOutput);
}
// Create a new HTML file named `SidebarPage.html` in the same Apps Script project:
/*
<!DOCTYPE html>
<html>
<head>
<base target=”_top”>
<style>
body { font-family: ‘Inter’, sans-serif; padding: 10px; }
h2 { color: #DB4437; }
</style>
</head>
<body>
<h2>Sidebar Content</h2>
<p>You can put various tools and information here.</p>
<button onclick=”google.script.run.doSomethingInDocs()”>Do Something</button>
<script>
function doSomethingInDocs() {
google.script.run.withSuccessHandler(function() {
console.log(‘Action completed!’);
}).appendTimestamp(); // Call a server-side function
}
</script>
</body>
</html>
*/
function appendTimestamp() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendParagraph(‘Timestamp from Sidebar: ‘ + new Date().toLocaleString());
Logger.log(‘Timestamp appended from sidebar request.’);
}
You need to create a new HTML file named SidebarPage.html in your Apps Script project for this to work.
14.90. Get User Input with Prompt
What it achieves: Displays a simple input box to get text from the user.
function getUserInput() {
const ui = DocumentApp.getUi();
const response = ui.prompt(
‘Enter Text’,
‘Please enter some text:’,
ui.ButtonSet.OK_CANCEL);
if (response.getSelectedButton() === ui.Button.OK) {
const inputText = response.getResponseText();
DocumentApp.getActiveDocument().getBody().appendParagraph(‘User entered: ‘ + inputText);
Logger.log(‘User entered: ‘ + inputText);
} else {
Logger.log(‘User cancelled the input.’);
}
}
15. Triggers (Time-driven, On Open)
Scripts that run automatically based on events or time.
15.91. On Open Trigger (already used in custom menus)
What it achieves: A special function onOpen() that runs automatically when the document is opened. This is commonly used to build custom menus.
// See example 14.86 and 14.87 for implementation.
// The onOpen() function is automatically triggered by Google Docs.
15.92. Create a Time-Driven Trigger
What it achieves: Sets up a script to run automatically at a specific interval (e.g., every hour, daily).
function createDailyTrigger() {
// Delete existing triggers to avoid duplicates
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach(trigger => {
if (trigger.getHandlerFunction() === ‘dailyDocumentBackup’) {
ScriptApp.deleteTrigger(trigger);
}
});
// Create a new trigger to run daily at a specific time (e.g., between 1 AM and 2 AM)
ScriptApp.newTrigger(‘dailyDocumentBackup’)
.timeBased()
.atHour(1)
.everyDays(1)
.create();
Logger.log(‘Daily trigger for “dailyDocumentBackup” created.’);
}
function dailyDocumentBackup() {
const doc = DocumentApp.getActiveDocument();
const docName = doc.getName();
const docId = doc.getId();
// Create a copy of the document
const copyName = `${docName} – Backup ${new Date().toLocaleDateString()}`;
const copy = DriveApp.getFileById(docId).makeCopy(copyName);
Logger.log(`Document “${docName}” backed up to “${copyName}” (ID: ${copy.getId()})`);
}
You need to run createDailyTrigger() once manually to set up the trigger. The dailyDocumentBackup() function will then run automatically.
15.93. Delete All Triggers for a Script
What it achieves: Removes all programmatic triggers associated with the current Apps Script project.
function deleteAllTriggers() {
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach(trigger => {
ScriptApp.deleteTrigger(trigger);
Logger.log(‘Deleted trigger: ‘ + trigger.getHandlerFunction());
});
Logger.log(‘All triggers for this script deleted.’);
}
15.94. On Edit Trigger (Not directly for Docs, but for Sheets/Forms)
What it achieves: While onEdit is primarily for Google Sheets, it’s a common trigger concept. For Docs, changes are often captured via version history or by polling, not a direct onEdit event on content. This example shows a placeholder.
// function onEdit(e) {
// // This function is for Google Sheets.
// // Google Docs does not have a direct onEdit trigger for content changes.
// // You would typically use time-driven triggers or custom UI actions.
// Logger.log(‘onEdit trigger fired (Note: This is for Sheets, not Docs content edits).’);
// }
16. Integration with Google Sheets (Basic)
Scripts that demonstrate basic data transfer between Docs and Sheets.
16.95. Read Data from Google Sheet and Insert into Doc
What it achieves: Fetches data from a specified Google Sheet and inserts it into the active Google Doc.
function readSheetDataToDoc() {
const spreadsheetId = ‘YOUR_SPREADSHEET_ID_HERE’; // Replace with your Sheet ID
const sheetName = ‘Sheet1’; // Replace with your sheet name
const rangeName = ‘A1:B3’; // Replace with the range you want to read
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
const sheet = spreadsheet.getSheetByName(sheetName);
if (!sheet) {
Logger.log(`Sheet “${sheetName}” not found.`);
return;
}
const data = sheet.getRange(rangeName).getValues();
const body = DocumentApp.getActiveDocument().getBody();
body.appendParagraph(‘Data from Google Sheet:’);
body.appendTable(data);
Logger.log(‘Data from Sheet inserted into document.’);
} catch (e) {
Logger.log(‘Error reading from Sheet: ‘ + e.message);
}
}
16.96. Write Doc Content to Google Sheet
What it achieves: Extracts paragraphs from the Google Doc and writes them into a Google Sheet.
function writeDocContentToSheet() {
const spreadsheetId = ‘YOUR_SPREADSHEET_ID_HERE’; // Replace with your Sheet ID
const sheetName = ‘DocContent’; // Sheet to write to
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
let sheet = spreadsheet.getSheetByName(sheetName);
if (!sheet) {
sheet = spreadsheet.insertSheet(sheetName);
}
const body = DocumentApp.getActiveDocument().getBody();
const paragraphs = body.getParagraphs();
const dataToWrite = [[‘Paragraph Text’]]; // Header row
paragraphs.forEach(paragraph => {
dataToWrite.push([paragraph.getText()]);
});
sheet.clearContents(); // Clear existing content
sheet.getRange(1, 1, dataToWrite.length, dataToWrite[0].length).setValues(dataToWrite);
Logger.log(‘Document paragraphs written to Google Sheet.’);
} catch (e) {
Logger.log(‘Error writing to Sheet: ‘ + e.message);
}
}
17. Mail Merge & Templating (Simple)
Basic examples of replacing placeholders in a document.
17.97. Simple Placeholder Replacement
What it achieves: Replaces {{placeholder}} text with dynamic values.
function simpleMailMerge() {
const doc = DocumentApp.getActiveDocument();
const body = doc.getBody();
// Ensure placeholders exist in the document for testing
// body.appendParagraph(‘Dear {{Name}},’);
// body.appendParagraph(‘Your order number is {{OrderNumber}}.’);
const data = {
‘{{Name}}’: ‘John Doe’,
‘{{OrderNumber}}’: ‘12345’
};
for (const placeholder in data) {
body.replaceText(placeholder, data[placeholder]);
}
Logger.log(‘Placeholders replaced.’);
}
17.98. Generate Multiple Documents from Template
What it achieves: Creates multiple copies of a template document, each populated with different data.
function generateMultipleDocsFromTemplate() {
const templateDocId = ‘YOUR_TEMPLATE_DOC_ID_HERE’; // ID of your template document
const folderId = ‘YOUR_OUTPUT_FOLDER_ID_HERE’; // Folder where new docs will be saved
const recipientsData = [
{ name: ‘Alice’, email: ‘alice@example.com’, amount: ‘$100’ },
{ name: ‘Bob’, email: ‘bob@example.com’, amount: ‘$150’ },
{ name: ‘Charlie’, email: ‘charlie@example.com’, amount: ‘$200’ }
];
const templateFile = DriveApp.getFileById(templateDocId);
const outputFolder = DriveApp.getFolderById(folderId);
recipientsData.forEach(data => {
const newDocName = `Invoice for ${data.name}`;
const newDocFile = templateFile.makeCopy(newDocName, outputFolder);
const newDoc = DocumentApp.openById(newDocFile.getId());
const body = newDoc.getBody();
body.replaceText(‘{{Name}}’, data.name);
body.replaceText(‘{{Email}}’, data.email);
body.replaceText(‘{{Amount}}’, data.amount);
newDoc.saveAndClose();
Logger.log(`Generated document for ${data.name}: ${newDoc.getUrl()}`);
});
Logger.log(‘Finished generating documents.’);
}
You need a template document with placeholders like {{Name}}, {{Email}}, {{Amount}} and an output folder in your Drive for this to work.
18. Advanced Document Structure
Scripts for manipulating more complex document elements.
18.99. Insert a Horizontal Rule (Line)
What it achieves: Inserts a horizontal line (HR) element into the document.
function insertHorizontalRule() {
const body = DocumentApp.getActiveDocument().getBody();
body.appendHorizontalRule();
Logger.log(‘Horizontal rule inserted.’);
}
18.100. Get All Elements in Document (Iterate through types)
What it achieves: Iterates through every element in the document body and logs its type and some content. This is a powerful way to understand document structure.
function inspectDocumentElements() {
const body = DocumentApp.getActiveDocument().getBody();
const numChildren = body.getNumChildren();
Logger.log(‘Inspecting Document Elements:’);
for (let i = 0; i < numChildren; i++) {
const child = body.getChild(i);
const type = child.getType();
Logger.log(`Element ${i + 1} Type: ${type}`);
switch (type) {
case DocumentApp.ElementType.PARAGRAPH:
Logger.log(` Text: “${child.asParagraph().getText().substring(0, 50)}…”`);
break;
case DocumentApp.ElementType.TABLE:
Logger.log(` Table with ${child.asTable().getNumRows()} rows.`);
break;
case DocumentApp.ElementType.LIST_ITEM:
Logger.log(` List Item: “${child.asListItem().getText().substring(0, 50)}…”`);
break;
case DocumentApp.ElementType.IMAGE:
Logger.log(` Image (Width: ${child.asImage().getWidth()}, Height: ${child.asImage().getHeight()})`);
break;
case DocumentApp.ElementType.HORIZONTAL_RULE:
Logger.log(` Horizontal Rule`);
break;
case DocumentApp.ElementType.PAGE_BREAK:
Logger.log(` Page Break`);
break;
// Add more cases for other element types as needed
default:
Logger.log(` Unhandled Element Type: ${type}`);
break;
}
}
Logger.log(‘Document inspection complete.’);
}
