jxls在生成Excel文件时,提供一个批量生成Excel Sheet的功能,即可以一次生成一个包含多个Sheet的Excel文件。但是,jxls在处理这类操作的时候会出现性能问题,当一次形成的Excel的Sheet数量超过500个的时候就会出现很严重的性能问题,运算到最后,系统会提示OutOfMemeroyError,这种问题的出现是由于jxls的实现方式决定的。
如果,仔细查看jxls的源代码就会发现,无论是处理单个Sheet还是处理多个Sheet的时候,在XLSTransformer类的Transform处理的时候都是在内存中对Sheet进行处理,然后,在生成WorkBook。假如,需要一次形成的Sheet为500以上的时候,势必会出现严重的性能问题。
针对以上的问题,如果我们的应用需要形成500Sheet以上的Excel时,我们可以采用人为干预的方式,即在进行处理前对Beans的个数进行限制,最好将Beans的个数限制在200个以内,即每次只生成包含200个Sheet的WorkBook,在WorkBook形成以后,再对WorkBook进行合并,然后,将合并的WorkBook输出形成Excel文件,这样处理的时候,对一个Excel的总的Sheet也需要进行控制,否则在运算的过程中也会出现OutOfMemeroyError,最好控制在3000个以内,如果,超过3000个建议形成多个Excel文件,下面我通过一个具体的企业应用来说明怎么来进行操作。
我这个应用是Payslip导出的一个应用,具体要求是:
按照Division和Costcenter来组织Payslip卡片,每个Costcenter下面的员工组织到一个Excel文件里面
在具体实现的过程发现有一个Costcenter下面的员工数量超过了3000,开始是想是否能够一次将这个Costcenter下面的Payslip全部形成,结果遭到了可耻的失败。经过不断的测试以后,得到了以上的两个临界点的数字。下面说明一下我的具体实现:
1)从数据库按照Costcenter取出Payslip,得到一个payslipList对象。具体就是组装出取数据的SQL Script,利用JDBCTemplate取出数据。
2)形成Costcenter对应的Excel文件的名称,如果,得到的List的size大于3000,则每3000个记录形成一个Excel文件
3)将得到的List按照200进行分块处理,每200处理一次
4)利用jxls提供的方法transformMultipleSheetsList()对数据进行处理,得到一个HSSFWorkbook对象
5)合并得到的HSSFWorkbook,输出形成Excel文件
具体代码如下:
java 代码
-
public void exportPayslip(String costcenterCode) throws IOException{
-
List payslipList = payslipDao.getPaylipByCostcenter(String costcenterCode);
-
String xlsFileName;
-
-
if (payslipList.size() <= 3000){
-
xlsFileName = "c:"+File.separator+costcenterCode+".xls";
-
transformXLSFile(payslipList ,xlsFileName );
-
} else {
-
for (int i =0;i<(int)Math.ceil((double)payslipList.size()/3000;i++)){
-
xlsFileName = "c:"+File.separator+costcenterCode+"_"+new Integer(i+1).toString()+".xls";
-
int k = ((i+1)*3000 < payslipList.size()) ? (i+1)*3000 : resultList.size();
-
List resultList = payslipList.subList(i*3000,k);
-
transformXLSFile(resultList ,xlsFileName );
-
}
-
}
-
}
-
- private void transformXLSFile(List resultList,String fileName){
-
XLSTransformer transformer = new XLSTransformer();
-
HSSFWorkBook resultWorkBook = null;
-
-
for (int i = 0;i<(int)Math.ceil((double)resultList.size()/200;i++)){
-
List payslipMaps = new ArrayList();
-
List sheetNames = new ArrayList();
-
-
InputStream xlsTemplateIO = new BufferedInputStream(getClass().getResourceAsStream("payslip.xls"));
-
-
int k = ((i+1)*200 < resultList.size()) ? (i+1)*200 : resultList.size();
-
-
payslipMaps = resultList.subList(i*200,k);
-
-
for (int j=0;j
-
Map payslip = (Map)resultList.get(i);
-
String sheetName = paysli.get("EMPLOYEE_ID");
-
-
sheetNames.add(sheetName);
-
}
-
-
HSSFWorkbook workBook = transformer.transformMultipleSheetsList(xlsTemplateIO , payslipMaps , sheetNames, "map", new HashMap(), 0);
-
-
if (i == 0){
-
resultWorkBook = workBook;
-
} else {
-
for (int h = 0;h < workBook.getNumberOfSheets();h++){
-
-
HSSFSheet newSheet = resultWorkBook.createSheet( (String) sheetNames.get(i) );
-
HSSFSheet hssfSheet = workBook.getSheetAt(h);
-
Util.copySheets(newSheet, hssfSheet);
-
Util.copyPageSetup(newSheet, hssfSheet);
-
Util.copyPrintSetup(newSheet, hssfSheet);
-
}
-
}
-
-
saveWorkbook(resultWorkbook, fileName);
-
xlsTemplateIO.close();
-
}
-
}
-
- private void saveWorkbook(HSSFWorkbook resultWorkbook, String fileName) throws IOException{
-
OutputStream os = new BufferedOutputStream(new FileOutputStream(fileName));
-
resultWorkbook.write(os);
-
os.flush();
-
os.close();
-
}
以上代码有部分代码需要被放在try/catch语句里面,确保Stream能够被关闭,否则,会影响程序的运行性能。代码只代表个人的一种实现方式。
以上代码有一个地方需要说明,就是jxls的transformMultipleSheetsList()方法,该方法的声明如下:
java 代码
-
public HSSFWorkbook transformMultipleSheetsList(InputStream is, List objects, List newSheetNames, String beanName, Map beanParams, int startSheetNum) throws ParsePropertyException {
该方法里面的参数说明如下:
1)is:即Template文件的一个输入流
2)newSheetNames:即形成Excel文件的时候Sheet的Name
3)objects:即我们传入的对应每个Sheet的一个Java对象,这里传入的List的元素为一个Map对象
4)beanName:这个参数在jxls对我们传入的List进行解析的时候使用,而且,该参数还对应Template文件中的Tag,例如,beanName为map,那么在Template文件中取值的公式应该定义成${map.get("property1")};如果beanName为payslip,公式应该定义成${payslip.get("property1")}
5)beanParams:这个参数在使用的时候我的代码没有使用到,这个参数是在如果传入的objects还与其他的对象关联的时候使用的,该参数是一个HashMap类型的参数,如果不使用的话,直接传入new HashMap()即可
6)startSheetNo:传入0即可,即SheetNo从0开始
以上代码的原理与操作Simple Sheet的时候差别不大,主要是Template的文件的取值公式和调用的方法有所改变而已。关键是在大数据量操作的时候注意对处理的数据进行分块处理即可,否则,系统运行性能将很难保证。以上代码,在我实际的使用过程中速度还是比较理想的,16000条数据的导出时间是15分钟左右。
分享到:
相关推荐
Jxls多sheet页demo 1.解决了多sheet页导出时候模板定义页无法删除,无法隐藏 2.新增冻结窗口接口 example: //JxlsHelper helper = JxlsHelper.getInstance(); //helper.setSourceSheetName("template"); //helper....
在使用 POI 生成报表时,需要首先创建一个 Workbook 对象,然后创建一个或多个 Sheet 对象,每个 Sheet 对象可以包含多个 Cell 对象。Cell 对象是 Excel 中最基本的单元格,可以设置其内容、格式、边框、背景等属性...
`jxls2` 还提供了更复杂的功能,如支持多sheet操作、动态列宽、自定义函数等。通过阅读官方文档和相关教程,可以掌握更多高级用法。 总结,`jxls2` 是一个强大的工具,可以帮助Java开发者轻松地处理Excel文件。通过...
6. **多sheet处理**: 可以在一个模板中处理多个Excel工作表,便于构建复杂的报告结构。 7. **易于集成**: 与Spring框架有良好的兼容性,可以轻松地整合到现有的Java项目中。 8. **版本兼容**: jxls 1.0.6是较早的...
6. **多sheet操作**:可以同时处理多个工作表,方便构建复杂的Excel报告。 **jxls工作流程** 1. **创建模板**:首先,开发者需要创建一个Excel模板,其中包含固定的布局和JEXL表达式。 2. **设置数据源**:准备需要...
这允许用户在一个Excel文件中处理多个工作表,例如,当需要将不同数据集合并到一个单一的Excel报告中时,这个功能就非常有用。通过JXLS,你可以轻松地创建、读取和修改不同工作表的内容,实现复杂的数据组织和展示。...
Jxls不仅支持单个工作表的操作,还可以处理包含多个工作表的模板。只需在Context中为每个工作表创建不同的数据集,然后指定相应的sheetName即可。 7. **性能优化**: 对于大数据量的操作,可以考虑使用Jxls的流式...
- **多sheet处理**:一个模板文件可以包含多个sheet,jxls可以分别处理每个sheet的数据。 总的来说,jxls是一个强大且灵活的工具,它可以简化Java程序中的Excel导出工作。通过模板方式,开发者可以专注于数据逻辑,...
除了单一Sheet的导出,`jxls2`还支持多Sheet的报表导出,这意味着可以在一个Excel文件中包含多个独立的数据集,这对于报告的组织和阅读非常有帮助。例如,可以将不同部门的数据分别放在不同的Sheet中,或者按照时间...
例如,你可以创建一个包含多个表格、条件格式化和计算的模板,然后用动态数据填充,无需在代码中硬编码所有细节。 在实际应用中,你可能还需要关注性能优化,因为大量数据处理可能导致内存压力。可以考虑使用`...
- **多sheet处理**:可以同时处理多个工作表的数据。 - **模板合并**:能够合并多个模板,生成复杂结构的Excel文件。 总的来说,"导出Excel_jxls1.0.2"是一个强大的工具,它简化了在Java应用中生成复杂Excel报告的...
3. **Sheet**: Sheet代表Excel中的一页,可以包含多个Row和Cell。你可以通过Sheet对象来设置行高、列宽,以及添加和删除行和列。 4. **Row**: 表示Excel的一行,可以包含多个Cell。Row对象允许你控制行的高,以及...
需要注意的是,这只是一个基本的实现,实际使用中可能需要处理更复杂的情况,比如处理日期、数字格式,处理多列合并的单元格,以及支持更多的数据类型等。此外,JXL库不支持较新版本的Excel文件格式(如.xlsx),...
一个Workbook可以包含多个Sheet。 - **Row**:Row表示工作表中的一行数据,包含一个或多个Cell。 - **Cell**:Cell是最小的数据单元,存储单个值或公式。 2. **API使用**: - **创建Workbook**:你可以使用`...
在一个Sheet中,我们可以创建Row对象,每行中再添加Cell对象来存储数据。对于从List对象导出数据的情况,我们可以遍历List,为每个元素创建一个新的Row,并在对应的Cell中设置值。 以下是一个简单的示例,展示如何...
Java导出Excel是Java开发中常见的一项任务,特别是在数据分析、报表生成或数据交换等领域。Apache POI是一个流行的开源库,允许Java程序读取和写入Microsoft Office格式的文件,包括Excel(.xls和.xlsx)。在本场景...
每个部分可以保存为单独的sheet,或者创建多个单独的Excel文件。 5. **下载管理**:为了提供友好的用户体验,需要实现断点续传功能,使得用户可以暂停、恢复或取消下载。此外,文件名可以包含用户查询的参数,以便...
除了Apache POI,还有其他库如JExcelApi、OpenCSV和JXLS供选择,它们各有优缺点,根据实际需求选择合适的库。 9. **实战应用** 在实际应用中,Java操作Excel常用于报表生成、数据导入导出、自动化测试数据准备等...