Google Apps Script: Как создать документ из шаблона?

Что такое Google Apps Script и его возможности для автоматизации Google Docs

Google Apps Script (GAS) — это облачная платформа для разработки скриптов, основанная на JavaScript, которая позволяет расширять функциональность приложений Google Workspace, включая Google Docs. С помощью GAS можно автоматизировать рутинные задачи, создавать кастомные функции, интегрировать различные сервисы Google и сторонние API.

В контексте Google Docs, Apps Script предоставляет мощные инструменты для манипулирования документами: создание, чтение, редактирование содержимого, форматирование текста, работа с таблицами, изображениями и другими элементами документа. Это открывает широкие возможности для автоматизации документооборота.

Преимущества использования шаблонов для создания документов

Использование шаблонов значительно ускоряет и стандартизирует процесс создания однотипных документов, таких как договоры, отчеты, коммерческие предложения, письма и т.д. Основные преимущества:

  • Консистентность: Гарантирует единообразие структуры, форматирования и стиля всех создаваемых документов.
  • Эффективность: Сокращает время на создание документов, исключая необходимость копирования и ручной правки.
  • Снижение ошибок: Минимизирует вероятность опечаток и пропуска данных при ручном заполнении.
  • Масштабируемость: Позволяет легко генерировать большое количество документов на основе структурированных данных.

Необходимые условия и подготовка к работе

Для работы с Google Apps Script и создания документов из шаблонов вам потребуется:

  • Аккаунт Google.
  • Базовое понимание JavaScript и принципов работы Google Apps Script.
  • Доступ к Google Drive и Google Docs.
  • Подготовленный шаблон документа Google Docs.
  • Источник данных (например, Google Sheets, база данных, JSON-файл) для заполнения шаблона.

Создание и настройка шаблона документа в Google Docs

Создание шаблона Google Docs с переменными (placeholder’ами)

Шаблон представляет собой обычный документ Google Docs, в котором места для вставки динамических данных обозначены специальными метками — плейсхолдерами (placeholder). Обычно их заключают в двойные фигурные скобки, например: {{client_name}}, {{report_date}}, {{campaign_id}}.

Создайте новый документ Google Docs, оформите его согласно требуемой структуре и стилю. В местах, куда будут подставляться данные из скрипта, вставьте соответствующие плейсхолдеры. Важно, чтобы имена плейсхолдеров были уникальными и легко идентифицируемыми.

Использование тегов и переменных для динамической подстановки данных

Плейсхолдеры ({{variable_name}}) служат тегами, которые скрипт будет находить и заменять реальными данными. Имя переменной внутри скобок должно точно соответствовать ключу в объекте данных, который вы будете использовать для заполнения.

Например, если в вашем источнике данных (скажем, объекте JavaScript) есть свойство client_name: "ООО Ромашка", то плейсхолдер {{client_name}} в шаблоне будет заменен на «ООО Ромашка».

Определение структуры шаблона для оптимальной работы скрипта

Четко структурированный шаблон упрощает написание скрипта и повышает его надежность. Рекомендуется:

  • Использовать осмысленные и уникальные имена для плейсхолдеров.
  • Избегать сложного форматирования внутри самих плейсхолдеров. Форматирование должно применяться к тексту вокруг них или ко всему абзацу/разделу.
  • Для повторяющихся блоков (например, строк таблицы) предусмотреть специальные маркеры или структуру, которую скрипт сможет распознать и обработать в цикле.

Написание скрипта Google Apps Script для заполнения шаблона

Получение доступа к шаблону документа и целевому документу

Сначала необходимо получить доступ к файлу шаблона на Google Drive. Это делается с помощью сервиса DriveApp или DocumentApp, используя ID файла.

/**
 * Получает объект файла шаблона Google Docs по его ID.
 * @param {string} templateId - ID файла шаблона Google Docs.
 * @returns {GoogleAppsScript.Drive.File} Объект файла шаблона.
 * @throws {Error} Если файл с указанным ID не найден.
 */
function getTemplateFile_(templateId: string): GoogleAppsScript.Drive.File {
  try {
    const templateFile = DriveApp.getFileById(templateId);
    Logger.log(`Найден файл шаблона: ${templateFile.getName()}`);
    return templateFile;
  } catch (e) {
    Logger.log(`Ошибка получения файла шаблона с ID ${templateId}: ${e}`);
    throw new Error(`Не удалось найти шаблон документа с ID: ${templateId}`);
  }
}

Для создания нового документа на основе шаблона, мы обычно копируем файл шаблона.

Чтение данных из внешнего источника (Google Sheets, JSON, и т.д.)

Данные для заполнения могут поступать из разных источников. Рассмотрим пример чтения данных из строки Google Sheets.

/**
 * Получает данные для заполнения шаблона из указанной строки Google Sheets.
 * @param {string} spreadsheetId - ID Google Таблицы.
 * @param {string} sheetName - Имя листа.
 * @param {number} rowIndex - Номер строки для чтения данных (начиная с 1).
 * @returns {object | null} Объект с данными {ключ: значение} или null, если строка пуста.
 */
function getDataFromSheet_(spreadsheetId: string, sheetName: string, rowIndex: number): object | null {
  try {
    const ss = SpreadsheetApp.openById(spreadsheetId);
    const sheet = ss.getSheetByName(sheetName);
    if (!sheet) {
      throw new Error(`Лист с именем "${sheetName}" не найден.`);
    }

    // Предполагаем, что первая строка содержит заголовки (ключи)
    const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    const dataRow = sheet.getRange(rowIndex, 1, 1, sheet.getLastColumn()).getValues()[0];

    if (dataRow.every(cell => cell === "")) {
        Logger.log(`Строка ${rowIndex} пуста.`);
        return null; // Строка пуста
    }

    const data: {[key: string]: any} = {};
    headers.forEach((header, index) => {
      if (header) { // Учитываем только непустые заголовки
          data[header] = dataRow[index];
      }
    });
    Logger.log(`Получены данные из строки ${rowIndex}: ${JSON.stringify(data)}`);
    return data;
  } catch (e) {
    Logger.log(`Ошибка чтения данных из Google Sheets: ${e}`);
    throw e;
  }
}

Замена переменных в шаблоне на фактические данные

Основная логика заключается в итерации по данным и замене соответствующих плейсхолдеров в теле документа.

/**
 * Заменяет плейсхолдеры в теле документа на значения из объекта данных.
 * @param {GoogleAppsScript.Document.Body} body - Тело документа (или Header/Footer).
 * @param {object} data - Объект с данными {placeholder_name: value}.
 */
function replacePlaceholders_(body: GoogleAppsScript.Document.Body, data: object): void {
  for (const key in data) {
    if (data.hasOwnProperty(key)) {
      const placeholder = `{{${key}}}`;
      // Важно: getValues() может возвращать разные типы, приводим к строке
      const value = String(data[key] ?? ''); // Используем пустую строку, если значение null/undefined
      body.replaceText(placeholder, value);
      Logger.log(`Замена "${placeholder}" на "${value}"`);
    }
  }
}
Реклама

Сохранение нового документа с заполненными данными

После замены плейсхолдеров необходимо сохранить новый документ.

/**
 * Создает документ из шаблона, заполняет его данными и сохраняет.
 * @param {string} templateId - ID файла шаблона.
 * @param {string} targetFolderId - ID папки для сохранения нового документа.
 * @param {string} newFileName - Имя нового файла.
 * @param {object} data - Объект с данными для заполнения.
 * @returns {string} ID созданного документа.
 */
function createDocumentFromTemplate(templateId: string, targetFolderId: string, newFileName: string, data: object): string {
  try {
    const templateFile = getTemplateFile_(templateId);
    const targetFolder = DriveApp.getFolderById(targetFolderId);

    // Создаем копию шаблона
    const newFile = templateFile.makeCopy(newFileName, targetFolder);
    const newDocId = newFile.getId();
    Logger.log(`Создана копия шаблона: ${newFileName} (ID: ${newDocId})`);

    // Открываем копию как документ и заменяем плейсхолдеры
    const doc = DocumentApp.openById(newDocId);
    const body = doc.getBody();
    const header = doc.getHeader();
    const footer = doc.getFooter();

    replacePlaceholders_(body, data);
    if (header) {
        replacePlaceholders_(header, data);
    }
    if (footer) {
        replacePlaceholders_(footer, data);
    }

    // Сохраняем изменения и закрываем документ
    doc.saveAndClose();
    Logger.log(`Документ "${newFileName}" успешно создан и заполнен.`);

    return newDocId;

  } catch (e) {
    Logger.log(`Ошибка создания документа из шаблона: ${e}`);
    // Здесь можно добавить логику обработки ошибок, например, отправку уведомления
    throw e;
  }
}

// Пример вызова функции
/*
function runDocumentCreation() {
  const TEMPLATE_ID = "YOUR_TEMPLATE_ID_HERE";
  const TARGET_FOLDER_ID = "YOUR_FOLDER_ID_HERE";
  const SPREADSHEET_ID = "YOUR_SPREADSHEET_ID_HERE";
  const SHEET_NAME = "Лист1";
  const ROW_INDEX = 2; // Обрабатываем данные из второй строки

  try {
    const clientData = getDataFromSheet_(SPREADSHEET_ID, SHEET_NAME, ROW_INDEX);
    if (clientData && clientData['client_name']) { // Проверяем наличие данных и ключевого поля
      const reportDate = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
      const fileName = `Отчет для ${clientData['client_name']} от ${reportDate}.docx`;

      // Добавляем динамические данные, не хранящиеся в таблице
      clientData['report_date'] = reportDate;

      const newDocId = createDocumentFromTemplate(TEMPLATE_ID, TARGET_FOLDER_ID, fileName, clientData);
      Logger.log(`Создан документ с ID: ${newDocId}`);
    } else {
      Logger.log(`Нет данных для обработки в строке ${ROW_INDEX} или отсутствует client_name.`);
    }
  } catch (error) {
    Logger.log(`Не удалось выполнить runDocumentCreation: ${error}`);
  }
}
*/

Примеры использования и расширенные возможности

Автоматическое создание документов на основе данных из Google Forms

Вы можете настроить триггер onFormSubmit для скрипта, привязанного к Google Sheets, куда сохраняются ответы из Google Forms. При каждом новом ответе скрипт будет автоматически запускаться, считывать данные из последней строки и генерировать документ.

Отправка созданных документов по электронной почте

После создания документа его можно автоматически отправить по email с помощью сервиса MailApp или GmailApp. Можно прикрепить документ как PDF или отправить ссылку на него.

// ... внутри функции createDocumentFromTemplate или после ее вызова ...
// const recipientEmail = clientData['email']; 
// const subject = `Ваш отчет готов: ${newFileName}`;
// const bodyMessage = `Здравствуйте, ${clientData['client_name']},\n\nВо вложении ваш отчет от ${clientData['report_date']}.`;
// const blob = DriveApp.getFileById(newDocId).getAs(MimeType.PDF);
// GmailApp.sendEmail(recipientEmail, subject, bodyMessage, { attachments: [blob] });
// Logger.log(`Документ отправлен на ${recipientEmail}`);

Создание копий документов в определенные папки на Google Drive

Папку для сохранения можно определять динамически, например, на основе данных клиента или типа документа, используя DriveApp для навигации по папкам или их создания.

Работа с таблицами и списками в шаблонах

Заполнение таблиц или списков требует более сложной логики. Обычно это включает:

  • Нахождение таблицы/списка в шаблоне (по тексту-маркеру до или после, по индексу).
  • Клонирование строки/элемента списка-образца для каждого элемента данных.
  • Заполнение плейсхолдеров в каждой новой строке/элементе.
  • Удаление строки/элемента-образца.

Это требует более глубокого использования DocumentApp API, включая работу с элементами Table, TableRow, TableCell, ListItem.

Рекомендации и лучшие практики

Оптимизация кода для повышения производительности

  • Минимизируйте количество вызовов сервисов Google (например, DocumentApp.openById, SpreadsheetApp.openById, replaceText). Читайте данные блоками, где это возможно.
  • Используйте CacheService для кэширования часто запрашиваемых данных (например, ID шаблона или папки).
  • Избегайте многократного открытия одного и того же документа/таблицы в рамках одного выполнения скрипта.

Обработка ошибок и отладка скрипта

  • Используйте блоки try...catch для перехвата и обработки потенциальных ошибок (файл не найден, нет доступа, неверные данные).
  • Активно используйте Logger.log() или console.log() для отслеживания выполнения скрипта и значений переменных. Просматривайте логи в редакторе скриптов.
  • Тестируйте скрипт на небольших объемах данных перед запуском на больших.

Рекомендации по безопасности при работе с Google Apps Script

  • Запрашивайте только необходимые разрешения (scopes) для скрипта.
  • Будьте осторожны при работе с конфиденциальными данными. Не храните учетные данные или API-ключи напрямую в коде; используйте PropertiesService.
  • Проверяйте входящие данные перед использованием, особенно если они поступают из внешних источников (например, Google Forms).

Альтернативные подходы к созданию документов из шаблонов

Помимо написания собственных скриптов, существуют и другие решения:

  • Надстройки Google Workspace Marketplace: Множество надстроек (например, Document Studio, Autocrat) предлагают готовые интерфейсы для генерации документов из шаблонов без необходимости программирования.
  • Google Docs API: Для более сложных интеграций и контроля можно использовать Google Docs API напрямую из серверных приложений на других языках программирования.

Выбор подхода зависит от сложности задачи, требуемой гибкости и ваших навыков программирования.


Добавить комментарий