前面讲完概述、原理以及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
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> {
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
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
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()
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()
for (short i = 0
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)
Class tCls = l.getClass()
try {
Method getMethod = tCls.getMethod(getMethodName,
new Class[] {})
Object val = getMethod.invoke(l, new Object[] {})
String textVal = null
if (val!= null) {
textVal = String.valueOf(val)
}else{
textVal = null
}
row.createCell((short) zdCell).setCellValue(textVal)
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();
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)));
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是:表格的名称
4)dtoList:我们要导出的所有数据(把数据封装在dtoList数据传输对象中)
(3)此处的入门篇工具兼容性并不很好,只是讲解了工具的核心。博客抽象的工具是已这两个demo工具为基准点去设计的。
好了,JavaWEB–POI之EXCEL操作、优化、封装详解系列(三)万能POI之EXCEL导出工具–PoiExportUtil入门篇讲完了,这是自己设计的第一个java工具库,并且抽象作为开源工具了,在这里写出来记录,这是积累的必经一步,我会继续出这个系列文章,分享经验给大家。欢迎在下面指出错误,共同学习!!你的点赞是对我最好的支持!!!