Java 将大型文本文件数据写入excel

Java 将大型文本文件数据写入excel,java,apache-poi,aspose,Java,Apache Poi,Aspose,我正在读一个用一些分隔符分隔的文本文件 我的文本文件内容示例 Avc def efg jksjd 1235 340 一行一行地保存在内存中,使用hashmap将行号作为整数类型的键 作为列表对象的文本文件的每行 考虑一下,我的地图会存储这样的信息 整数列表 1[Avc def efg jksjd] 我正在使用ApachePOI编写excel。 在使用ApachePOI编写excel时,我遵循这种方法,下面是我的代码片段 HSSFWorkbook workbook = new HSSFWorkbo

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

我的文本文件内容示例

Avc def efg jksjd
1235
340

一行一行地保存在内存中,使用hashmap将行号作为整数类型的键 作为列表对象的文本文件的每行

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

整数列表

1[Avc def efg jksjd]

我正在使用ApachePOI编写excel。 在使用ApachePOI编写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);
            }
}
HSSFWorkbook工作簿=新的HSSFWorkbook();
HSSFSheet sheet=workbook.createSheet(“样本表”);
Map excelDataHolder=新建LinkedHashMap();
int rownum=0;
for(整数键:键集){
Row-Row=sheet.createRow(rownum++);
List objList=excelHolder.get(key);//excelHolder是我的地图
int-cellnum=0;
用于(对象对象对象:对象列表){
Cell Cell=row.createCell(cellnum++);
cell.setCellValue((日期)obj);
}
}
如果要写入excel的行数/记录数较少,则此操作非常有效。想象一下,如果记录以十亿为单位,或者如果文本文件以100000为单位有更多行。我想,我的方法失败了,因为 createRow和createCell在堆中创建超过100000个对象。 无论java到excel的api是什么,我认为写入它(excel)是基于相同的方法,即如上所示的集合迭代。我也用aspose做了一些例子,结果aspose也有同样的问题

  • createRow和createCell是否每次调用时都创建新对象
  • 如果是,还有什么选择?。如何以更好的性能将大数据写入excel

    • 为什么不分块读写呢。以下是我可以考虑的方法:

      • 读几行你的txt文件,并把信息在地图上,因为你正在做。假设你读了100行,地图上有100个条目
      • 将这一百个条目写入您的excel文件,第一次使用excel
      • 清空地图或重新初始化
      • 现在从课文中读下100行。据我所知,如果不阅读前100行,就无法直接访问第101行。因此,您可能必须从一开始就读取文件,但可以避免前100行并在映射中创建条目
      • 现在更新excel文件。我认为您可以使用此链接中提到的POI更新excel:
      如果你继续重复这个过程。您肯定会节省内存消耗,尽管我看不出cpu消耗有什么主要区别

      希望有帮助

      这是你的答案

      试试这个简单的代码&如果你需要进一步的未来,你可以


      apache poi的最新版本已经发布。无耻的网站拷贝

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


      我用它创建了150万行的电子表格

      我将回答关于Aspose.Cells for Java的问题,因为您也尝试过它

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

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

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

      稍后,手动将它们合并到单个Excel工作簿中。当复制包含如此巨大数据的工作表时,单元格将出现内存不足异常

      下面是创建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");
          }
      }
      
      导入com.aspose.cells.*;
      导入java.util.*;
      公共类ExcelLargeTextImport
      {
      私有静态字符串excelFile=Common.dataDir+“largedata.xlsx”;
      公共静态void main(字符串参数[])
      {
      尝试
      {
      Common.setLicenses();
      导入Excel();
      }
      捕获(例外情况除外)
      {
      System.out.println(例如getMessage());
      }
      }
      私有静态void importToExcel()引发异常
      {
      //在方法中处理每个工作簿
      
      for(int sheetCounter=0;sheetCounter@OnlineSolution:应该是注释吗?