POI导出表格到浏览器工具类
要封装的实体bean类
public class Question {
private String id; //题目ID
private String companyId; //所属企业
private String catalogId; //题目所属目录ID
private String remark; //题目简介
private String subject; //题干
private String picture; //图片
private String analysis; //题目分析
private String type; //题目类型 1:单选,2:多选,3:简答
private String difficulty; //难易程度: 1极易 2容易 3普通 4困难 5极难
private String isClassic; //是否经典面试题 0:否 1:是
private String state; //题目状态 0:不可用 1:可用(只有审核通过的题目才可以设置)
private String reviewStatus;//审核状态 -1 审核不通过 0 审核中 1 审核通过
// 如果要进行的是多表查询,你需要提供对象的属性值和想要对象那个值的get方法
private Company company;
private Catalog catalog;
public String getCatelogName() {
return catalog.getName();
}
public String getCompanyName() {
return company.getName();
}
业务层使用代码
// 调用查询全部方法,由持久层提供查询的数据集合
List<Question> questions = questionMapper.findAll();
// 创建excl导出对象工厂类
PoiFactory poiFactory = new PoiFactory();
// 准备要导出的数据和表头
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("id", "题目ID");
linkedHashMap.put("companyName", "所属企业名称");
linkedHashMap.put("catelogName", "题目所属目录名称");
linkedHashMap.put("remark", "题目简介");
linkedHashMap.put("subject", "题干");
linkedHashMap.put("picture", "图片");
linkedHashMap.put("analysis", "题目分析");
linkedHashMap.put("type", "题目类型 1:单选,2:多选,3:简答");
linkedHashMap.put("difficulty", "难易程度: 1极易 2容易 3普通 4困难 5极难");
linkedHashMap.put("isClassic", "是否经典面试题 0:否 1:是");
linkedHashMap.put("state", "题目状态 0:不可用 1:可用");
linkedHashMap.put("reviewStatus", "审核状态 -1 审核不通过 0 审核中 1 审核通过");
// 设置表头名字
poiFactory.setHeaderName("在线试题导出信息");
// 返回传递给浏览器的ByteArrayOutputStream对象
ByteArrayOutputStream os = poiFactory.autoPioOs(questions, linkedHashMap, Question.class);
excl导出对象工厂类
public class PoiFactory {
// 定义题目名称和表头名称,如果未设置数据则使用空
private String wordName = "";
private String headerName = "";
/**
* 调用方法创建文件到服务器
* @param obj 可以调用持久层的方法得到一个list集合将集合传入
* @param map key为bean的属性值,value为你要设置的表头
* @param clazz 要传入bean的字节码对象
* @param <E>
*/
public <E> void autoPio(List<E> obj, LinkedHashMap<String, String> map, Class<E> clazz) {
// 创建工作簿
XSSFWorkbook work = new XSSFWorkbook();
// 创建工作表
XSSFSheet sheet = work.createSheet();
// 创建表头数据
XSSFRow row_1 = sheet.createRow(0);
XSSFCell cell_1_1 = row_1.createCell(0);
cell_1_1.setCellValue(headerName);
// 将map集合拆分
Set<String> list = map.keySet();
Object[] objects = map.values().toArray();
// 设置表头
String header;
// 第二行设置
XSSFRow row_2 = sheet.createRow(1);
for (int i = 0; i < objects.length; i++) {
header = (String) objects[i];
row_2.createCell(i).setCellValue(header);
}
// 制作数据区
// 循环集合创建集合的对象,每个对象为一行,每个对象里的值为一个单元格
try {
for (int i = 0; i < obj.size(); i++) {
E bean = clazz.newInstance();
bean = obj.get(i);
// 创建第几行
XSSFRow row = sheet.createRow(i + 2);
// 创建存储数据的集合
ArrayList<String> data = new ArrayList<>();
// 获取所有传入的方法并存入集合
for (String string : list) {
// 获取方法对应的PropertyDescriptor
PropertyDescriptor proDescriptor = new PropertyDescriptor(string, clazz);
// 获取方法
String invoke = (String) proDescriptor.getReadMethod().invoke(bean);
System.out.println(invoke);
// 将得到get方法的值存入集合
data.add(invoke);
}
// 将数据写入单元格中
for (int j = 0; j < data.size(); j++) {
row.createCell(j).setCellValue(data.get(j));
}
}
// 从内存写出到文件
work.write(new FileOutputStream(new File(wordName + ".xlsx")));
// 释放资源
work.close();
} catch (Exception e) {
System.out.println("调用autoPio方法制作数据区时出现异常");
throw new RuntimeException(e);
}
}
/**
* 调用方法创建文件将文件的字节流返回
* @param obj 可以调用持久层的方法得到一个list集合将集合传入
* @param map key为bean的属性值,value为你要设置的表头
* @param clazz 要传入bean的字节码对象
* @param <E>
* @return
*/
public <E> ByteArrayOutputStream autoPioOs(List<E> obj, LinkedHashMap<String, String> map, Class<E> clazz) {
// 创建工作簿
XSSFWorkbook work = new XSSFWorkbook();
// 创建工作表
XSSFSheet sheet = work.createSheet();
// 创建表头数据
XSSFRow row_1 = sheet.createRow(0);
XSSFCell cell_1_1 = row_1.createCell(0);
cell_1_1.setCellValue(headerName);
// 将map集合拆分
Set<String> list = map.keySet();
Object[] objects = map.values().toArray();
// 设置表头
String header;
// 第二行设置
XSSFRow row_2 = sheet.createRow(1);
for (int i = 0; i < objects.length; i++) {
header = (String) objects[i];
row_2.createCell(i).setCellValue(header);
}
// 制作数据区
// 循环集合创建集合的对象,每个对象为一行,每个对象里的值为一个单元格
ByteArrayOutputStream os = null;
try {
for (int i = 0; i < obj.size(); i++) {
E bean = clazz.newInstance();
bean = obj.get(i);
// 创建第几行
XSSFRow row = sheet.createRow(i + 2);
// 创建存储数据的集合
ArrayList<String> data = new ArrayList<>();
// 获取所有传入的方法并存入集合
for (String string : list) {
// 获取方法对应的PropertyDescriptor
PropertyDescriptor proDescriptor = new PropertyDescriptor(string, clazz);
// 获取方法
String invoke = (String) proDescriptor.getReadMethod().invoke(bean);
System.out.println(invoke);
// 将得到get方法的值存入集合
data.add(invoke);
}
// 将数据写入单元格中
for (int j = 0; j < data.size(); j++) {
row.createCell(j).setCellValue(data.get(j));
}
}
//输出时通过流的形式对外输出,包装对应的目标文件
// os = new FileOutputStream(new File(wordName + ".xlsx"));
os = new ByteArrayOutputStream();
// 从内存写出到文件
work.write(os);
// 释放资源
work.close();
} catch (Exception e) {
System.out.println("调用autoPioOs方法制作数据区时出现异常");
throw new RuntimeException(e);
}
// 返回流对象
return os;
}
public String getWordName() {
return wordName;
}
public void setWordName(String wordName) {
this.wordName = wordName;
}
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}
servlet返回到浏览器
try {
//返回的数据类型为文件xlsx类型
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
String fileName = new String("题目数据.xlsx".getBytes(),"iso8859-1");
response.addHeader("Content-Disposition","attachment;fileName="+fileName);
//生成报告的文件,然后传递到前端页面
ByteArrayOutputStream os = questionService.getReport();
// 创建浏览器响应输出流对象
ServletOutputStream sos = response.getOutputStream();
os.writeTo(sos);
sos.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}