Как читать файлы в Google Apps Script: Полное руководство

Введение в чтение файлов в Google Apps Script

Что такое Google Apps Script и его возможности для работы с файлами

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

Обзор доступных сервисов Google Apps Script для чтения файлов (Drive Service, Spreadsheet Service и другие)

Для чтения файлов в GAS используются следующие сервисы:

  • Drive Service: Предназначен для работы с файлами, хранящимися на Google Drive. Позволяет получать доступ к файлам по ID или имени, читать содержимое, управлять разрешениями.
  • Spreadsheet Service: Используется для работы с Google Sheets. Позволяет открывать таблицы, получать доступ к листам, читать и записывать данные в ячейки.
  • UrlFetch Service: Позволяет отправлять HTTP-запросы и получать данные из внешних источников, например, читать файлы по URL.

Необходимые разрешения для доступа к файлам в Google Apps Script

Для доступа к файлам необходимо запросить соответствующие разрешения (scopes) в манифесте скрипта (appsscript.json). Наиболее часто используемые разрешения:

  • https://www.googleapis.com/auth/drive.readonly: Разрешение на чтение файлов на Google Drive.
  • https://www.googleapis.com/auth/spreadsheets.readonly: Разрешение на чтение данных из Google Sheets.
  • https://www.googleapis.com/auth/script.external_request: Разрешение на выполнение HTTP-запросов (для UrlFetch Service).

Чтение текстовых файлов из Google Drive

Получение файла по ID или имени с использованием Drive Service

Для получения файла из Google Drive используйте DriveApp.getFileById(id) или DriveApp.getFilesByName(name). getFileById возвращает один файл, а getFilesByName – итератор файлов с указанным именем.

/**
 * Получает файл по ID.
 * @param {string} fileId ID файла.
 * @return {GoogleAppsScript.Drive.File} Файл.
 */
function getFileById(fileId: string): GoogleAppsScript.Drive.File | null {
  try {
    const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
    return file;
  } catch (e) {
    Logger.log("Файл не найден: " + e);
    return null;
  }
}

/**
 * Получает файлы по имени.
 * @param {string} fileName Имя файла.
 * @return {GoogleAppsScript.Drive.FileIterator} Итератор файлов.
 */
function getFilesByName(fileName: string): GoogleAppsScript.Drive.FileIterator {
  const files: GoogleAppsScript.Drive.FileIterator = DriveApp.getFilesByName(fileName);
  return files;
}

Чтение содержимого файла как текстовой строки (getText())

Для чтения содержимого текстового файла используйте метод getText():

/**
 * Читает содержимое текстового файла.
 * @param {GoogleAppsScript.Drive.File} file Файл.
 * @return {string} Содержимое файла.
 */
function readFileContent(file: GoogleAppsScript.Drive.File): string {
  const content: string = file.getText();
  return content;
}

Обработка ошибок при чтении файла (файл не найден, нет доступа)

При чтении файла необходимо обрабатывать возможные ошибки, например, файл не найден или нет доступа. Используйте try...catch блоки для обработки исключений:

function readFile(fileId: string): string | null {
  try {
    const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
    const content: string = file.getText();
    return content;
  } catch (e) {
    Logger.log("Ошибка при чтении файла: " + e);
    return null;
  }
}

Пример: Считывание данных из CSV-файла и их обработка

/**
 * Считывает данные из CSV-файла и возвращает массив массивов.
 * @param {string} fileId ID CSV-файла.
 * @return {string[][]} Массив данных.
 */
function readCsvData(fileId: string): string[][] | null {
  try {
    const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
    const content: string = file.getText();
    const lines: string[] = content.split("\n");
    const data: string[][] = [];

    for (const line of lines) {
      const values: string[] = line.split(",");
      data.push(values);
    }

    return data;
  } catch (e) {
    Logger.log("Ошибка при чтении CSV-файла: " + e);
    return null;
  }
}

// Пример использования:
// const csvData: string[][] | null = readCsvData("your_file_id");
// if (csvData) {
//   Logger.log(csvData);
// }

Чтение данных из Google Sheets

Открытие Google Sheet по ID или URL с использованием Spreadsheet Service

Для открытия Google Sheet используйте SpreadsheetApp.openById(id) или SpreadsheetApp.openByUrl(url).

/**
 * Открывает Google Sheet по ID.
 * @param {string} spreadsheetId ID таблицы.
 * @return {GoogleAppsScript.Spreadsheet.Spreadsheet} Таблица.
 */
function openSpreadsheetById(spreadsheetId: string): GoogleAppsScript.Spreadsheet.Spreadsheet | null {
  try {
    const spreadsheet: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.openById(spreadsheetId);
    return spreadsheet;
  } catch (e) {
    Logger.log("Таблица не найдена: " + e);
    return null;
  }
}

/**
 * Открывает Google Sheet по URL.
 * @param {string} spreadsheetUrl URL таблицы.
 * @return {GoogleAppsScript.Spreadsheet.Spreadsheet} Таблица.
 */
function openSpreadsheetByUrl(spreadsheetUrl: string): GoogleAppsScript.Spreadsheet.Spreadsheet | null {
  try {
    const spreadsheet: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
    return spreadsheet;
  } catch (e) {
    Logger.log("Таблица не найдена: " + e);
    return null;
  }
}

Получение доступа к листам в Google Sheet

Для получения доступа к листу используйте spreadsheet.getSheetByName(name) или spreadsheet.getActiveSheet().

/**
 * Получает лист по имени.
 * @param {GoogleAppsScript.Spreadsheet.Spreadsheet} spreadsheet Таблица.
 * @param {string} sheetName Имя листа.
 * @return {GoogleAppsScript.Spreadsheet.Sheet} Лист.
 */
function getSheetByName(spreadsheet: GoogleAppsScript.Spreadsheet.Spreadsheet, sheetName: string): GoogleAppsScript.Spreadsheet.Sheet | null {
  try {
    const sheet: GoogleAppsScript.Spreadsheet.Sheet = spreadsheet.getSheetByName(sheetName);
    return sheet;
  } catch (e) {
    Logger.log("Лист не найден: " + e);
    return null;
  }
}

/**
 * Получает активный лист.
 * @param {GoogleAppsScript.Spreadsheet.Spreadsheet} spreadsheet Таблица.
 * @return {GoogleAppsScript.Spreadsheet.Sheet} Лист.
 */
function getActiveSheet(spreadsheet: GoogleAppsScript.Spreadsheet.Spreadsheet): GoogleAppsScript.Spreadsheet.Sheet {
  const sheet: GoogleAppsScript.Spreadsheet.Sheet = spreadsheet.getActiveSheet();
  return sheet;
}

Чтение данных из ячеек и диапазонов (getValues(), getValue())

Для чтения данных используйте методы sheet.getValue(row, column) (для одной ячейки) и sheet.getRange(row, column, numRows, numColumns).getValues() (для диапазона).

/**
 * Читает значение из ячейки.
 * @param {GoogleAppsScript.Spreadsheet.Sheet} sheet Лист.
 * @param {number} row Номер строки.
 * @param {number} column Номер столбца.
 * @return {any} Значение ячейки.
 */
function getCellValue(sheet: GoogleAppsScript.Spreadsheet.Sheet, row: number, column: number): any {
  const value: any = sheet.getValue(row, column);
  return value;
}

/**
 * Читает значения из диапазона.
 * @param {GoogleAppsScript.Spreadsheet.Sheet} sheet Лист.
 * @param {number} row Начальный номер строки.
 * @param {number} column Начальный номер столбца.
 * @param {number} numRows Количество строк.
 * @param {number} numColumns Количество столбцов.
 * @return {any[][]} Массив значений.
 */
function getRangeValues(sheet: GoogleAppsScript.Spreadsheet.Sheet, row: number, column: number, numRows: number, numColumns: number): any[][] {
  const values: any[][] = sheet.getRange(row, column, numRows, numColumns).getValues();
  return values;
}

Пример: Чтение данных из таблицы и создание массива данных

/**
 * Читает данные из таблицы и создает массив объектов.
 * @param {string} spreadsheetId ID таблицы.
 * @param {string} sheetName Имя листа.
 * @return {object[]} Массив объектов.
 */
function readSheetData(spreadsheetId: string, sheetName: string): object[] | null {
  try {
    const spreadsheet: GoogleAppsScript.Spreadsheet.Spreadsheet | null = SpreadsheetApp.openById(spreadsheetId);
    if (!spreadsheet) return null;
    const sheet: GoogleAppsScript.Spreadsheet.Sheet | null = spreadsheet.getSheetByName(sheetName);
    if (!sheet) return null;
    const data: any[][] = sheet.getDataRange().getValues();

    const headers: string[] = data[0];
    const result: object[] = [];

    for (let i = 1; i < data.length; i++) {
      const rowData: any[] = data[i];
      const rowObject: { [key: string]: any } = {};

      for (let j = 0; j < headers.length; j++) {
        rowObject[headers[j]] = rowData[j];
      }

      result.push(rowObject);
    }

    return result;
  } catch (e) {
    Logger.log("Ошибка при чтении данных из таблицы: " + e);
    return null;
  }
}

// Пример использования:
// const sheetData: object[] | null = readSheetData("your_spreadsheet_id", "Sheet1");
// if (sheetData) {
//   Logger.log(sheetData);
// }

Чтение бинарных файлов (изображения, PDF и т.д.)

Получение файла как Blob (getBlob())

Для чтения бинарных файлов необходимо получить файл как Blob. Blob (Binary Large Object) представляет собой массив байтов.

/**
 * Получает файл как Blob.
 * @param {GoogleAppsScript.Drive.File} file Файл.
 * @return {GoogleAppsScript.Base.Blob} Blob.
 */
function getFileBlob(file: GoogleAppsScript.Drive.File): GoogleAppsScript.Base.Blob {
  const blob: GoogleAppsScript.Base.Blob = file.getBlob();
  return blob;
}

Работа с MIME-типами (getContentType())

MIME-тип указывает тип данных, содержащихся в файле (например, image/jpeg, application/pdf). Используйте blob.getContentType() для получения MIME-типа.

/**
 * Получает MIME-тип Blob.
 * @param {GoogleAppsScript.Base.Blob} blob Blob.
 * @return {string} MIME-тип.
 */
function getBlobContentType(blob: GoogleAppsScript.Base.Blob): string {
  const contentType: string = blob.getContentType();
  return contentType;
}

Сохранение или передача бинарных данных

Blob можно сохранить на Google Drive, отправить по электронной почте или передать в другую систему.

Пример: Чтение изображения и отправка его по электронной почте

/**
 * Читает изображение и отправляет его по электронной почте.
 * @param {string} fileId ID файла изображения.
 * @param {string} recipient Email получателя.
 */
function sendImageByEmail(fileId: string, recipient: string): void {
  try {
    const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
    const blob: GoogleAppsScript.Base.Blob = file.getBlob();

    MailApp.sendEmail({
      to: recipient,
      subject: "Изображение",
      body: "В приложении изображение.",
      attachments: [blob]
    });

    Logger.log("Email отправлен.");
  } catch (e) {
    Logger.log("Ошибка при отправке email: " + e);
  }
}

// Пример использования:
// sendImageByEmail("your_image_file_id", "recipient@example.com");

Продвинутые техники и оптимизация

Чтение больших файлов: Chunking и потоковая обработка (если применимо)

Для больших файлов рекомендуется использовать chunking. К сожалению, в GAS отсутствует полноценная потоковая обработка в традиционном понимании. Однако, можно реализовать подобие chunking, считывая файл небольшими частями и обрабатывая их последовательно, если это позволяет формат файла. Например, при чтении больших текстовых файлов, можно считывать построчно и обрабатывать каждую строку.

Асинхронное чтение файлов (если применимо)

GAS не поддерживает асинхронное чтение файлов напрямую. Однако, можно использовать LockService для предотвращения конфликтов при параллельном доступе к файлам из нескольких скриптов.

Обработка кодировок текста при чтении файлов

При чтении текстовых файлов важно учитывать кодировку. По умолчанию GAS использует UTF-8. Если файл имеет другую кодировку, необходимо преобразовать его в UTF-8 после чтения. Это можно сделать с использованием внешних библиотек или API, если это необходимо, однако, GAS нативно не предоставляет инструментов для работы с различными кодировками напрямую.

Советы по оптимизации скорости чтения файлов

  • Используйте ID файлов вместо имен. Получение файла по ID работает быстрее, чем по имени.
  • Избегайте многократного обращения к Drive Service. Старайтесь получить все необходимые данные за один запрос.
  • Оптимизируйте обработку данных. Используйте эффективные алгоритмы и структуры данных для обработки прочитанных данных.

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