Java导出Excel

查数据不是本节的重点,主要是SQL,索引这一块,此处不讨论。本节重点是写数据。

问题

当数据量小(比如,几千几万条)的时候可以采用同步的方式,不用考虑别的。

而当数据量大的时候(比如,几十上百万)的时候问题就暴露出来了。

首先,慢是肯定的了。少则几十秒,多则几十分钟都是有可能的。

这还是小问题,最要命的因为一个导出把系统搞挂了。。。

笔者曾经见过,因为一个导出,系统直接挂了,还严重拖慢了同一台机器上的其它应用,最终宕机了。。。

究其原因,大量数据堆积在内存中,可能会造成内存溢出。夸张一点,几百万条数据每条数据几十个字段都放到内存中,要等到全部写完这些内存才会释放。

方案

针对单个工作表(sheet)的行数限制,可以分多个工作表

针对单个文件太大不容易打开,可以分多个文件,最终打成压缩包

针对内存溢出,可以分批导,每次导一批数据,分多次导

建议

异步下载!异步!异步!异步!

如果对样式没什么要求,也不用公式的话,强烈推荐导出CSV格式

可以采用多线程的方式,先查总数,然后分一下看需要多少个线程,每个线程读取一部数据并写入单独Excel文件;当然,也可以多线程读,单线程写

分批导,这一点跟上一步类似

思路

客户端发起下载请求以后,服务端异步执行下载任务并生成下载文件,客户端读取这个文件下载。

那么问题来了,客户端怎么知道服务端下载文件已经生成好了呢?

有一个方案是:WebSocket

客户端发起下载请求并收到服务端的响应以后和服务端建立一个WebSocket连接,这样服务端生成完文件以后就可以主动通知客户端了。

组件

关于导Excel的组件,笔者用过以下4种:

CSV

POI

JXLS

EasyPoi

其中,POS就不用说了,CSV真的很快,不熟悉CSV的请参考《Java导出CSV文件》,JXLS用模板的方式也很方便,可以预先定义好样式格式,easypoi是在poi基础上做了封装,使用注解就能轻松完成导出。

Apache POI HSSF与XSSF基本用法

@Test public void testHSSF() throws Exception { // 创建一个工作簿 HSSFWorkbook wb = new HSSFWorkbook(); // 创建一个工作表 HSSFSheet sheet = wb.createSheet(); // 创建字体 HSSFFont font1 = wb.createFont(); HSSFFont font2 = wb.createFont(); font1.setFontHeightInPoints((short) 14); font1.setColor(HSSFColor.HSSFColorPredefined.RED.getIndex()); font2.setFontHeightInPoints((short) 12); font2.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex()); // 创建单元格样式 HSSFCellStyle css1 = wb.createCellStyle(); HSSFCellStyle css2 = wb.createCellStyle(); HSSFDataFormat df = wb.createDataFormat(); // 设置单元格字体及格式 css1.setFont(font1); css1.setDataFormat(df.getFormat("#,##0.0")); css2.setFont(font2); css2.setDataFormat(HSSFDataFormat.getBuiltinFormat("text")); // 创建行 for (int i = 0; i < 20; i++) { HSSFRow row = sheet.createRow(i); for (int j = 0; j < 10; j = j + 2) { HSSFCell cell = row.createCell(j); cell.setCellValue("Spring"); cell.setCellStyle(css1); HSSFCell cell2 = row.createCell(j+1); cell2.setCellValue(new HSSFRichTextString("Hello! " + j)); cell2.setCellStyle(css2); } } // 写文件 FileOutputStream fos = new FileOutputStream("G:/wb.xls"); wb.write(fos); fos.close(); } @Test public void testSS() throws IOException { Workbook[] wbs = {new HSSFWorkbook(), new XSSFWorkbook()}; for (int i = 0; i < wbs.length; i++) { Workbook wb = wbs[i]; CreationHelper creationHelper = wb.getCreationHelper(); Sheet sheet = wb.createSheet(); for (int j = 0; j < 10; j++) { Row row = sheet.createRow(j); Cell cell = row.createCell(0); cell.setCellValue(creationHelper.createRichTextString("ABC")); } String filename = "G:/workbook.xls"; if (wb instanceof XSSFWorkbook) { filename = filename + "x"; } wb.write(new FileOutputStream(filename)); wb.close(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfsgf.html