java web 导出Excel 的工具类公用实现
平时我们在开发后端管理的系统时,经常会出现导出Excel的功能。这个功能很简单,但是呢,我一般就会使用公用的工具类,在一个Util中,暴露公用导出的接口,只需要传入需要导出的数据(一般使用list集合)以及需要导出的key-value字段和值的模板(这里使用了org.json,更加轻量话)。
一、废话不多说,直接先上暴露给用户的controller层的代码.这里呢,更改了header,通知浏览器打开下载功能(Content-Disposition 和attachment;filename一起使用)。然后只需要从数据库中调用需要导出的数据,这里我就直接调用所有的数据。
/** * 导出excel * @param response */ @RequestMapping(value = "exportExcel",method = RequestMethod.GET) public void exportExcel(HttpServletResponse response){ OutputStream out = null; try { out = response.getOutputStream(); response.reset(); String header = "attachment; filename=" + URLEncoder.encode("业主信息.xls", "UTF-8"); response.setHeader("Content-Disposition", header); response.setContentType("application/octet-stream; charset=utf-8"); List<Owner> owners = ownerService.findAll(); ownerService.exportExcel(owners,out); out.flush(); }catch (Exception e){ e.printStackTrace(); }finally { try{ if(out!=null){ out.close(); } }catch (Exception e){ e.printStackTrace(); } } }
二、Service的代码,对应 ownerService.exportExcel(owners,out); 传入了需要导出的集合,以及需要导出的out流。
@Override public void exportExcel(List<Owner> owners, OutputStream out){ JSONArray jsonArray = new JSONArray(); List<Map<String, String>> eventRecordMapList = new ArrayList<Map<String, String>>(); JSONObject jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "序号"); jsonObject.accumulate("header", "id"); jsonArray.put(jsonObject); jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "业主姓名"); jsonObject.accumulate("header", "name"); jsonArray.put(jsonObject); jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "业主开户银行"); jsonObject.accumulate("header", "bankName"); jsonArray.put(jsonObject); jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "业主开户银行账号"); jsonObject.accumulate("header", "bankAccount"); jsonArray.put(jsonObject); jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "供应商"); jsonObject.accumulate("header", "vendor"); jsonArray.put(jsonObject); jsonObject = new JSONObject(); jsonObject.accumulate("headerName", "代付金额"); jsonObject.accumulate("header", "payed"); jsonArray.put(jsonObject); for (int i = 0; i < owners.size(); i++) { Owner owner = owners.get(i); Map<String, String> recordMap = new HashMap<String, String>(); recordMap.put("id",owner.getId().toString()); recordMap.put("name", owner.getName()); recordMap.put("bankName", owner.getBankName()); recordMap.put("bankAccount",owner.getBankAccount()); recordMap.put("vendor",owner.getVendor()); if (owner.getPayed()!=null){ recordMap.put("payed",owner.getPayed().toString()); }else { recordMap.put("payed","0"); } eventRecordMapList.add(recordMap); } ExcelUtils exportExcel = new ExcelUtils(); exportExcel.exportExcel("业主信息", jsonArray, eventRecordMapList, out); }
这一块呢,使用了org.json ,如果亲们要使用我的代码,就要在项目中引入org.json ,maven引用如下
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20151123</version> </dependency>
Service中的代码,主要是为了通过key-value的形式将数据全部进行整理,以便用通用的接口实现导出
三 、本块代码就是核心的Util中的通用工具类,这个通用工具类可以通过定制,继承的方式无限扩展适用的业务逻辑,比如可以扩展那些字段导出是需要下拉的,哪些是不能修改的等等,都可以扩展,这个考验扩展人的接口封装功底(我就特别喜欢封装公用接口给别人用,那种成就感很爽,不过就要考虑很多业务逻辑的情况),请打开查看哦,写得不是很复杂,不过也要慢慢看看就会懂了,就是一个公用方法。这样的好处就是,不管以后哪些板块用到导出功能,就不用再去写excel的操作代码了,只需要在模块的service中定义需要导出的字段,告诉Excel的栏目这些等等。还是那句话,util中的导出逻辑还可以继承修改,也更好的实现了扩展性。
public void exportExcel(String title, JSONArray jsonArray, List<Map<String, String>> eventRecordMapList, OutputStream out) { // 创建一个excel工作簿 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(title); // excel列默认宽度 sheet.setDefaultColumnWidth(20); // 第一行标题样式(白字蓝底) HSSFCellStyle titleStyle = workbook.createCellStyle(); HSSFPalette palette = workbook.getCustomPalette(); palette.setColorAtIndex((short) 63, (byte) (50), (byte) (126), (byte) (179)); titleStyle.setFillForegroundColor((short) 63); titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); HSSFFont font = workbook.createFont(); font.setColor(HSSFColor.WHITE.index); font.setFontHeightInPoints((short) 12); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); titleStyle.setFont(font); titleStyle.setWrapText(false); // 内容行样式 (白底黑字) HSSFCellStyle contentStyle = workbook.createCellStyle(); contentStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); contentStyle.setFillForegroundColor(HSSFColor.WHITE.index); contentStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); contentStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); contentStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); contentStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); contentStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT); contentStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); HSSFFont font2 = workbook.createFont(); font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); contentStyle.setFont(font2); contentStyle.setWrapText(true); HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5)); comment.setString(new HSSFRichTextString("数据列表")); comment.setAuthor("csh"); // 填充标题,就是第一行啦 HSSFRow row = sheet.createRow(0); row.setHeight((short) 500); for (short i = 0; i < jsonArray.length(); i++) { HSSFCell cell = row.createCell(i); cell.setCellStyle(titleStyle); JSONObject jsonObject = jsonArray.getJSONObject(i); HSSFRichTextString text = new HSSFRichTextString(jsonObject.getString("headerName")); cell.setCellValue(text); } // 填充内容行,就是除第一行外的所有行,从第二行开始 for (int i = 0; i < eventRecordMapList.size(); i++) { row = sheet.createRow(i + 1); row.setHeight((short) 350); Map<String, String> eventRecordMap = eventRecordMapList.get(i); for (int j = 0; j < jsonArray.length(); j++) { JSONObject jsonObject = jsonArray.getJSONObject(j); HSSFCell cell = row.createCell(j); cell.setCellStyle(contentStyle); try { String textValue = eventRecordMap.get(jsonObject.getString("header")); if (textValue != null) { Pattern p = Pattern.compile("^//d+(//.//d+)?$"); // 匹配是否是数值类型 Matcher matcher = p.matcher(textValue); if (matcher.matches()) { cell.setCellValue(Double.parseDouble(textValue)); } else { HSSFRichTextString richString = new HSSFRichTextString(textValue); HSSFFont font3 = workbook.createFont(); font3.setColor(HSSFColor.BLACK.index); richString.applyFont(font3); cell.setCellValue(richString); } } } catch (Exception e) { e.printStackTrace(); } finally { } } } try { workbook.write(out);// 将excel工作簿写入到输出流中 // workbook.close();//关闭 } catch (IOException e) { e.printStackTrace(); } }
java web 导出Excel 的工具类公用实现的更多相关文章
- 使用Apache poi来编写导出excel的工具类
在JavaWeb开发的需求中,我们会经常看到导出excel的功能需求,然后java并没有提供操作office文档的功能,这个时候我们就需要使用额外的组件来帮助我们完成这项功能了. 很高兴Apache基 ...
- 使用POI插件,提取导出excel的工具类
在网站的不同的模块都需要使用到导入导出excel的功能,我们就需要写一个通用的工具类ExcelUtil. 我的思路:首先,导入和导出的Excel的文件格式固定:主标题,二级标题,数据行(姑且就这么叫) ...
- POI导入导出excel(附工具类)
关于POI导出excel的功能我在前面的文章已经写过了,POI导出excel的三种方式 , 导出表格数据到excel并下载(HSSFWorkbook版) ,本篇文章主要是将导入导出功能进一步地封装,在 ...
- 导出excel文件工具类
package com.rrz.common.utils.excel; import java.io.IOException;import java.io.OutputStream;import ja ...
- 导出excel(利用工具类导出excel)
/** * 添加导出功能 * @param creditPageResult * @param request * @param response */ @RequestMapping(value = ...
- Excel导入工具类兼容xls和xlsx
package com.bj58.finance.platform.operation.provider.util; import org.apache.log4j.Logger; import or ...
- java里poi操作excel的工具类(兼容各版本)
转: java里poi操作excel的工具类(兼容各版本) 下面是文件内具体内容,文件下载: import java.io.FileNotFoundException; import java.io. ...
- 重构:以Java POI 导出EXCEL为例
重构 开头先抛出几个问题吧,这几个问题也是<重构:改善既有代码的设计>这本书第2章的问题. 什么是重构? 为什么要重构? 什么时候要重构? 接下来就从这几个问题出发,通过这几个问题来系统的 ...
- 由需求而产生的一款db导出excel的工具
代码地址如下:http://www.demodashi.com/demo/12062.html 程序员最大的毛病可能就是懒,因为懒所以做出了许许多多提高自己工作效率的工具. 起因于我是商业开发,既然是 ...
随机推荐
- linux下处理excel里copy的某列的字符串,去除行末空格并添加特殊字段
背景:从excel里copy出一列数据到txt,然后放到linux下处理,发现每一行末尾都是固定个数的空格,我想要在每行字符串末尾加固定字段并逗号隔开输出, 1.将特定字段取出,去掉每行末尾的不定个数 ...
- Oracle14~23
14.查询所有学生的Sname.Cno和Degree列. 15.查询所有学生的Sno.Cname和Degree列. 16.查询所有学生的Sname.Cname和Degree列. 17. 查询“9503 ...
- .Net面试葵花宝典
1. 面向对象的特征有哪些方面 抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中 ...
- SQLite 数据库
内容来源:高成珍.钟元生<Android编程经典案例解析> SQLite 数据库是Android 中内嵌的轻量级关系型数据库,本质上只是一个文件.SQLite 内部只支持NULL,INTE ...
- BZOJ2818 与 BZOJ2301【euler,线性筛,莫比乌斯】
题目大意: 给一个范围[1,n],从中找出两个数x,y,使得gcd(x,y)为质数,问有多少对(x,y有序) 解法: 不难,欧拉函数练手题,可以定义集合P ={x|x为素数},那么我们枚举gcd(x, ...
- Python 列表(List) 的三种遍历(序号和值)方法
三种遍历列表里面序号和值的方法: 最近学习python这门语言,感觉到其对自己的工作效率有很大的提升,特在情人节这一天写下了这篇博客,下面废话不多说,直接贴代码 #!/usr/bin/env pyth ...
- Xamarin GitHub 下载的源码运行不了
初学Xamarin ,各种折腾,大概这公司破电脑配置差,老是很多问题. GitHub 真是个好东西,可以参考别人做的,不过下载来运行不了就各种折腾了,为此我重装电脑两次了,反正win10安装就十几分 ...
- Oracle自动备份.bat 最新更新(支持Win10了)
20170418更新: 很多年没有用了,最近两天打开来用,发现在Win10下面At命令已经被淘汰不能使用了,还有不少命令工作方式和原来也不一样了 所以就更新了一下下,使用 schtasks 命令代替了 ...
- angular 自定义filter
用modul.filter .filter("fiilterCity",function(){ return function(obj){ var newObj = []; ang ...
- Elasticsearch搜索之best_fields分析
顾名思义,best_field就是获取最佳匹配的field,另个可以通过tie_breaker来控制其他field的得分,boost可以设置权重(默认都为1). 下面从宏观上来讲的简单公式: scor ...