使用Apache Poi我已经将我的代码转换为将数据写入从HSSF到SXSSF的Excel电子表格,以便在编写大文件时减少内存占用。我遇到的一个问题是尝试根据
的数据调整列的大小for (int 0 = 1; i < next.getMapping().size(); i++)
{
next.getSheet().autoSizeColumn(i);
}
现在失败抱怨我的专栏没有被跟踪
我通过添加第一个
解决了这个问题((SXSSFSheet)next.getSheet()).trackAllColumnsForAutoSizing();
此行和我在最终保存之前调用的调整大小代码
workbook.write(fos);
fos.close();
workbook.dispose();
我不清楚的是
更新 所以我在[https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFSheet.html#trackAllColumnsForAutoSizing()]查看了SXSSFSheet的javadoc 它说
调整列宽以适合内容。
这个过程在大型纸张上可能相对较慢,因此应该这样做 通常每列只调用一次,在你的结尾 处理。您可以指定合并单元格的内容是否应该 被考虑或忽略。默认是忽略合并的单元格。
关于SXSSF实现的特别说明:您必须注册列 您希望使用SXSSFSheet进行跟踪 trackColumnForAutoSizing(int)或trackAllColumnsForAutoSizing()。这个 是必需的,因为计算列宽所需的行可能有 落在随机访问窗口之外并被刷新到磁盘。 即使所有行都在随机访问中,也需要跟踪列 窗口。
POI 3.14 beta 1中的新功能:使用当前单元格自动调整列数 和冲洗的行。
它没有给出关于内存缓慢的任何警告,并且它还说它考虑了所有行但我在3.15并且我不认为它正在考虑所有行。我有一些列,其中数据占用第0行中列标题的空间较小,但创建的电子表格的列宽度小于第一行中标题的宽度。
当我处理每一行并存储最宽的数据时,我可以很容易地存储数据的宽度。但是,虽然我可以使用setColumnWidth(),但如何考虑不同的字体
答案 0 :(得分:2)
由于Apache POI是开源的,因此您可以read the implementation code and see how it works!
跟踪列没有太大的内存占用影响,因为主存储每列只有一个对象:
Map<Integer, ColumnWidthPair> maxColumnWidths =
new HashMap<Integer, ColumnWidthPair>();
跟踪将会减慢行的添加速度,因为对于跟踪列中的每个单元格,POI必须计算出将单元格刷回磁盘之前的宽度。
如果您的文件是可预测的,通常最好打开所有列的跟踪,写出前10行,然后关闭跟踪到文件的末尾。这样就可以很好地猜测宽度,而无需计算每个单元格。
但是,如果您不知道哪个行将包含每个单元格的最长值,则您需要获得轻微的性能命中并跟踪整个文件中的所有列和所有行。虽然
,但太不是做得多