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的功能是:只使用几行代码就可以建立极端复杂的Excel报表。你所需要实现的大部分工作是建立XLS模板文件,完成所需要的格式,公式和宏等等,使用注释来指示出数据需要填入的位置。接着写几行代码调用jXLS引擎解析...
jxls是一个强大的工具,它允许我们使用Apache POI库的功能,但通过使用JSP标签和简单的模板来简化Excel文件的创建过程。下面将详细介绍jxls如何利用模板来实现Excel的导出。 1. **jxls概述**: jxls是一个Java库,...
#### 二、JXLS安装与配置 为了使用JXLS引擎,需要将`jxls-core.jar`文件添加到项目的classpath中。如果还需要读取.xls文件,则需额外添加`jxls-reader.jar`。对于使用Maven构建的应用程序,可以在`pom.xml`文件中...
本文将详细介绍如何使用JXLS库结合Excel模板来实现这一功能。 JXLS(Java Excel Library)是一个强大的开源Java库,它允许开发者通过简单的XML模板来控制Excel文件的内容和格式。这个库简化了Java程序生成复杂Excel...
在这个项目案例中,开发者使用了jxls库的最新版本(jxls2),它是一个强大的工具,能够帮助程序员将Java集合和POJOs(Plain Old Java Objects)直接转换为Excel工作表。 jxls是一个开源的Java库,其主要功能是允许...
包括以下几个: commons-beanutils.jar commons-collections-2.1.1.jar commons-digester.jar commons-jexl-1.1.jar commons-logging.jar jxl.jar jxls.jar jxls-core-0.9.5.jar poi_2006_5_19.jar
使用jxls标签导出Excel说明 基于jxls标签导出Excel的方式可以简化Excel报表的生成过程,并且可以实现复杂的报表功能。jxls标签可以直接写在Excel模板中,并可以与POI结合使用,生成复杂的Excel报表。 JXLS是一个...
`jxls`(Java eXtensions for Sheets)是一个开源项目,其主要功能是在Java应用中动态地填充Excel模板,生成定制化的Excel文件。它利用Apache POI库操作Excel,并引入了类似于JSP标签的概念,使得开发者可以轻松地将...
1. **JXLS库**:JXLS(Java eXtensions for LibreOffice Sheets)是Java开发人员用来处理Excel工作簿的工具,它提供了一种声明式的方式来定义模板,并用Java对象的数据填充这些模板。JXLS通过使用类似于JSP的语法,...
jxls是一款基于Java的库,它允许开发者通过使用Java编程语言和模板技术来动态生成Excel工作簿。这个库极大地简化了从Java对象到Excel表格的数据转换过程,尤其在处理复杂的数据结构和模板时,其优势更为明显。本文将...
1. **模板语法**:Jxls使用一种类似于JSP的简单模板语法,允许在Excel中插入Java表达式和控制结构。例如,`<jx:each>`标签可以用来迭代Java集合中的元素,将它们填充到对应的单元格中。 2. **数据绑定**:通过AOP...
- **jar文件**:`jxls-2.3.0.jar`是核心库文件,包含了所有必需的类和方法,用于在Java项目中集成和使用Jxls。将其添加到项目的类路径中,即可开始利用Jxls的功能。 **使用场景** - **报告生成**:Jxls适用于需要...
6. **doc**:文档目录,可能包含了API参考、用户指南或其他技术文档,帮助开发者理解和使用jxls库。 jxls的一个主要优点是它的模板语法,它允许在Excel模板中使用Java Expression Language (JEXL)。通过这种方式,...
- jxls 使用`java.util.List`或`java.util.Map`等集合类作为数据源,结合注解,可以直接将数据映射到Excel单元格,实现了类似JSP的EL表达式功能。 6. **动态计算和逻辑** - 除了简单的数据填充,jxls还允许在模板...
JXLS是一个强大的Java库,用于处理Excel工作簿,它允许开发者使用模板方式来生成和读取Excel数据。2.4.0版本是其一个重要里程碑,提供了更多的功能和改进。这个压缩包“jxls_2.4.0_examples”包含了官方提供的示例...
Jxls(Java Excel Templates)是一个开源库,它允许开发人员使用Java POI库和模板Excel文件来生成动态的Excel报告。这个工具极大地简化了在Java应用程序中生成复杂Excel表格的过程,尤其适合那些需要根据数据源动态...
你先创建一个Excel模板,包含各个字段的占位符,然后使用jxls的API,传入User集合和模板文件,jxls会自动填充数据并生成最终的Excel文件。 **应用场景** jxls在很多领域都有应用,如报表生成、数据导出、批量数据...
使用net.sf.jxls下的jxls-core包进行复杂的Excel导出
Jxls是一个强大的Java库,它允许用户通过使用普通的Excel模板来生成复杂的Excel报告。这个压缩包文件包含了所有必要的jar包,使得开发者无需依赖Maven或其他构建工具,可以直接在项目中集成Jxls。以下是对Jxls及其...