【问题标题】:Write large text file data into excel将大文本文件数据写入excel
【发布时间】:2013-05-08 11:01:25
【问题描述】:

我正在阅读一个用一些分隔符分隔的文本文件。

我的文本文件内容示例

Avc def efg jksjd
1 2 3 5
3 4 6 0

逐行并使用以行号作为整数类型键的哈希图将其保存在内存中 文本文件的每一行作为 List 对象

考虑一下,我的地图会存储这样的信息

整数列表

1 [Avc def efg jksjd]

我正在使用 Apache POI 写入 excel。 使用Apache POI写入excel时,我遵循这种方法,这是我的代码sn-p

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 的行数/记录数较少,这将非常有效。想象一下,如果记录以十亿为单位,或者如果文本文件有更多行假设为 100 000。我认为,我的方法失败了,因为 createRow 和 createCell 在堆中创建了超过 100 000 个对象。 无论使用java to excel api,我认为写入它(excel)是基于相同的方法,即如上所示的集合迭代。我也用 aspose 做了一些例子,结果 aspose 我猜也有同样的问题。

  • createRow 和 createCell 是否在每次调用时都会创建新对象?
  • 如果是,有什么替代方案?我如何将大数据写入 Excel 并获得更好的性能?

【问题讨论】:

    标签: java apache-poi aspose


    【解决方案1】:

    我将回答 Aspose.Cells for Java,因为您也尝试过。

    创建或加载非常大的 Excel 文件几乎总是需要大量内存。即使您一次读取单行或多行,您仍然会将内容写入加载到内存中的 Workbook 实例。

    解决方案 1(不好且非常有限):增加堆大小,如果允许的最大堆大小适用于您的最大文件,请选择它。

    解决方案 2(复杂,需要一些人工): Excel 2007 及更高版本允许每张纸大约 100 万行。我建议您为 100 万行创建一个只有一张工作表的工作簿。也就是说,如果文本文件中有 1000 万行,则创建 10 个单独的 Excel 工作簿。

    稍后,手动将它们合并到一个 Excel 工作簿中。 Aspose.Cells 在复制具有如此庞大数据的工作表时会出现内存不足的异常。

    下面是创建 10 个单独的 Excel 文件的代码 sn-p,每个文件有 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】:

      最新版本的 apache-poi 具有 sxssf。来自网站的无耻复制

      SXSSF(包:org.apache.poi.xssf.streaming)是一个API兼容的 非常大的电子表格时使用 XSSF 的流式扩展 必须生产,并且堆空间有限。 SXSSF 实现了它的低 通过限制对 a 内的行的访问来占用内存 滑动窗口,而 XSSF 允许访问文档中的所有行。 不再在窗口中的旧行变得不可访问,因为 它们被写入磁盘。

      我曾用它来创建包含 150 万行的电子表格。

      【讨论】:

        【解决方案3】:

        这是你的答案...

        试试这个简单的代码,如果你需要更多的未来,你可以广告......

        https://stackoverflow.com/a/16479713/1490962

        【讨论】:

        • @ OnlineSolution : 应该是评论吗?
        【解决方案4】:

        为什么不分块进行读写。这是我能想到的方法:

        • 阅读您的 txt 文件几行,然后将信息放入地图中。假设您阅读了 100 行,并且您的地图中有 100 个条目。
        • 写这百条excel文件给你,第一次生成excel
        • 清空地图或重新初始化。
        • 现在从文本中读取接下来的 100 行。因此,据我了解,如果不阅读前 100 行,就无法直接访问第 101 行。因此,您可能必须从一开始就读取文件,但您可以避免前 100 行并在 map 中创建条目。
        • 现在更新 excel 文件。我认为您可以使用此链接中提到的 POI 更新 excel: Edit existing excel files using jxl api / Apache POI

        如果你不断迭代这个过程。你肯定会节省你的内存消耗,虽然我没有看到 CPU 消耗有很大的不同。

        希望对你有帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-09
          • 1970-01-01
          相关资源
          最近更新 更多