常见报表开发工具POI和JXL(JExcel)。本文采用JXL实现导出Excle功能。Excle-2003中对每个工作表的数据量大小有限制,行数最大限制为65536行,列数最大限制为256列。一个工作薄(workbook)可以有多个工作表(sheet)。
实现大批量数据导出Excel的方法
- 导出csv格式的数据
- 导出多个中间文件,将多个中间文件合并
- 导出一个文件,循环分页请求数据,写入excel是分多个工作表(sheet)写入
- 导出一个Excel文件的xml形式,另存为.xls文件
实现第3种方法,实现思路:
- 创建一个workbook,先设定导出参数,每次从数据库请求的数据条数,每个工作表放置的最大行数,根据查询记录总数 / 每次请求记录数 = 循环分页请求数据次数。
- 请求后台得到数据,对数据合法性进行保证,jxl导出是,数据字段不能为null。
- 读取数据,创建一个sheet,如果当前的行数大于最大设定行数,则新建一个sheet写入。将数据不断转换为sheet中的单元格label对象。
- 请求数据结束,调用workbook写入方法,关闭workbook,关闭输出流。
下面是封装后的类:
package com.xsm.pub.tool; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import jxl.Workbook; import jxl.WorkbookSettings; import jxl.write.Label; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * * @author * @时间 : 2014-7-24 上午09:23:47 * @功能 : TODO 大数据量导出Excel */ public class ExportExcelMassData { private static final Log log = LogFactory.getLog(ExportExcelMassData.class); public int totalSize;//总行数 public int firstRow = 0; // 开始请求数据行号 public int getDataTimes;//请求数据次数 totalSize / perPageSize + 1 public int perPageSize = 5000; // 一次请求分页大小 public int perSheetMaxRows = 10000; //每个工作表最大行数 public Map mapTitle = null; //列头 public Map mapColumn = null; //列数据 public List argList = null; //导出数据 //导出流 private OutputStream toClient; // 得到一个工作薄 private WritableWorkbook workbook; // 得到一个工作表 private WritableSheet lastSheet; //总的工作表数目 private int totalSheets = 0; //最后一行行号 private int lastRow = 0; public Map getMapTitle() { return mapTitle; } public void setMapTitle(Map mapTitle) { this.mapTitle = mapTitle; } public Map getMapColumn() { return mapColumn; } public void setMapColumn(Map mapColumn) { this.mapColumn = mapColumn; } public int getTotalSize() { return totalSize; } public void setTotalSize(int totalSize) { this.totalSize = totalSize; } public int getPerPageSize() { return perPageSize; } public void setPerPageSize(int perPageSize) { this.perPageSize = perPageSize; } public int getPerSheetMaxRows() { return perSheetMaxRows; } public void setPerSheetMaxRows(int perSheetMaxRows) { this.perSheetMaxRows = perSheetMaxRows; } public void init(OutputStream os) throws IOException { // 查询次数 getDataTimes = totalSize / perPageSize + 1; /* //计算工作表数目 totalSheets = totalSize / perSheetMaxRows + 1;*/ toClient = new BufferedOutputStream(os); // 得到一个工作薄 workbook = Workbook.createWorkbook(toClient); if (log.isDebugEnabled()) { log.debug("JXL版本:"+Workbook.getVersion());} WorkbookSettings ws = new WorkbookSettings(); ws.setLocale(new Locale("en", "EN")); } /** * * @创建人: * @时间 : 2014-7-24 上午10:18:08 * @功能 : TODO 数据合法性 * @param list * @return */ private List<Map> checkDatas(List<Map> list) { List<Map> rtnlist = new ArrayList<Map>();; Map map = null; Map temp = null; String key = null; String value = null; // 值 while (list.size() > 0) { map = (Map) list.get(0); temp = new HashMap(); Iterator it = mapTitle.keySet().iterator(); while (it.hasNext()) { key = (String) it.next(); value = map.get(key) == null ? "" : map.get(key).toString(); temp.put(key, value); } rtnlist.add(temp); temp = null; list.remove(0); } return rtnlist; } /** * * @创建人: yinxm * @时间 : 2014-7-24 上午10:19:45 * @功能 : TODO 写入excel * @param datas * @throws RowsExceededException * @throws WriteException * @throws IOException */ public void writeExcel(List datas) throws RowsExceededException, WriteException, IOException { List<Map> list = checkDatas(datas); int length = list.size(); Map map = null; String key = null; String value = null; // 值 Label label = null; // 行 int col = 0; // 列 for (int i = 0; i < length; i++) { if (lastRow >= perSheetMaxRows || lastRow == 0) {// 创建新工作表:当前行数超过本表限制条数,或者初始开始数据 if (log.isDebugEnabled()) { log.debug("创建工作表: " + (totalSheets+1));} lastSheet = workbook.createSheet(("工作表" + (totalSheets+1)),totalSheets); // 行数归1,0行为标题头 lastRow = 0; // 为新工作表加列标题头 Iterator it = mapTitle.keySet().iterator(); while (it.hasNext()) { key = (String) it.next(); value = new String((String) mapTitle.get(key)); col = Integer.valueOf((String) mapColumn.get(key)) .intValue(); label = new Label(col, lastRow, value); lastSheet.addCell(label); } // 工作表数 增加 totalSheets = totalSheets + 1; lastRow++; } map = (Map) list.get(i); Iterator it = map.keySet().iterator(); while (it.hasNext()) { key = (String) it.next(); // log.debug("key="+key); value = new String(map.get(key).toString()); // log.debug("mapColumn.get(key)="+mapColumn.get(key)); col = Integer.valueOf((String) mapColumn.get(key)).intValue(); label = new Label(col, lastRow, value); lastSheet.addCell(label); } lastRow++; } // 下一次分页请求开始行号位置 firstRow = firstRow + length; // if (log.isDebugEnabled()) { log.debug("循环一次,下一次行号:"+firstRow);} toClient.flush(); } public void closed() throws IOException, WriteException { // 关闭流 if (toClient != null) { toClient.flush(); toClient.close(); } if (workbook != null) { workbook.write(); workbook.close(); } } }
测试方法:
package org.test.pub.tool; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.test.pub.LogOut; import jxl.write.WriteException; public class ExportExcelMassDataMainTest { /** * @创建人: * @时间 : 2014-7-22 下午04:29:15 * @功能 : TODO * @param args * @throws IOException * @throws WriteException */ public static void main(String[] args) { long start = System.currentTimeMillis(); ExportExcelMassData tool = null; try { tool = new ExportExcelMassData(); // 执行查询操作 List list = new ArrayList(); OutputStream os = new FileOutputStream("test-export.xls"); //excel表头 List<Map> argList = new ArrayList<Map>(); Map<String, String> title = new HashMap<String, String>(); title.put("COL_NUM_ONE", "第一列"); title.put("COL_NUM_TWO", "第二列"); title.put("COL_NUM_THREE", "第三列"); title.put("COL_NUM_FOUR", "第四列"); title.put("COL_NUM_FIVE", "第五列"); argList.add(title); //组织Excel,各列数据,一个for循环一行 Map<String, String> seqmap = new HashMap<String, String>(); seqmap.put("COL_NUM_ONE", "0"); seqmap.put("COL_NUM_TWO", "1"); seqmap.put("COL_NUM_THREE", "2"); seqmap.put("COL_NUM_FOUR", "3"); seqmap.put("COL_NUM_FIVE", "4"); tool.setTotalSize(80000);//总数8万条,每次请求5000条数据,每个工作表最多1万行 tool.setPerPageSize(5000); tool.setPerSheetMaxRows(10000); tool.init(os); tool.setMapTitle(title); tool.setMapColumn(seqmap); System.out.println("请求次数:"+(tool.getDataTimes)); for (int k=0; k<tool.getDataTimes; k++) { System.out.println("请求数据:"+(k+1)+"\t开始行号:"+tool.firstRow); //自己模拟获取后台数据,实际应用时,将这段代码换成调用后台分页查询接口获取数据 for (int i=tool.firstRow; (i<(tool.firstRow+tool.perPageSize) && i<8000); i++) { Map map = new HashMap(); map.put("COL_NUM_ONE",i); map.put("COL_NUM_TWO", i+1); map.put("COL_NUM_THREE", i+2); map.put("COL_NUM_FOUR", new Integer(23)); map.put("COL_NUM_FIVE", new BigDecimal(20)); list.add(map); } //传入一次数据 tool.writeExcel(list); list.clear(); list = new ArrayList(); } }catch (Exception e) { System.out.println(e.toString()); LogOut.logError(e,true); } finally { try { tool.closed(); } catch (WriteException e) { System.out.println(e.toString()); LogOut.logError(e,true); } catch (IOException e) { System.out.println(e.toString()); LogOut.logError(e,true); } } System.out.println("耗时:"+(System.currentTimeMillis()-start)); } }
结果:
本地测试,导出8万条以内数据能够导出,耗时1710毫秒。
超过8万条数据报内存溢出错误:
java.lang.OutOfMemoryError: Java heap space
at jxl.write.biff.File.write(File.java:136)
at jxl.write.biff.RowRecord.writeCells(RowRecord.java:296)
at jxl.write.biff.SheetWriter.write(SheetWriter.java:410)
at jxl.write.biff.WritableSheetImpl.write(WritableSheetImpl.java:1165)
at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:805)
at org.test.pub.tool.ExportExcelMassData.closed(ExportExcelMassData.java:198)
at org.test.pub.tool.ExportExcelMassDataMainTest.main(ExportExcelMassDataMainTe
st.java:91)
Exception in thread "main" java.lang.RuntimeException: java.lang.OutOfMemoryErro
r: Java heap space
at jxl.write.biff.File.write(File.java:147)
at jxl.write.biff.RowRecord.writeCells(RowRecord.java:296)
at jxl.write.biff.SheetWriter.write(SheetWriter.java:410)
at jxl.write.biff.WritableSheetImpl.write(WritableSheetImpl.java:1165)
at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:805)
at org.test.pub.tool.ExportExcelMassData.closed(ExportExcelMassData.java:198)
at org.test.pub.tool.ExportExcelMassDataMainTest.main(ExportExcelMassDataMainTe
st.java:91)
Caused by: java.lang.OutOfMemoryError: Java heap space
at jxl.write.biff.File.write(File.java:136)
... 6 more
相关推荐
下面我们将深入探讨如何使用JXL库实现导出Excel数据。 首先,你需要在你的项目中引入JXL库。可以通过Maven或Gradle来添加依赖,如果是Maven,可以在pom.xml文件中添加以下依赖: ```xml <groupId>...
jxl实现excel大数据导出,26000条记录,测试导出时间是19s,例子不算复杂,没有excel样式的处理,可以自己扩展哈,有数据库文件,部署即可看到效果!!! 有三个功能:代码构建数据的导出、数据库数据的导出(从配置...
总之,`jxl`库提供了强大的功能来操作Excel文件,通过`WritableWorkbook`、`WritableSheet`和`WritableCellFormat`这三个核心类,我们可以实现自定义的Excel导出任务,包括添加水印等高级功能。在实际开发中,结合...
jxl导出excel 完整例子工程jxl导出excel 完整例子工程jxl导出excel 完整例子工程 jxl导出excel 完整例子工程jxl导出excel 完整例子工程jxl导出excel 完整例子工程
使用jxl方式实现Excel表格导出,非常简单而且实用
你可以通过研究这个项目的源代码,学习如何将Android中的数据结构(如ArrayList或Cursor)与jxl库结合,实现数据的导出功能。 总之,使用jxl库在Android上快速导出Excel表格需要理解jxl的API,处理Android特有的...
总结起来,`jxl导出excel工具类`是一个强大的工具,它能够帮助开发者快速实现数据到Excel的导出功能,减少重复代码,提高开发效率。通过合理的封装和设计,可以使得这类工具类在不同的项目中重用,降低维护成本。...
本篇将详细介绍如何使用JXL库来导出Excel数据表,并结合描述中的信息,探讨其核心特性和实现方式。 首先,我们来理解"JXL导出Excel数据表"这一主题。JXL(Java Excel API)是一个开源项目,它允许Java程序创建、...
总结来说,JXL库为Java开发者提供了强大的Excel操作能力,无论是在数据导入还是导出方面,都能满足大部分需求。通过以上步骤,你可以开始尝试使用JXL处理Excel文件了。在实际开发中,根据具体业务场景进行调整和优化...
标题 "jxl 实现根据sql语句导出excel文件" 提到的是使用jxl库来创建Excel文件,并根据SQL查询结果填充数据的过程。jxl是一个Java库,它提供了读写Microsoft Excel文件的能力,这对于在Java应用程序中处理和生成报表...
在Java编程环境中,将数据库内容导出到Excel文件是一种常见的需求,这可以帮助用户更方便地查看、分析和处理大量数据。jxl库是Java中一个广泛使用的库,它提供了读写Excel文件的功能。本篇文章将深入探讨如何利用jxl...
本篇文章将深入探讨如何使用jxl库实现大数据量的Excel导出,并讨论相关优化策略。 首先,让我们了解jxl库。jxl是Java Excel API的简称,它支持多种版本的Excel文件格式,包括97-2003的.BIFF8格式以及2007年以后的....
在本文中,我们将深入探讨`jxl`库如何帮助开发者实现Excel的导入和导出功能。 首先,我们需要理解`jxl`库的基本结构和核心概念。`jxl`库主要包含以下几个关键类: 1. `Workbook`:这个类代表一个Excel工作簿,相当...
"jxl 导出 excel"的标题和描述暗示了我们将会讨论如何使用JXL库从数据库中导出数据到Excel文档的过程。这个过程涉及到Java编程、数据库操作以及JXL库的使用。 首先,我们需要了解JXL库。JXL是一个开源库,它提供了...
以下是使用Java和jxl库将数据导出到Excel的基本步骤: 1. **导入库**:在你的Java源代码中,你需要导入jxl库的相关类。例如: ```java import jxl.*; import jxl.write.*; ``` 2. **创建Workbook对象**:...
在Java开发环境中,有时我们需要将数据库中的数据导出到Excel文件,以便于数据分析、报表生成或数据共享。这时,一个常用的工具就是JXL库。JXL全称为Java Excel API,它是一个强大的开源Java库,允许开发者在Java...
通过熟练掌握jxl,开发者可以轻松地在Java应用程序中实现数据的导入导出,提升工作效率。在实际项目中,根据具体需求选择合适的使用方式,结合良好的编程习惯,可以避免潜在的问题,确保程序的稳定性和性能。
在Java编程环境中,导出数据到Excel是一种常见的需求,特别是在数据分析、报表生成或者数据交换的场景下。JXL是一个流行的库,它允许开发者方便地读取、写入和操作Excel文件。本文将深入探讨如何利用JXL库通过模板来...
以上就是关于使用JXL和Apache POI实现Excel导入导出的基本知识。根据实际需求,你可以结合这两个库的功能,灵活地处理各种Excel文件操作。在实际项目中,通常会根据性能、功能需求以及文件兼容性等因素选择适合的库...