demo-project/杂项/excel导出.java

189 lines
6.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Description 支持多sheet表格
*
* @author fxb
* @Date 2018-08-23
*/
public class ExcelUtil {
private Logger log = LoggerFactory.getLogger(this.getClass());
/**
* 表格文件名
*/
private String fileName;
/**
* 表格数据项string为sheet名List<Object[]> 为这个sheet的数据
*/
private HashMap<String, List<?>> data;
/**
* 每个sheet的表头String为sheet名String[][] 为object的属性名与表头的对应关系,例如:["id","对象id"]
*/
private LinkedHashMap<String, String[][]> headers;
private static final String IE = "msie";
private static final String OPERA = "opera";
private static final String SAFARI = "safari";
private static final String FIREFOX = "mozilla";
public ExcelUtil(String fileName, HashMap<String, List<?>> data, LinkedHashMap<String, String[][]> headers) {
this.fileName = fileName;
this.data = data;
this.headers = headers;
}
/**
* Description 创建表格
*
* @return org.apache.poi.hssf.usermodel.HSSFWorkbook
* @author fxb
* @date 2018/8/23
*/
public SXSSFWorkbook createExcel() throws Exception {
try {
//只在内存中保留五百条记录,五百条之前的会写到磁盘上,后面无法再操作
SXSSFWorkbook workbook = new SXSSFWorkbook(500);
//遍历headers创建表格
for (String key : headers.keySet()) {
this.createSheet(workbook, key, headers.get(key), this.data.get(key));
}
return workbook;
} catch (Exception e) {
log.error("创建表格失败:{}", e.getMessage());
throw e;
}
}
public void writeToResponse(SXSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {
String userAgent = request.getHeader("User-Agent");
String fileName = "Excel-" + this.fileName + ".xls";
String encodeFileName = URLEncoder.encode(fileName, "UTF8");
// 如果没有userAgent则默认使用IE的方式进行编码
String rtn = "filename=\"" + encodeFileName + "\"";
if (userAgent != null) {
userAgent = userAgent.toLowerCase();
if (userAgent.contains(IE)) {
// IE浏览器只能采用URLEncoder编码
rtn = "filename=\"" + encodeFileName + "\"";
} else if (userAgent.contains(OPERA)) {
// Opera浏览器只能采用filename*
rtn = "filename*=UTF-8''" + encodeFileName;
} else if (userAgent.contains(SAFARI)) {
// Safari浏览器只能采用ISO编码的中文输出
rtn = "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\"";
} else if (userAgent.contains(FIREFOX)) {
// FireFox浏览器可以使用MimeUtility或filename*或ISO编码的中文输出
rtn = "filename*=UTF-8''" + encodeFileName;
}
}
String headStr = "attachment; " + rtn;
response.setContentType("APPLICATION/ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", headStr);
OutputStream out1 = response.getOutputStream();
workbook.write(out1);
}
/**
* 创建一个sheet
*
* @param workbook workbook
* @param sheetName 名称
* @param header 表头
* @param data 数据
*/
private void createSheet(SXSSFWorkbook workbook, String sheetName, String[][] header, List<?> data) throws Exception {
Sheet sheet = workbook.createSheet(sheetName);
// 单元行,单元格
Row row;
Cell cell;
//列数
int cellNum = header.length;
//设置表头
row = sheet.createRow(0);
for (int i = 0; i < cellNum; i++) {
cell = row.createCell(i);
String str = header[i][1];
cell.setCellValue(str);
//设置列宽为表头的宽度+4
sheet.setColumnWidth(i, (str.getBytes("utf-8").length + 6) * 256);
}
int rowNum = data.size();
if (rowNum == 0) {
return;
}
//获取Object 属性名与field属性的映射后面通过反射获取值来设置到cell
Field[] fields = data.get(0).getClass().getDeclaredFields();
Map<String, Field> fieldMap = new HashMap<>(fields.length);
for (Field field : fields) {
field.setAccessible(true);
fieldMap.put(field.getName(), field);
}
Object object;
for (int i = 0; i < rowNum; i++) {
row = sheet.createRow(i + 1);
object = data.get(i);
for (int j = 0; j < cellNum; j++) {
cell = row.createCell(j);
this.setCell(cell, object, fieldMap, header[j][0]);
}
}
}
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
/**
* 设置单元格,根据fieldName获取对应的Field类使用反射得到值
*
* @param cell cell
* @param obj obj
* @param fieldMap 属性名与Field的映射
* @param fieldName 属性名
*/
private void setCell(Cell cell, Object obj, Map<String, Field> fieldMap, String fieldName) throws Exception {
Field field = fieldMap.get(fieldName);
if(field == null){
throw new Exception("找不到 "+fieldName+" 数据项");
}
Object value = field.get(obj);
if (value == null) {
cell.setCellValue("");
} else {
switch (field.getGenericType().getTypeName()) {
case "java.lang.String":
cell.setCellValue((String) value);
break;
case "java.lang.Integer":
case "int":
cell.setCellValue((int) value);
break;
case "java.lang.Double":
case "double":
cell.setCellValue((double) value);
break;
case "java.util.Date":
cell.setCellValue(this.dateFormat.format((Date) value));
break;
default:
cell.setCellValue(obj.toString());
}
}
}
}