此导出工具类借鉴了一些大神的写法以及结合自己业务上的需求
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;
import java.awt.*;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
public class ExcelUtil {
/**
* @param title:sheet名称
* @param propertyHeaderMap:()
* 用LinkedHashMap保证读取的顺序和put的顺序一样
* @param dataSet:实体类集合
* @description: 适用于单表导出
* @author: xch
* @date: 2018/5/23 9:38
* 根据输入的数据生成一个XSSFWorkbook
* @return:XSSFWorkbook
*/
public static <T> XSSFWorkbook generateXlsxWorkbook(String title, LinkedHashMap<String, String> propertyHeaderMap, Collection<T> dataSet) {
// 声明一个工作薄
XSSFWorkbook workbook = new XSSFWorkbook();
// 生成一个表格
XSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为20个字节
sheet.setDefaultColumnWidth((int) 20);
XSSFCellStyle headerStyle = getHeaderStyle(workbook);
XSSFCellStyle contentStyle = getContentStyle(workbook);
// 生成表格标题行
XSSFRow row = sheet.createRow(0);
int i = 0;
//传过来的map设置表头
for (String key: propertyHeaderMap.keySet()) {
XSSFCell cell = row.createCell(i);
cell.setCellStyle(headerStyle);
XSSFRichTextString text = new XSSFRichTextString(propertyHeaderMap.get(key));
cell.setCellValue(text);
i++;
}
//循环dataSet,每一条对应一行
int index = 0;
for (T data: dataSet) {
index++;
row = sheet.createRow(index);
int j = 0;
for (String property: propertyHeaderMap.keySet()) {
XSSFCell cell = row.createCell(j);
cell.setCellStyle(contentStyle);
//拼装getter方法名 //toUpperCase()英文字符转换为大写字母,例如P+kId;完成拼出:getPkId
String getMethodName = "get" + property.substring(0, 1).toUpperCase() + property.substring(1);
try {
//利用反射机制获取dataSet中的属性值,填进cell中
Class<? extends Object> tCls = data.getClass();
Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
Object value = getMethod.invoke(data, new Object[]{}); //调用getter从data中获取数据
// 判断值的类型后进行类型转换
String textValue = null;
if (value != null) {
if (value instanceof Double) {
//double类型如果小数点后为零显示整数,否则保留
if ((Double) value % 1.0 == 0) {
textValue = String.valueOf(((Double) value).longValue());
} else {
textValue = value.toString();
}
} else if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
textValue = sdf.format(date);
} else {
// 其它数据类型都当作字符串简单处理
textValue = value.toString();
}
} else {
textValue = "";
}
XSSFRichTextString richString = new XSSFRichTextString(textValue);
cell.setCellValue(richString);
} catch (Exception e) {
e.printStackTrace();
}
j++;
}
}
return workbook;
}
public static <T> XSSFWorkbook generateXlsxWorkbook(String title, LinkedHashMap<String, String> propertyHeaderMap, Collection<T> dataSet, Map<String, Object[]> map) {
// 声明一个工作薄
XSSFWorkbook workbook = new XSSFWorkbook();
// 生成一个表格
XSSFSheet sheet = workbook.createSheet(title);
// 设置表格默认列宽度为20个字节
sheet.setDefaultColumnWidth((int) 20);
XSSFCellStyle headerStyle = getHeaderStyle(workbook);
XSSFCellStyle contentStyle = getContentStyle(workbook);
// 生成表格标题行
XSSFRow row = sheet.createRow(0);
int i = 0;
//传过来的map设置表头
for (String key: propertyHeaderMap.keySet()) {
XSSFCell cell = row.createCell(i);
cell.setCellStyle(headerStyle);
XSSFRichTextString text = new XSSFRichTextString(propertyHeaderMap.get(key));
cell.setCellValue(text);
i++;
}
//循环dataSet,每一条对应一行
int index = 0;
for (T data: dataSet) {
index++;
row = sheet.createRow(index);
int j = 0;
for (String property: propertyHeaderMap.keySet()) {
XSSFCell cell = row.createCell(j);
cell.setCellStyle(contentStyle);
//拼装getter方法名 //toUpperCase()英文字符转换为大写字母,例如P+kId
String getMethodName = "get" + property.substring(0, 1).toUpperCase() + property.substring(1);
try {
//利用反射机制获取dataSet中的属性值,填进cell中
Class<? extends Object> tCls = data.getClass();
Method getMethod = tCls.getMethod(getMethodName, new Class[]{});
Object value = getMethod.invoke(data, new Object[]{}); //调用getter从data中获取数据
int a = 0;
int b = 0;
if (map != null) {
if (map.get(property) != null) {
a = Integer.parseInt(value.toString());
b = map.get(property).length;
for (int n = 0; n < b; n++) {
value = map.get(property)[a];
}
}
}
// 判断值的类型后进行类型转换
String textValue = null;
if (value != null) {
if (value instanceof Double) {
//double类型如果小数点后为零显示整数,否则保留
if ((Double) value % 1.0 == 0) {
textValue = String.valueOf(((Double) value).longValue());
} else {
textValue = value.toString();
}
} else if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
textValue = sdf.format(date);
} else {
// 其它数据类型都当作字符串简单处理
textValue = value.toString();
}
} else {
textValue = "";
}
XSSFRichTextString richString = new XSSFRichTextString(textValue);
cell.setCellValue(richString);
} catch (Exception e) {
e.printStackTrace();
}
j++;
}
}
return workbook;
}
/**
* @param workbook
* @return style
* @description: 生成一个标题style
* @author: xch
* @date: 2018/5/23 9:39
*/
public static XSSFCellStyle getHeaderStyle(XSSFWorkbook workbook) {
return getHeaderStyle(workbook, Color.WHITE, IndexedColors.BLACK.getIndex());
}
/**
* @param workbook
* @param foregroundColor
* @param fontColor
* @description: 生成一个指定颜色的标题style
* @author: xch
* @date: 2018/5/23 9:39
*/
public static XSSFCellStyle getHeaderStyle(Workbook workbook, Color foregroundColor, short fontColor) {
// 生成一个样式(用于标题)
XSSFCellStyle style = (XSSFCellStyle) workbook.createCellStyle();
// 设置这些样式
style.setFillForegroundColor(new XSSFColor(foregroundColor));
style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 生成一个字体
XSSFFont font = (XSSFFont) workbook.createFont();
font.setColor(fontColor);
font.setFontHeightInPoints((short) 12);
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
/**
* @param workbook
* @return
* @description: 生成一个用于内容的style
* @author: xch
* @date: 2018/5/23 9:39
*/
public static XSSFCellStyle getContentStyle(XSSFWorkbook workbook) {
// 生成并设置另一个样式(用于内容)
XSSFCellStyle style = (XSSFCellStyle) workbook.createCellStyle();
//style.setFillForegroundColor(new XSSFColor(Color.YELLOW));
//style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
style.setBorderRight(XSSFCellStyle.BORDER_THIN);
style.setBorderTop(XSSFCellStyle.BORDER_THIN);
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
// 生成另一个字体
XSSFFont font = (XSSFFont) workbook.createFont();
font.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
// 把字体应用到当前的样式
style.setFont(font);
return style;
}
}
1、第一个参数为excel的title名字
2、第二个参数选择LinkedHashMap的原因在于内部维持了一个双向链表,可以保持顺序;map的键 必须和实体类的属性名称一致,
值为导出excel的表头名称
3、第三个参数为导出数据的集合
Map<String, Object> temp = new HashMap();
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("folderName", "订单号");
map.put("customerName", "客户名");
map.put("housingAddress", "客户地址");
map.put("fileNumber", "文件数");
map.put("createName", "创建人");
map.put("createTime", "创建时间");
XSSFWorkbook ex = ExcelUtil.generateXlsxWorkbook("文档中心", map, fileFolderList);
一些特别的业务有很多种状态,数据库查询返回的都是int型的数字,每一个数字代表不同的状态,这时候就需要第四个参数了:将返回状态的int型数字作为下标来将状态转为需要导出的内容
Map<String, Object> temp = new HashMap();
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("po.orderNumber", "订单编号");
map.put("name", "销售");
map.put("area", "门店");
map.put("customerName", "客户");
map.put("customerPhone", "客户电话");
map.put("price", "已收金额");
map.put("po.pactPrices", "订单金额");
map.put("po.billType", "状态");
map.put("po.startTime", "进场时间");
map.put("po.endTime", "出场时间");
map.put("po.createTime", "录入时间");
map.put("po.updateTime", "更新时间");
String[] billType = {"已取消", "正常", "草稿", "正在等待删除审核", "正在生产审核的"};
Map<String, Object[]> types = new LinkedHashMap<>();
types.put("po.billType", billType);
XSSFWorkbook ex = ExcelUtilDTO.generateXlsxWorkbook("取消订单列表", map, podList, types);
String path = ServletActionContext.getServletContext().getRealPath("/") + "excel";
String fileName = "取消订单报表" + UUID.randomUUID().toString() + ".xlsx";
File file = new File(path);
if (!file.exists()) {
file.mkdir();
}
OutputStream out = new FileOutputStream(file.getPath() + File.separator + fileName);
BufferedOutputStream bos = new BufferedOutputStream(out);
ex.write(bos);