Какой самый быстрый способ обновить электронную таблицу Google с большим количеством данных через API таблицы? - PullRequest
5 голосов
/ 06 декабря 2011

Я использую Google Spreadsheet API для обновления электронной таблицы большим количеством данных (сотни строк и около двадцати столбцов).

Я протестировал выполнение пакетного вызова для обновления 2500 ячеек. Вызов занимает около 40 секунд, с запросом около 1 МБ и ответом ~ 2 МБ.

Есть ли способ заставить его работать быстрее?

Ответы [ 3 ]

11 голосов
/ 29 февраля 2012

Мне удалось ускорить пакетный запрос, предоставленный в официальном API http://code.google.com/apis/spreadsheets/data/3.0/developers_guide.html#SendingBatchRequests, пропустив часть QUERY до ОБНОВЛЕНИЯ.Итак, это то, что у них есть в примере:

// Prepare the update
    // getCellEntryMap is what makes the update fast.
    Map cellEntries = getCellEntryMap(ssSvc, cellFeedUrl, cellAddrs);

    CellFeed batchRequest = new CellFeed();
    for (CellAddress cellAddr : cellAddrs) {
      URL entryUrl = new URL(cellFeedUrl.toString() + "/" + cellAddr.idString);
      CellEntry batchEntry = new CellEntry(cellEntries.get(cellAddr.idString));
      batchEntry.changeInputValueLocal(cellAddr.idString);
      BatchUtils.setBatchId(batchEntry, cellAddr.idString);
      BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);
      batchRequest.getEntries().add(batchEntry);
    }
  // Submit the update
    Link batchLink = cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
    CellFeed batchResponse = ssSvc.batch(new URL(batchLink.getHref()), batchRequest);

, и это то, что я изменил на

CellFeed batchRequest = new CellFeed();
        for (CellInfo cellAddr : cellsInfo) {
             CellEntry batchEntry = new CellEntry(cellAddr.row, cellAddr.col, cellAddr.idString);
              batchEntry.setId(String.format("%s/%s", worksheet.getCellFeedUrl().toString(), cellAddr.idString));         
              BatchUtils.setBatchId(batchEntry, cellAddr.idString);
              BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);  
              batchRequest.getEntries().add(batchEntry);



        }

        CellFeed cellFeed = ssSvc.getFeed(worksheet.getCellFeedUrl(), CellFeed.class);      
        Link batchLink =  cellFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);

        ssSvc.setHeader("If-Match", "*");
        CellFeed batchResponse = ssSvc.batch(new URL(batchLink.getHref()), batchRequest);
        ssSvc.setHeader("If-Match", null);

Обратите внимание, заголовок должен быть изменен, чтобы он работал.

2 голосов
/ 31 января 2013

Ускорение: выложил Давид Толиупов - все работает. Некоторая дополнительная информация, которая помогла.

Пример использования CellFeed см. В CellDemo.java. http://gdata -java-client.googlecode.com / СВН-история / r51 / багажник / Java / образец / таблица / клетка / CellDemo.java

В примере есть детали, достаточно подробно, чтобы он помог мне оптимизировать мой код.

Как заявил Давид Толиупов, создайте CellEntry следующим образом:

CellEntry batchEntry = new CellEntry(cellAddr.row, cellAddr.col, cellAddr.idString);
batchEntry.setId(String.format("%s/%s", cellFeedUrl.toString(), cellAddr.idString)); 

Из примера:

/**
 * Returns a CellEntry with batch id and operation type that will tell the
 * server to update the specified cell with the given value. The entry is
 * fetched from the server in order to get the current edit link (for
 * optimistic concurrency).
 * 
 * @param row the row number of the cell to operate on
 * @param col the column number of the cell to operate on
 * @param value the value to set in case of an update the cell to operate on
 * 
 * @throws ServiceException when the request causes an error in the Google
 *         Spreadsheets service.
 * @throws IOException when an error occurs in communication with the Google
 *         Spreadsheets service.
 */
private CellEntry createUpdateOperation(int row, int col, String value)
    throws ServiceException, IOException {
  String batchId = "R" + row + "C" + col;
  URL entryUrl = new URL(cellFeedUrl.toString() + "/" + batchId);
  CellEntry entry = service.getEntry(entryUrl, CellEntry.class);
  entry.changeInputValueLocal(value);
  BatchUtils.setBatchId(entry, batchId);
  BatchUtils.setBatchOperationType(entry, BatchOperationType.UPDATE);

  return entry;
}

Все, что требуется, - это cellFeedUrl, затем создайте запрос и отправьте его.

1 голос
/ 06 декабря 2011

Если вы обновляете целые строки, вы можете попробовать работать с лентами на основе списка:

http://code.google.com/intl/fr-FR/apis/spreadsheets/data/3.0/developers_guide.html#UpdatingListRows

Это позволит вам обновить значения (не формулы).

Если у вас все еще есть проблемы с производительностью, вам следует переключиться на что-то вроде сервера реляционной базы данных или хранилища данных Google (если вы работаете с механизмом приложений Google)

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