资源预览内容
第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
第9页 / 共9页
亲,该文档总共9页全部预览完了,如果喜欢就下载吧!
资源描述
POI或者JXL在导出大量数据的时候,由于它们将每一个单元格生都成一个Cell对象,所以很容易导致内存溢出。解决这个问题,唯一的 办法是弄清楚Excel的二进制格式(汗),并且用流的方式读写 Excel。 POI和JXL其实提供了二进制方式读写Excel的API,只是因为缺少文 档和实例,所以使用的人不多。我编写了这个简单的合并 Excel的类,它只适合合并结构相同的多个Excel文件。好 在这个功能已经可以解决数据导出产生 OOM的问题:将数据分批导出然后合并。下面的代码使用POI3.1 ,合并11个3000多行的文档用时约6秒,我实在找不 到 更多的测试用的文档了。Java代码1. SuppressWarnings(unchecked)2. public class XlsMergeUtil 3. private static Logger logger = LoggerFactory.getLogger (XlsMergeUtil.class);4.5./*6. *将多个Xls文件合并为一个,适用于只有一个sheet ,并且格 式相同的文档7. * param inputs 输入的 Xls 文件8. * param out输出文件9. */10. public static voidmerge(InputStream inputs, OutputStream out) 11. if (inputs = null | inputs.length = 1) 12:throw new IllegalArgumentException( 没有传入输入 流数组,或只有一个输入流.);13. 14.15. List rootRecords = getRecords(inputs 0);16. Workbook workbook = Workbook.createWorkbook(rootRecords);17. List sheets = getSheets(workbook, rootRecords);18. if(sheets = null | sheets.size() = 0) 19. throw new IllegalArgumentException(第一篇文档的格式错误:必须有至少一个sheet);20. 21. /以第一篇文档的最后一个sheet为根,以后的数据都追加在这个sheet后面22. Sheet rootSheet = sheets.get(sheets.size() - 1);23. int rootRows = getRowsOfSheet(rootSheet); / 记录第 一篇文档的行数,以后的行数在此基础上增加24. rootSheet.setLoc(rootSheet.getDimsLoc();25. Map map = new HashMap(10000);26.27.28.35.36.37.38.39.40.41.42.43.44.45.46.47.48.for (int i = 1; i inputs.length; i+) / 从第二篇开始遍历List records = getRecords(inputsi);29.30.31.32.33.RowRecord34.int rowsOfCurXls = 0;/ 遍历当前文档的每一个recordfor (Iterator itr = records.iterator(); itr.ha sNext();) Record record = (Record) itr.next();if (record.getSid() = RowRecord.sid) / 如果是RowRecord rowRecord = (RowRecord) recor d;/ 调整行号rowRecord.setRowNumber(rootRows+ rowReco rd.getRowNumber();rootSheet.addRow(rowRecord); / 追加 RowrowsOfCurXls+; / 记录当前文档的行数/SST 记录, SST 保存 xls 文件中唯一的 String , 各个 String 都是对应着SST 记录的索引else if (record.getSid() = SSTRecord.sid)SSTRecord sstRecord = (SSTRecord) recor d;for (int j = 0; j sstRecord.getNum UniqueStrings();j+) int index = workbook.addSSTString(ss tRecord.getString(j);/ 记录原来的索引和现在的索引的对应关系map.put(Integer.valueOf(j), Integer.va lueOf(index); else if (record.getSid() = LabelSSTReco rd.sid) record;/调整SST索引的对应关系label.setSSTIndex(map.get(Integer.valueOf(l50.51.abel.getSSTIndex();52. 53. / 追加 ValueCell54. if (record instanceof CellValueRecordInterface) 55. CellValueRecordInterface cell = (CellValueRecordInterface) record;56. int cellRow = cell.getRow()+ rootRows57. cell.setRow(cellRow);58. rootSheet.addValueRecord(cellRow,cell);59. 60. 61. rootRows += rowsOfCurXls;62. 63. byte口 data = getBytes(workbook,sheets.toArray(newSheet 0);64. write(out, data);65. 66.67. static void write(OutputStream out, bytedata) 68. POIFSFileSystem fs = new POIFSFileSystem();69. / Write out the Workbook stream70. try 71. fs.createDocument(new ByteArrayInputStream(data),Workbook);72. fs.writeFilesystem(out);73. out.flush();74. catch (IOException e) 75. e.printStackTrace();76. finally 77. try 78. out.close();79. catch (IOException e) 80. e.printStackTrace();81. 82. 83. 84.85. static List getSheets(Workbookworkbook, List records) 86. int recOffset = workbook.getNumRecords();87. int sheetNum = 0;88.89. / convert all LabelRecord records to LabelSSTRecord90. convertLabelRecords(records, recOffset, workbook);91. List sheets = new ArrayList();92. while (recOffset records.size()93. Sheet sh = Sheet.createSheet(records, sheetNum+, recOffset);94.95. recOffset = sh.getEofLoc() + 1;96. if (recOffset = 1)97. break;98. 99. sheets.add(sh);100.101.return sheets;102.103.104.static int getRows(Listrecords) 105.int row = 0;106.for (Iterator itr = records.iterator(); itr.hasNext();) 107.Record record = (Record)itr.next();108.if (record.getSid()=RowRecord.sid) 109.row+;110.111.112.return row;113.114.115.static int getRowsOfSheet(Sheetsheet) 116.int rows = 0;117.sheet.setLoc( 0);118.while(sheet.getNextRow() !=null) 119.rows+;120.121.return rows;122.123.124.125.SuppressWarnings(deprecation)static List getRecords(InputStream input)126. try127.m(input);128.POIFSFileSystem poifsInputStream stream =new POIFSFileSystepoifs.getRoot().createDocumentInputStream(Workbook);129. return org.apache.poi.hssf.record.RecordFactory.createRecords(stream);130. catch (IOException e) 131. logger.error(IO 异常:,e.getMessage();132. e.printStackTrace();133. 134. return Collections.EMPTY_LIST;135. 136.137. static voidconvertLabelRe
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号