JavaWEB--POI之EXCEL操作、优化、封装详解系列(三)--万能POI之EXCEL导出工具--PoiExportUtil入门篇
2017-08-28 17:16
931 查看
前面讲完概述、原理以及helloworld,现在就讲下怎样的POI的EXCEL导出工具可以适用于各种情况吧。后面再做个优化分页的万能POI之EXCEL导出工具,本篇章先做个简单的万能POI之EXCEL导出工具(博主已经抽象成库,请于文末前去使用)。
文章结构:(1)面向JavaBean的导出工具;(2)面向List-Map结构的导出工具。
大家阅读了前篇就知道Excel报表导出之JSP方式就是这么简单了,查出数据直接对到jsp处理,样式也可以在制作excel模板时自定义,相当简单。但是我们要想当要导出大量数据的时候呢??难道我们也这样实时导出??这样一个正常系统而且在大量人使用的时候,对于系统的负载会非常非常高的,所以前篇我也给出了另一种方式:Excel报表导出之上传文件流方式。在这样的方式下,如何做出一个公用的适应各种情况的设计,这就是往后几篇文章要探讨的。
一、面向JavaBean的导出工具:
(一)设计的关键:
(1)兼容普通JavaBean;
(2)接口方法易用性;
(3)导出数据准确性;
(4)扩展性。
(二)基于POI抽象的关键步骤:
(1)设置表格标题
(2)设置标题栏
(3)设置内容栏(为了精确比对,需要给出标题栏对应的字段—DTO类(普通javabean)的属性)
(4)导出写入到流对象
(三)核心代码与demo:
准备实体:(一个普通的JavaBean)
package com.fuzhu.model; /** * Created by 符柱成 on 2017/8/24. */ public class Student { private int id; private String name; private String sex; public Student(int id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
工具代码:
package com.fuzhu.utils; /** * Created by 符柱成 on 2017/8/23. */ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import com.fuzhu.entity.Student; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class ExportBeanExcel<T> { /** * 这是一个通用的方法,利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出 * * title 表格标题名 * headersName 表格属性列名数组 * headersId 表格属性列名对应的字段---你需要导出的字段名(为了更灵活控制你想要导出的字段) * dtoList 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象 * out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中 */ public void exportExcel(String title, List<String> headersName,List<String> headersId, List<T> dtoList) { /*(一)表头--标题栏*/ Map<Integer, String> headersNameMap = new HashMap<>(); int key=0; for (int i = 0; i < headersName.size(); i++) { if (!headersName.get(i).equals(null)) { headersNameMap.put(key, headersName.get(i)); key++; } } /*(二)字段*/ Map<Integer, String> titleFieldMap = new HashMap<>(); int value = 0; for (int i = 0; i < headersId.size(); i++) { if (!headersId.get(i).equals(null)) { titleFieldMap.put(value, headersId.get(i)); value++; } } /* (三)声明一个工作薄:包括构建工作簿、表格、样式*/ HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(title); sheet.setDefaultColumnWidth((short)15); // 生成一个样式 HSSFCellStyle style = wb.createCellStyle(); HSSFRow row = sheet.createRow(0); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); HSSFCell cell; Collection c = headersNameMap.values();//拿到表格所有标题的value的集合 Iterator<String> it = c.iterator();//表格标题的迭代器 /*(四)导出数据:包括导出标题栏以及内容栏*/ //根据选择的字段生成表头 short size = 0; while (it.hasNext()) { cell = row.createCell(size); cell.setCellValue(it.next().toString()); cell.setCellStyle(style); size++; } //表格标题一行的字段的集合 Collection zdC = titleFieldMap.values(); Iterator<T> labIt = dtoList.iterator();//总记录的迭代器 int zdRow =0;//列序号 while (labIt.hasNext()) {//记录的迭代器,遍历总记录 int zdCell = 0; zdRow++; row = sheet.createRow(zdRow); T l = (T) labIt.next(); // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 Field[] fields = l.getClass().getDeclaredFields();//获得JavaBean全部属性 for (short i = 0; i < fields.length; i++) {//遍历属性,比对 Field field = fields[i]; String fieldName = field.getName();//属性名 Iterator<String> zdIt = zdC.iterator();//一条字段的集合的迭代器 while (zdIt.hasNext()) {//遍历要导出的字段集合 if (zdIt.next().equals(fieldName)) {//比对JavaBean的属性名,一致就写入,不一致就丢弃 String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);//拿到属性的get方法 Class tCls = l.getClass();//拿到JavaBean对象 try { Method getMethod = tCls.getMethod(getMethodName, new Class[] {});//通过JavaBean对象拿到该属性的get方法,从而进行操控 Object val = getMethod.invoke(l, new Object[] {});//操控该对象属性的get方法,从而拿到属性值 String textVal = null; if (val!= null) { textVal = String.valueOf(val);//转化成String }else{ textVal = null; } row.createCell((short) zdCell).setCellValue(textVal);//写进excel对象 zdCell++; } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } } try { FileOutputStream exportXls = new FileOutputStream("E://工单信息表.xls"); wb.write(exportXls); exportXls.close(); System.out.println("导出成功!"); } catch (FileNotFoundException e) { System.out.println("导出失败!"); e.printStackTrace(); } catch (IOException e) { System.out.println("导出失败!"); e.printStackTrace(); } } /* 使用例子 */ public static void main(String [] args){ List<String> listName = new ArrayList<>(); listName.add("id"); listName.add("名字"); listName.add("性别"); List<String> listId = new ArrayList<>(); listId.add("id"); listId.add("name"); listId.add("sex"); List<Student> list = new ArrayList<>(); list.add(new Student(111,"张三asdf","男")); list.add(new Student(111,"李四asd","男")); list.add(new Student(111,"王五","女")); ExportBeanExcel<Student> exportBeanExcelUtil = new ExportBeanExcel(); exportBeanExcelUtil.exportExcel("测试POI导出EXCEL文档",listName,listId,list); } }
(四)工具注意点:
(1)应用泛型,代表任意一个符合javabean风格的类
(2)注意这里为了简单起见,boolean型的属性xxx的get器方式为getXxx(),而不是isXxx()
(3) T这里代表一个不确定是实体类,即参数实体
二、面向List-Map结构的导出工具:
(一)设计的关键:
(1)兼容普通List-Map结构;
(2)接口方法易用性;
(3)导出数据准确性;
(4)扩展性。
(二)基于POI抽象的关键步骤:
(1)设置表格标题
(2)设置标题栏
(3)设置内容栏(为了精确比对,需要给出标题栏对应的字段—dtoList(List-Map结构中的key))
(4)导出写入到流对象
(三)核心代码与demo:
package com.fuzhu.utils; import org.apache.poi.hssf.usermodel.*; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.*; /** * Created by 符柱成 on 2017/8/24. */ public class ExportMapExcel { public void exportExcel(String title, List<String> headersName, List<String> headersId, List<Map<String, Object>> dtoList) { /* (一)表头--标题栏 */ Map<Integer, String> headersNameMap = new HashMap<>(); int key = 0; for (int i = 0; i < headersName.size(); i++) { if (!headersName.get(i).equals(null)) { headersNameMap.put(key, headersName.get(i)); key++; } } /* (二)字段---标题的字段 */ Map<Integer, String> titleFieldMap = new HashMap<>(); int value = 0; for (int i = 0; i < headersId.size(); i++) { if (!headersId.get(i).equals(null)) { titleFieldMap.put(value, headersId.get(i)); value++; } } /* (三)声明一个工作薄:包括构建工作簿、表格、样式 */ HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(title); sheet.setDefaultColumnWidth((short) 15); // 生成一个样式 HSSFCellStyle style = wb.createCellStyle(); HSSFRow row = sheet.createRow(0); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); HSSFCell cell; Collection c = headersNameMap.values();//拿到表格所有标题的value的集合 Iterator<String> headersNameIt = c.iterator();//表格标题的迭代器 /* (四)导出数据:包括导出标题栏以及内容栏 */ //根据选择的字段生成表头--标题 short size = 0; while (headersNameIt.hasNext()) { cell = row.createCell(size); cell.setCellValue(headersNameIt.next().toString()); cell.setCellStyle(style); size++; } //表格一行的字段的集合,以便拿到迭代器 Collection zdC = titleFieldMap.values(); Iterator<Map<String, Object>> titleFieldIt = dtoList.iterator();//总记录的迭代器 int zdRow = 1;//真正的数据记录的列序号 while (titleFieldIt.hasNext()) {//记录的迭代器,遍历总记录 Map<String, Object> mapTemp = titleFieldIt.next();//拿到一条记录 row = sheet.createRow(zdRow); zdRow++; int zdCell = 0; Iterator<String> zdIt = zdC.iterator();//一条记录的字段的集合的迭代器 while (zdIt.hasNext()) { String tempField =zdIt.next();//字段的暂存 if (mapTemp.get(tempField) != null) { row.createCell((short) zdCell).setCellValue(String.valueOf(mapTemp.get(tempField)));//写进excel对象 zdCell++; } } } try { FileOutputStream exportXls = new FileOutputStream("E://工单信息表Map.xls"); wb.write(exportXls); exportXls.close(); System.out.println("导出成功!"); } catch (FileNotFoundException e) { System.out.println("导出失败!"); e.printStackTrace(); } catch (IOException e) { System.out.println("导出失败!"); e.printStackTrace(); } } public static void main(String [] args) { List<String> listName = new ArrayList<>(); listName.add("id"); listName.add("名字"); listName.add("性别"); List<String> listId = new ArrayList<>(); listId.add("id"); listId.add("name"); listId.add("sex"); List<Map<String,Object>> listB = new ArrayList<>(); for (int t=0;t<6;t++){ Map<String,Object> map = new HashMap<>(); map.put("id",t); map.put("name","abc"+t); map.put("sex","男"+t); listB.add(map); } System.out.println("listB : "+listB.toString()); ExportMapExcel exportExcelUtil = new ExportMapExcel(); exportExcelUtil.exportExcel("测试POI导出EXCEL文档",listName,listId,listB); } }
(四)工具注意点:
(1)面向的是List-Map数据结构,请不要注入别的数据结构
(2)方法参数说明:
1)title是:表格的名称2)headersName标题栏的文字
3)headersId:对应标题栏的字段,为了准确导出到对应列而设计
4)dtoList:我们要导出的所有数据(把数据封装在dtoList数据传输对象中)
(3)此处的入门篇工具兼容性并不很好,只是讲解了工具的核心。博客抽象的工具是已这两个demo工具为基准点去设计的。
本篇的demo源码下载:JavaWEB–POI之EXCEL操作、优化、封装详解系列(三)万能POI之EXCEL导出工具–PoiExportUtil入门篇
POI辅助库:POI辅助库
好了,JavaWEB–POI之EXCEL操作、优化、封装详解系列(三)万能POI之EXCEL导出工具–PoiExportUtil入门篇讲完了,这是自己设计的第一个java工具库,并且抽象作为开源工具了,在这里写出来记录,这是积累的必经一步,我会继续出这个系列文章,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!!
更多内容,可以访问JackFrost的博客
相关文章推荐
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(二)--导入导出helloworld(对比JXL库)
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(一)--概述与原理
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(五)--PoiExportUtil使用文档(1)
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(六)--PoiExportUtil使用文档(2)分页
- JavaWEB--POI之EXCEL操作、优化、封装详解系列(四)--PoiExportUtil架构设计篇与功能说明
- 详解JAVA POI导出EXCEL报表的操作(包括各种格式及样式的实现)
- 详解JAVA POI导出EXCEL报表的操作(包括各种格式及样式的实现)
- java简易excel导入导出工具(封装POI)
- java实现excel的导入导出(poi详解)[转]
- java操作poi导出Excel
- Java使用POI将数据导出到Excel的工具方法
- Java通过POI技术操作Excel(3)----数据导出
- java实现excel的导入导出(poi详解)
- java实现excel的导入导出(poi详解)
- javaweb 利用poi 导出excel
- Java程序员从笨鸟到菜鸟之(一百零五)java操作office和pdf文件(三)利用jxl实现数据导出excel报表以及与POI的区别
- java使用jxl工具导入导出excel操作
- JXL(针对Excel操作)系列之四:简单的(WEB)导出操作
- java操作poi导出Excel2
- java通过POI技术操作Excel(1)----模板导出