Как убедиться, что запрос Excel Online занимает менее 5 МБ с помощью Office JavaScript API - PullRequest
1 голос
/ 12 апреля 2020

Очевидно, что для отправки запросов в Excel Online существует ограничение в 5 МБ (см .: https://github.com/OfficeDev/office-js-docs-reference/issues/354).

Мы используем API-интерфейс Office JavaScript для записи больших объемов данных. в лист Excel, используя следующий код:

// Example rows - in our actual code this comes from an API
const rows = [
  ["Date", "Product", "Sales", "Customers"],
  ["13/03/2020", "Chocolate biscuits", 598.00, 93],
  // ... and many more
]

sheet.getRangeByIndexes(0, 0, numRows, numColumns).values = rows;

Превышение вышеуказанного предела приведет к выдаче этой ошибки: RichApi.Error: An internal error has occurred.

Число строк и столбцов неизвестно при сборке время; размер данных зависит от запросов, выполняемых пользователями надстройки.

Есть ли надежный способ гарантировать, что наш запрос не превышает лимит?

Я попытался отследить размер массивов сериализованных значений JSON и допустить некоторый коэффициент служебной информации:

Excel.run(async context => {
  const sheet = context.workbook.worksheets.add();

  // 50% of 5MB: allow 50% of overhead
  const THRESHOLD = 0.5 * (5 * 1000 * 1000);
  let bytes = 0;

  // Example rows - in our actual code this comes from an API
  const numColumns = 4;
  const rows = [
    ["Date", "Product", "Sales", "Customers"],
    ["13/03/2020", "Chocolate biscuits", 598.00, 93],
    // ... and many more
  ];

  for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
    const row = rows[rowIndex];
    sheet.getRangeByIndexes(rowIndex, 0, 1, numColumns).values = [row];
    bytes += JSON.stringify([row]).length;

    if (bytes >= THRESHOLD) {
      await context.sync();
      bytes = 0;
    }
  }

  return context.sync();
}

Даже при учете 50% накладных расходов, вызов context.sync() все еще выдавал RichApi.Error: An internal error has occurred. с некоторыми данные. Возможно, я мог бы установить что-то действительно низкое (например, 10%), но это было бы довольно неэффективно в большинстве случаев. Я надеюсь, что есть более надежный способ вычисления размера полезной нагрузки или способ запроса Office API для проверки размера ожидающего запроса.

1 Ответ

0 голосов
/ 16 апреля 2020

Размер полезной нагрузки запроса пропорционален: - количеству вызовов API - количеству объектов (например, объекту диапазона) - длине устанавливаемого значения

Таким образом, чтобы повысить эффективность скрипт, необходимо оптимизировать количество вызовов API как можно меньше. Если вызывать API Range.Values ​​для каждой строки, будет больше служебной нагрузки.

Вот пример с оптимизированными вызовами API для справки:

    const newValues = [
  ["Date", "Product", "Sales", "Customers"],
  ["13/03/2020", "Chocolate biscuits", 598.00, 93],
  // ... and many more
];

for (let rowIndex = 0; rowIndex < newValues.length;) {
  const row = newValues[rowIndex];
  var bytes = JSON.stringify([row]).length;
  var valuesToSet = [];
  valuesToSet.push(row);

  var rowCountForNextBatch = 1;
  for (; (rowIndex + rowCountForNextBatch) < newValues.length; rowCountForNextBatch++) {
    const nextRow = newValues[rowIndex + rowCountForNextBatch];
    bytes += JSON.stringify([nextRow]).length;

    if (bytes >= THRESHOLD) {
      break;
    }
    valuesToSet.push(nextRow);
  }

  console.log(valuesToSet);
  console.log(rowCountForNextBatch);
  sheet.getRangeByIndexes(rowIndex, 0, rowCountForNextBatch, numColumns).values = valuesToSet;
  await context.sync();

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