我正在阅读一些用分隔符分隔的文本文件。
我的文本文件内容示例
Avc def efg jksjd
1 2 3 5
3 4 6 0
逐行并使用具有行号作为整数类型键的散列映射将其保存在内存中 每行文本文件为List对象
考虑一下,我的地图会存储这样的信息
整数列表
1 [Avc def efg jksjd]
我正在使用Apache POI写入excel。 使用Apache POI写入excel时,我遵循这种方法,这是我的代码片段
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Sample sheet");
Map<Integer, List<Object>> excelDataHolder = new LinkedHashMap<Integer, List<Object>>();
int rownum = 0;
for (Integer key : keyset) {
Row row = sheet.createRow(rownum++);
List<Object> objList = excelHolder.get(key);//excelHolder is my map
int cellnum = 0;
for (Object obj : objList) {
Cell cell = row.createCell(cellnum++);
cell.setCellValue((Date) obj);
}
}
如果要写入excel的行/记录数量较少,则此方法非常有效。想象一下,如果记录是十亿个数字,或者如果文本文件中有更多的行假设为10万个。我想,我的方法失败了,因为 createRow和createCell在堆中创建超过10万个对象。 无论java是excel api,我认为写入它(excel)是基于相同的方法,即如上所示的集合迭代。我也用aspose做了一些例子,因此aspose也有同样的问题。
答案 0 :(得分:3)
最新版本的apache-poi有sxssf。来自网站的无耻副本
SXSSF(包:org.apache.poi.xssf.streaming)是API兼容的 在非常大的电子表格中使用XSSF的流扩展 必须生产,堆空间有限。 SXSSF实现了低价 通过限制对a内的行的访问来限制内存占用 滑动窗口,而XSSF可以访问文档中的所有行。 不再在窗口中的旧行变得无法访问,如 它们被写入磁盘。
我用它创建了150万行的电子表格。
答案 1 :(得分:2)
我将回答Aspose.Cells for Java,因为你也尝试过。
创建或加载非常大的Excel文件几乎总是需要大容量内存。即使您一次只读取一行或多行,您仍然会将内容写入工作簿的实例,该工作簿将加载到内存中。
解决方案1(不好且非常有限):增加堆大小,如果允许的最大堆大小适用于您的最大文件,请选择它。
解决方案2(与某些手动工作相结合): Excel 2007及更高版本允许每张大约100万行。我建议你创建一个只有一张100万行的工作簿。也就是说,如果文本文件中有1000万行,则创建10个单独的Excel工作簿。
稍后,将它们手动组合到一个Excel工作簿中。在复制具有如此庞大数据的工作表时,Aspose.Cells会给出内存不足的异常。
以下是创建10个单独Excel文件的代码段,每个文件包含100万行。
import com.aspose.cells.*;
import java.util.*;
public class ExcelLargeTextImport
{
private static String excelFile = Common.dataDir + "largedata.xlsx";
public static void main(String args[])
{
try
{
Common.setLicenses();
importToExcel();
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
}
private static void importToExcel() throws Exception
{
// Process each workbook in a method
for (int sheetCounter=0 ; sheetCounter<10 ; sheetCounter++)
{
saveWorkbook(sheetCounter);
}
}
private static void saveWorkbook(int sheetCounter) throws Exception
{
Workbook workbook = new Workbook();
// Get the first sheet
Worksheet worksheet = workbook.getWorksheets().get(0);
Cells cells = worksheet.getCells();
// Initialize array list with 1 million records
ArrayList<String> lines = new ArrayList<String>();
int rowCount = 1000000;
for (int i=0 ; i<rowCount ; i++)
{
lines.add(i + ";value1;value2;value3");
}
long lineNo = 1;
for (String line : lines)
{
// Split the line by delimeter
String[] values = line.split(";");
// First cell
Cell cell = cells.get("A" + lineNo);
cell.setValue(values[0]);
// Second cell
cell = cells.get("B" + lineNo);
cell.setValue(values[1]);
// Third cell
cell = cells.get("C" + lineNo);
cell.setValue(values[2]);
// Fourth cell
cell = cells.get("D" + lineNo);
cell.setValue(values[2]);
lineNo++;
}
System.out.print(sheetCounter + " ");
// Saving the Excel file
workbook.save(excelFile.replace(".xlsx", sheetCounter + ".xlsx"));
System.out.println("\nExcel file created");
}
}
PS。我是Aspose的开发人员传播者。
答案 2 :(得分:1)
为什么不以块的形式进行读写操作。这是我能想到的方法:
如果你继续迭代这个过程。你肯定会节省你的内存消耗,虽然我没有看到cpu消耗的主要差异。
希望它有所帮助!
答案 3 :(得分:0)