-2
我刚刚尝试使用XSSF XLSX2CSV样本,使用SAX事件API将使用OpenCV的630k行5列电子表格导出为CSV。 完成操作需要至少70秒(尽管我最初在分析Web服务器时看到20分钟),而Excel在不到10秒的时间内完成操作。问题的将XLSX导出为CSV的最快方式
部分原因是org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler界面看起来是这样的:
/**
* You need to implement this to handle the results
* of the sheet parsing.
*/
public interface SheetContentsHandler {
/** A row with the (zero based) row number has started */
public void startRow(int rowNum);
/** A row with the (zero based) row number has ended */
public void endRow(int rowNum);
/**
* A cell, with the given formatted value (may be null),
* and possibly a comment (may be null), was encountered */
public void cell(String cellReference, String formattedValue, XSSFComment comment);
/** A header or footer has been encountered */
public void headerFooter(String text, boolean isHeader, String tagName);
}
注意你怎么只有一次一个细胞,而不是一个整体行。 我对此的解决方案是将单元格放入映射中,使用列标题作为使用endRow写入行的键。
@Override
public void endRow(int rowNum) {
if(currentRow == HEADER_ROW) {
processRow(currentRow, columnHeaders);
} else {
processRow(currentRow, currentRowMap);
}
}
private void processRow(int currentRow, LinkedHashMap<String, String> map) {
String[] nextLine = map.values().toArray(new String[map.size()]);
csvWriter.writeNext(nextLine);
}
/**
* POI will not invoke this method if the cell is blank or if it detects there's no more data in the row.
* Therefore, this is not necessarily invoked the same number of times each row.
* The startRow method has initialised the currentRowMap to work around this.
*/
@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment) {
if(currentRow == HEADER_ROW) {
columnHeaders.put(getColumnReference(cellReference), formattedValue);
} else {
String columnHeader = columnHeaders.get(getColumnReference(cellReference));
currentRowMap.put(columnHeader, formattedValue);
}
}
/**
* Returns the alphabetic column reference from this cell reference. Example: Given 'A12' returns
* 'A' or given 'BA205' returns 'BA'
*/
private static String getColumnReference(String cellReference) {
if (StringUtils.isBlank(cellReference)) {
return "";
}
return cellReference.split("[0-9]*$")[0];
}
添加并读取到此映射并获取每个单元格的列引用称为3M时间,效率非常低。
将XLSX导出到CSV有哪些更快的选项?
显然你做错了什么,但没有看到任何代码,我们不可能帮助你。此外,由于您的问题现在有了措辞(_“将XLS和XLSX导出为CSV有哪些更快的选项”),因为它要求提供外部资源建议,所以它是无关紧要的。 –
该接口需要一个单元格,因为文件格式一次存储一个单元格!至于性能,它应该只需要几秒钟就可以完成。你在用什么堆大小? – Gagravarr
我刚刚运行了一个微型基准测试,大约需要2秒才能调用3M次getColumnReference,所以我没有看到整个文件导出如何在几秒钟内完成。 – opticyclic