Обходные решения для скрипта Google App «Исключение: FILENAME.csv превышает максимальный размер файла»? - PullRequest
0 голосов
/ 26 июня 2018

Я создаю приложение Google App Maker, которое принимает загруженный пользователем файл электронной таблицы Excel CSV в качестве входных данных.Я думал о нескольких возможных решениях для чтения данных из этого файла, но я столкнулся с этой ошибкой: «Исключение: FILENAME.csv превышает максимальный размер файла» каждый раз.Я попытался извлечь данные с помощью parseCSV () в Google Cloud SQL, считав одну строку с помощью .getBlob (). GetDataAsString () и разделив ее на «\ n», записав все данные в Google Docs и пытаясь прочитатьэто оттуда.Однако все эти методы привели к одной и той же ошибке.

Есть ли обходное решение для решения этой проблемы максимального размера файла?

Я думал о разбиении файла на файлы меньшего размера CSV, но я не уверен, как это сделать.

1 Ответ

0 голосов
/ 26 июня 2018

Вы хотите преобразовать большой CSV-файл в разделенную электронную таблицу.Если мое понимание правильное, как насчет этого обходного пути?

Проблемы и обходные пути для этой ситуации:

  1. Когда такой большой CSV-файл преобразуется в электронную таблицу, он не может напрямую преобразоватьв электронную таблицу из-за общего количества ячеек и размера файла.А также, когда большой файл пытается разделить, он не может этого сделать, потому что размер большого двоичного объекта, который можно использовать на GAS, составляет менее 50 МБ (52 428 800 байт).

  2. В моей среде, когда файл CSV размером 100 МБиспользуется для этого примера сценария, когда файл разделяется на 10 МБ, для преобразования фрагмента в электронную таблицу требуется около 65 секунд.В этом случае, когда файл CSV полностью конвертируется, считается, что для выполнения ГАЗА будет превышено время ограничения (6 минут).

    • Во избежание этого требуется:реализовать возобновляемое преобразование из большого CSV-файла в несколько электронных таблиц.

Подготовка:

Чтобы использовать этот пример сценария, включите Drive API вРасширенная консоль служб Google и API.

Включение Drive API v2 в дополнительных службах Google

  • В редакторе сценариев
    • Ресурсы -> Расширенные службы Google
    • Включить Drive API v2

Включить Drive API на консоли API

  • В редакторе сценариев
    • Ресурсы -> Проект облачной платформы
    • Просмотр консоли API
    • На начальном этапе нажмите Включить API и получите учетные данные, такие как ключи.
    • С левой стороны нажмите Библиотека.
    • В поле Поиск API и сервисов введите «Диск».И нажмите Drive API.
    • Нажмите кнопку Включить.
    • Если API уже включен, пожалуйста, не выключайте.

Пример сценария:

function createSplitSpreadsheet(obj) {
  var accessToken = ScriptApp.getOAuthToken();
  var baseUrl = "https://www.googleapis.com/drive/v3/files/";

  // Retrieve file size.
  var url1 = baseUrl + obj.fileId + "?fields=size";
  var params1 = {
    method: "get",
    headers: {Authorization: "Bearer " + accessToken},
  };
  var fileSize = Number(JSON.parse(UrlFetchApp.fetch(url1, {headers: {Authorization: "Bearer " + accessToken}}).getContentText()).size);

  // Calculate number of output files.
  if (obj.files == null) {
    obj.number = 1;
    obj.start = 0;
  }
  var start = obj.start;
  var end = start + obj.chunk;
  var useFileSize = fileSize - start;
  f = Math.floor(useFileSize / obj.chunk);
  f = useFileSize % obj.chunk > 0 ? f + 1 : f;
  if (f < obj.files || obj.files == null) {
    obj.files = f;
  }

  // Split large file by chunk size (bytes).
  var url2 = baseUrl + obj.fileId + "?alt=media";
  var i;
  for (i = 0; i < obj.files; i++) {
    var params = {
      method: "get",
      headers: {
        Authorization: "Bearer " + accessToken,
        Range: "bytes=" + start + "-" + end,
      },
    };
    var res = UrlFetchApp.fetch(url2, params).getContentText();
    var e = res.lastIndexOf("\n");
    start += e + 1;
    end = start + obj.chunk;
    Drive.Files.insert(
      {mimeType: MimeType.GOOGLE_SHEETS, title: obj.fileName + (i + obj.number)},
      Utilities.newBlob(res.substr(0, e), MimeType.CSV)
    );
  }

  // Return next start value if there is a next chunk for the resume.
  if (start < fileSize) {
    return {nextStart: start, nextNumber: i + obj.number};
  } else {
    return null;
  }
}

// Please run this function.
function main() {
    var obj = {
        fileId: "#####", // File ID of the large CSV file.
        chunk: 10485760, // 10MB Please modify this for your situation.
        files: 3, // Please input the number of files you want to convert.
        start: 0,
        fileName: "sample",
        number: 1, // Counter of output files. Please input this as a next number.
    };
    var nextStart = createSplitSpreadsheet(obj);
    Logger.log(nextStart);
}

Использование:

Когда вы используете это, пожалуйста, измените obj в main() для вашей ситуации и запустите main().Пример использования следующий.

Предполагается следующее.

  • Вы хотите преобразовать файл CSV размером от 100 МБ до 10 таблиц.
  • Размер одного блока составляет 10 МБ.
  • Файл CSV обрабатывается каждым 3.

В этом примере каждый obj выглядит следующим образом.Пожалуйста, вводите каждый obj при каждом запуске.

  1. var obj = {fileId: "#####", chunk: 10485760, files: 3, start: 0, fileName: "sample", number: 1}
    • {"nextStart": ### nextStart2 ###, "nextNumber": 4} возвращается из createSplitSpreadsheet().
  2. var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart2 ###, fileName: "sample", number: 4}
    • {"nextStart": ### nextStart3 ###, "nextNumber": 7} возвращается из createSplitSpreadsheet().
  3. var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart3 ###, fileName: "sample", number: 7}
    • {"nextStart": ### nextStart4 ###, "nextNumber": 10} возвращается из createSplitSpreadsheet().
  4. var obj = {fileId: "#####", chunk: 10485760, files: 3, start: ### nextStart4 ###, fileName: "sample", number: 10}
    • null возвращается из createSplitSpreadsheet().

этим потокомИз CSV-файла создается 10 электронных таблиц размером 100 МБ.

Если null используется для files в obj, автоматически вычисляется files.Но в этом случае время ограничения на выполнение ГАЗА может закончиться.Пожалуйста, будьте осторожны.

Ссылки:

Если это не то, что вы хотите, извините.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...