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 程序员最大的毛病可能就是懒,因为懒所以做出了许许多多提高自己工作效率的工具. 起因于我是商业开发,既然是 ...
随机推荐
- 深入PHP变量存储结构 标签: PHP存储
1.深入PHP变量存储结构 标签: PHP存储 分类: 编程语言(10) 首先声明,我并没有去读PHP的源码,只是对于PHP的有时候诡异的表现感兴趣,找了一下开发人员laruence的博客结合PH ...
- 老李推荐:第6章4节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-翻译命令字串
老李推荐:第6章4节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-翻译命令字串 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自 ...
- SQL语句中的日期查询
我们先创建一个表: CREATE TABLE `student` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(10) NULL COMMEN ...
- MongoDB基础教程系列--第五篇 MongoDB 映射与限制记录
上一篇提到的 find() 的方法,细心的伙伴会发现查询的结果都是显示了集合中全部的字段,实际应用中,显然是不够用的.那么有没有办法指定特定的字段显示出文档呢?答案是肯定的,MongoDB 中用映射实 ...
- js根据条件json生成随机json:randomjson
前端开发中,在做前后端分离的时候,经常需要手写json数据,有3个问题特别揪心: 1,数据是写死的,不能按一定的条件随机生成长度不一,内容不一的数据 2,写数组的时候,如果有很多条,需要一条一条地写, ...
- Angular2入门-数据绑定
▓▓▓▓▓▓ 大致介绍 Angular2中数据绑定的方式默认是以单向方式,数据绑定的方式可以分为: 1.属性绑定和插值表达式 组件类-> 模板 2.事件绑定:模板 -> 组件类 3.双向绑 ...
- 浅谈css中单位px和em,rem的区别-转载
px是你屏幕设备物理上能显示出的最小的一个点,这个点不是固定宽度的,不同设备上点的长宽.比例有可能会不同.假设:你现在用的显示器上1px宽=1毫米,但我用的显示器1px宽=两毫米,那么你定义一个div ...
- 学习MVC之租房网站(三)-编写实体类并创建数据库
在上一篇<学习MVC之租房网站(二)-框架搭建及准备工作>中,搭建好了项目框架,并配置了EF.Log4Net和进程外Session.接下来会编写Eneity类并采用CodeFirst的方式 ...
- SQL Server函数---Union与Union All的区别
SQL Server函数---Union与Union All的区别 如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字.union(或称 ...
- Java集合的区别和选择
Collection |--List 有序,可重复 |--ArrayList 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高 |--Vector 底层数据结构 ...