我正在使用 Google 电子表格 API 来更新包含大量数据(数百行和大约 20 列)的电子表格。
我已经测试了批量调用以更新 2500 个单元格。调用大约需要 40 秒才能完成,请求大约 1mb,响应大约 2mb。
有没有办法让它更快地工作?
我正在使用 Google 电子表格 API 来更新包含大量数据(数百行和大约 20 列)的电子表格。
我已经测试了批量调用以更新 2500 个单元格。调用大约需要 40 秒才能完成,请求大约 1mb,响应大约 2mb。
有没有办法让它更快地工作?
通过在更新之前跳过查询部分,我能够加快官方 API http://code.google.com/apis/spreadsheets/data/3.0/developers_guide.html#SendingBatchRequests中提供的批处理请求。所以这就是他们在示例中的内容:
// 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);
请注意,应更改标题以使其正常工作。
加速:由 David Tolioupov 发布 - 它有效。一些有帮助的额外信息。
如何使用 CellFeed 的示例,请参见 CellDemo.java http://gdata-java-client.googlecode.com/svn-history/r51/trunk/java/sample/spreadsheet/cell/CellDemo.java
该示例具有详细信息,足够详细,可以帮助我优化代码。
正如 David Tolioupov 所说,以这种方式创建 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,然后创建请求并发送它。
如果要更新整行,可以尝试使用基于列表的提要:
http://code.google.com/intl/fr-FR/apis/spreadsheets/data/3.0/developers_guide.html#UpdatingListRows
它将允许您更新值(不是公式)。
如果您仍然有性能问题,您应该切换到关系数据库服务器或谷歌的数据存储(如果您使用的是谷歌应用引擎)