本实例通过poi实现excel导出,实现会员数据的excle下载
0.导入maven依赖
<!-- POI相关的包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.9</version>
</dependency>
1.新建个实体SharedMember
/**
*/
package com.sml.sz.supplier.pojo;
import com.sml.sz.ExceVo;
import com.sml.sz.common.persistence.NewDataEntity;
import org.hibernate.validator.constraints.Length;
import java.util.Date;
/**
* 会员共享Entity
*
* @author xxx
* @version 2018-10-15
*/
public class SharedMember{
private static final long serialVersionUID = 1L;
@ExceVo(name = "编号", sort = 1)
private String number; // 编号
@ExceVo(name = "姓名", sort = 2)
private String name; // 姓名
@ExceVo(name = "账号", sort = 3)
private String account; // 账号
@ExceVo(name = "来源", sort = 4)
private String source; // 来源
private String code; // 平台唯一编码
@ExceVo(name = "添加时间", sort = 5)
private Date createDate;// 添加时间
public SharedMember() {
super();
}
public SharedMember(String id) {
super(id);
}
@Length(min = 1, max = 64, message = "编号长度必须介于 1 和 64 之间")
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@Length(min = 1, max = 255, message = "姓名长度必须介于 1 和 255 之间")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Length(min = 1, max = 64, message = "账号长度必须介于 1 和 64 之间")
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
@Length(min = 1, max = 255, message = "来源长度必须介于 1 和 255 之间")
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
@Length(min = 1, max = 30, message = "平台唯一编码长度必须介于 1 和 30 之间")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(String date) {
this.createDate = super.createDate;
}
}
2.新建注解ExceVo
package com.sml.sz;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.TYPE })
public @interface ExceVo {
/** 对应的列名称 */
String name() default "";
/** 列序号 */
int sort();
/** 字段类型对应的格式 */
String format() default "";
/** 是否需要校验 */
boolean isCheck() default false;
/** 校验字段长度 */
int fieldLength() default 50;
/** 校验是否可以为空 */
boolean isEmpty() default true;
}
3.新建一个TestController
package com.sml.sz.supplier.controller;
import com.sml.sz.ExcelExportUtil;
import com.sml.sz.supplier.common.Message;
import com.sml.sz.supplier.pojo.SharedMember;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @author xxx
* @ClassName TestController
* @Description: todo
* @date 2020/7/3 17:05
* @Version 1.0
*/
public class TestController {
/**
* 会员导出
* @param response
* @throws IOException
*/
@RequestMapping(value = "export", method = { RequestMethod.POST, RequestMethod.GET })
public void list(HttpServletResponse response) throws IOException {
response.setContentType("application/binary;charset=ISO8859_1");
ServletOutputStream outputStream = response.getOutputStream();
String fileName = new String(("会员列表").getBytes(), "ISO8859_1");
// 组装附件名称和格式
response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");
//这里替换成自己的list就行
List<SharedMember> sharedMembers = sharedMemberService.findList(new SharedMember());
ExcelExportUtil<SharedMember> excelUtil = new ExcelExportUtil<SharedMember>(SharedMember.class);
excelUtil.export(sharedMembers, outputStream);
}
}
4.新建 ExcelExportUtil
package com.sml.sz;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.xssf.usermodel.*;
import javax.servlet.ServletOutputStream;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
public class ExcelExportUtil<T> {
private Class claze;
public ExcelExportUtil(Class claze) {
this.claze = claze;
}
/**
* 基于注解导出 不需要自己封装每列的值
*
* @param fileName
* 模板名称
* @param objs
* 导出实体集合
* @param rowIndex
* excel第几行开始导出
*/
public void export(List<T> objs, ServletOutputStream outputStream) {
// 带注解并排序好的字段
List<Field> fieldList = getFieldList();
// 创建一个workbook 对应一个excel应用文件
XSSFWorkbook workBook = new XSSFWorkbook();
// 在workbook中添加一个sheet,对应Excel文件中的sheet
XSSFSheet sheet = workBook.createSheet("Sheet1");
XSSFCellStyle headStyle = getHeadStyle(workBook);
XSSFCellStyle bodyStyle = getBodyStyle(workBook);
try {
// 构建表头
XSSFRow headRow = sheet.createRow(0);
XSSFCell cell = null;
for (int i = 0; i < fieldList.size(); i++) {
cell = headRow.createCell(i);
cell.setCellStyle(headStyle);
Field field = fieldList.get(i);
cell.setCellValue(getExcelHead(field));
}
// 构建表体数据
for (int j = 0; j < objs.size(); j++) {
XSSFRow bodyRow = sheet.createRow(j + 1);
T t = objs.get(j);
Class clazz = t.getClass();
for (int k = 0; k < fieldList.size(); k++) {
Field field = fieldList.get(k);
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
// 获取值之前先把日期类型转化成string
Map<String, Boolean> map = covertAttrType(field, t);
Method getMethod = pd.getReadMethod();
if (getMethod != null) {
cell = bodyRow.createCell(k);
cell.setCellStyle(bodyStyle);
for (Map.Entry<String, Boolean> entry : map.entrySet()) {
// 日期类型
if (entry.getValue() == true) {
cell.setCellValue(entry.getKey());
} else {
String stringCell=getMethod.invoke(t) == null ? "" : getMethod.invoke(t) + "";
if(!StringUtils.isBlank(stringCell)){
//如果excel内容是网络地址,需要单独处理,否则打不开excel
if(stringCell.contains("https")){
// 使用creationHelpper来创建XSSFHyperlink对象
CreationHelper createHelper = workBook.getCreationHelper();
XSSFHyperlink link = (XSSFHyperlink) createHelper.createHyperlink(Hyperlink.LINK_URL);
link.setAddress(stringCell);
// 设置超链接
cell.setHyperlink(link);
}
cell.setCellValue(stringCell);
}
}
}
}
}
}
workBook.write(outputStream);
outputStream.flush();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
outputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 设置表头的单元格样式
*
* @return
*/
public XSSFCellStyle getHeadStyle(XSSFWorkbook wb) {
// 创建单元格样式
XSSFCellStyle cellStyle = wb.createCellStyle();
// 设置单元格的背景颜色为淡蓝色
cellStyle.setFillForegroundColor(HSSFColor.PALE_BLUE.index);
cellStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
// 设置单元格居中对齐
cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 设置单元格垂直居中对齐
cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
// 创建单元格内容显示不下时自动换行
cellStyle.setWrapText(true);
// 设置单元格字体样式
XSSFFont font = wb.createFont();
// 设置字体加粗
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
font.setFontName("宋体");
font.setFontHeight((short) 200);
cellStyle.setFont(font);
// 设置单元格边框为细线条
cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
return cellStyle;
}
/**
* 设置表体的单元格样式
*
* @return
*/
public XSSFCellStyle getBodyStyle(XSSFWorkbook wb) {
// 创建单元格样式
XSSFCellStyle cellStyle = wb.createCellStyle();
// 设置单元格居中对齐
cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 设置单元格垂直居中对齐
cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
// 创建单元格内容显示不下时自动换行
cellStyle.setWrapText(true);
// 设置单元格字体样式
XSSFFont font = wb.createFont();
// 设置字体加粗
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
font.setFontName("宋体");
font.setFontHeight((short) 200);
cellStyle.setFont(font);
// 设置单元格边框为细线条
cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
return cellStyle;
}
/**
* 获取带注解的字段 并且排序
*
* @return
*/
private List<Field> getFieldList() {
Field[] fields = getAllFields(this.claze);
// 无序
List<Field> fieldList = new ArrayList<Field>();
// 排序后的字段
List<Field> fieldSortList = new LinkedList<Field>();
int length = fields.length;
int sort = 0;
Field field = null;
// 获取带注解的字段
for (int i = 0; i < length; i++) {
field = fields[i];
if (field.isAnnotationPresent(ExceVo.class)) {
fieldList.add(field);
}
}
// Assert.assertNotNull("未获取到需要导出的字段", fieldList);
length = fieldList.size();
for (int i = 1; i <= length; i++) {
for (int j = 0; j < length; j++) {
field = fieldList.get(j);
ExceVo exceVo = field.getAnnotation(ExceVo.class);
field.setAccessible(true);
sort = exceVo.sort();
if (sort == i) {
fieldSortList.add(field);
continue;
}
}
}
return fieldSortList;
}
/**
* 获取所有属性包括父类
*
* @param object
* @return
*/
public static Field[] getAllFields(Class clazz) {
List<Field> fieldList = new ArrayList<>();
while (clazz != null) {
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
clazz = clazz.getSuperclass();
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
/**
* 类型转换把date类型转为String
*/
public Map<String, Boolean> covertAttrType(Field field, T obj) {
Map<String, Boolean> map = new HashMap<String, Boolean>();
try {
if (field.get(obj) == null) {
map.put("", false);
return map;
}
String type = field.getType().getSimpleName();
if ("Date".equals(type)) {
map.put(DateFormatUtils.format((Date) field.get(obj), "yyyy-MM-dd HH:mm:ss"), true);
return map;
} else {
map.put(field.get(obj).toString(), false);
return map;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取excel表头信息
*/
public String getExcelHead(Field field) {
if (null == field) {
return null;
}
ExceVo exceVo = field.getAnnotation(ExceVo.class);
return exceVo.name();
}
}
5.大功告成~