使用EasyPoi导出Excel
Posted Beckoning737
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用EasyPoi导出Excel相关的知识,希望对你有一定的参考价值。
1、引入Java包依赖
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.2.0</version>
</dependency>
2、创建导出的Excel样式类:
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import cn.afterturn.easypoi.excel.export.styler.AbstractExcelExportStyler;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
/**
* @ClassName: ExcelExportMyStylerImpl
* @Description: 自定义报表导出样式,可以修改表头颜色,高度等
* @Author: sunt
* @Date: 2019/8/29 21:39
* @Version 1.0
**/
public class ExcelExportMyStylerImpl extends AbstractExcelExportStyler implements IExcelExportStyler
public ExcelExportMyStylerImpl(Workbook workbook)
super.createStyles(workbook);
@Override
public CellStyle getTitleStyle(short color)
CellStyle titleStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);// 加粗
titleStyle.setFont(font);
titleStyle.setAlignment(HorizontalAlignment.CENTER);// 居中
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
titleStyle.setFillForegroundColor(IndexedColors.AQUA.index);// 设置颜色
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setWrapText(true);
return titleStyle;
@SuppressWarnings("deprecation")
@Override
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp)
CellStyle style = workbook.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setDataFormat(STRING_FORMAT);
if (isWarp)
style.setWrapText(true);
return style;
@Override
public CellStyle getHeaderStyle(short color)
CellStyle titleStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);// 加粗
font.setColor(IndexedColors.RED.index);
font.setFontHeightInPoints((short) 11);
titleStyle.setFont(font);
titleStyle.setAlignment(HorizontalAlignment.CENTER);// 居中
titleStyle.setFillForegroundColor(IndexedColors.WHITE.index);// 设置颜色
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setWrapText(true);
return titleStyle;
@SuppressWarnings("deprecation")
@Override
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp)
CellStyle style = workbook.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setDataFormat(STRING_FORMAT);
if (isWarp)
style.setWrapText(true);
return style;
3、创建核心导出工具类
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.sunny.spring.boot.poi.common.ExcelExportMyStylerImpl;
import com.sunny.spring.boot.poi.pojo.StudentInfoBean;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
* @ClassName: ExcelExportUtil
* @Description: Exceld导出工具类
* @Author: sunt
* @Date: 2019/8/30 14:49
* @Version 1.0
**/
public class MyExcelExportUtil
/**
* Excel文件导出,导出的文件名默认为:headTitle+当前系统时间
* @param listData 要导出的list数据
* @param pojoClass 定义excel属性信息
* @param headTitle Excel文件头信息
* @param sheetName Excel文件sheet名称
* @param response
*/
public static void exportExcel(Collection<?> listData,Class<?> pojoClass, String headTitle, String sheetName, HttpServletResponse response)
ExportParams params = new ExportParams(headTitle, sheetName);
params.setHeight((short) 8);
params.setStyle(ExcelExportMyStylerImpl.class);
try
Workbook workbook = ExcelExportUtil.exportExcel(params, pojoClass, listData);
String fileName = headTitle + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
fileName = URLEncoder.encode(fileName, "UTF8");
response.setContentType("application/vnd.ms-excel;chartset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="+fileName + ".xls");
ServletOutputStream out=response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
catch (Exception e)
e.printStackTrace();
4、创建导出对象实体Bean
注意日期类型 注解内要加上: exportFormat = "yyyy-MM-dd hh:mm:ss"
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
* 学生基本信息表
* </p>
*
* @author sunt
* @since 2019-08-29
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("T_STUDENT")
public class StudentInfoBean implements Serializable
private static final long serialVersionUID = 1L;
/**
* 学号
*/
@TableId("ID")
@Excel(name = "学号", width = 20, orderNum = "1")
private String id;
/**
* 姓名
*/
@TableField("NAME")
@Excel(name = "姓名", width = 20, orderNum = "2")
private String name;
/**
* 性别(1:男 2:女)
* replace:导出是a_id,b_id 导入反过来,注意大括号里面单独引号引起来的
*/
@TableField("SEX")
@Excel(name = "性别", width = 20, replace = "男_1", "女_2" ,orderNum = "3")
private String sex;
/**
* 年龄
*/
@TableField("AGE")
@Excel(name = "年龄", width = 20, orderNum = "4")
private Integer age;
/**
* 出生日期
*/
@TableField("BIRTHDAY")
@Excel(name = "商品创建时间", width = 20, orderNum = "12",exportFormat = "yyyy-MM-dd hh:mm:ss")
private String birthday;
/**
* 入学时间
*/
@TableField("REGIST_DATE")
@Excel(name = "入学时间",width = 20,orderNum = "6")
private String registDate;
/**
* 学费
*/
@TableField("FEE")
@Excel(name = "学费", width = 20, orderNum = "7")
private BigDecimal fee;
属性字段 | 属性值 |
@TableField | 这个字段代表数据库表的字段 |
@Excel | name代表导出Excel列名称 |
@Excel | orderNum代表Excel列排在第几列 |
@Excel | replace一般数据库存的性别例如0和1,导出的值0展示为男性,女展示为女性 |
5、后台方法:
直接调用查询方法,返回给前台就OK
@RequestMapping("/exportStudent")
public void exportStudent(HttpServletResponse response)
try
List<StudentInfoBean> sutdentList = studentService.queryAllStudent();
MyExcelExportUtil.exportExcel(sutdentList,StudentInfoBean.class,"学生基本信息","新生入学信息",response);
catch (Exception e)
e.printStackTrace();
6、前台的方法
不能使用ajax方法,返回的是字符串,后台返回的是流,如果用ajax返回的是乱码,并且浏览器不下载
//导出excel
excel()
window.open("http://localhost:88/api/shop/shop/exportShop")
,
使用 easypoi 导出 excel 实现动态列,完美解决!
大家好。
说明
使用的是easypoi进行导出
行头是动态生成
依据key进行列匹配,进行数据填充
第一列进行纵向动态合并
自己的一个使用,记录一下
工具依赖
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>3.2.0</version>
</dependency>
实现效果
变更前样式

变更后样式

代码解析
动态生成列头
另外,搜索公众号GitHub猿后台回复“天猫”,获取一份惊喜礼包。
private List<ExcelExportEntity> dynamicNewAddExcel(Map<String, PlatformStatisParamRespData> paramInfo)
//表头的集合,用于添加表头
List<ExcelExportEntity> entityList = new ArrayList<>();
//ExcelExportEntity构造参数【第一个是列名头的统计字段,第二个是需要指定的一个key在填充数据的时候是需要根据这个key进行填充值,第三个参数是列宽】
ExcelExportEntity platformXh = new ExcelExportEntity("统计字段1", "statisKey1", 30);
//列的合并(纵向列的同名称会进行合并,效果见上图的平台名称的变化)
platformXh.setMergeVertical(true);
entityList.add(platformXh);
ExcelExportEntity statisDateXh = new ExcelExportEntity("统计字段2", "statisKey2", 30);
entityList.add(statisDateXh);
//参数信息--[用于动态拼接列头]
final Iterator<String> iterator = paramInfo.keySet().iterator();
while (iterator.hasNext())
final String paramKeyStr = iterator.next();
final String paramNameStr = paramInfo.get(paramKeyStr).getDataName();
//列头由参数汉字名称,参数key为列key
entityList.add(new ExcelExportEntity(paramNameStr, paramKeyStr, 30));
return entityList;
动态填充数据
private List<Map<String, Object>> dynamicListDataByKey(List<PlatformIncomeRespDTO> statisData)
//参数类型
final Set<String> statisParamKey = statisData.get(0).getParamInfo().keySet();
final List<String> statisDate = statisData.get(0).getStatisDate();
final int platformNum = statisData.size();
//最终的数据
List<Map<String, Object>> datas = new ArrayList<>();
for (int i = 0; i < platformNum; i++)
for (int j = 0; j < statisDate.size(); j++)
Map<String, Object> hashMap = new LinkedHashMap<>(10);
//这个是依据key进行数据的填充,(根据前面填写的statisKey1进行填充数据)
hashMap.put("statisKey1", statisData.get(i).getPlatformNickName());
String statisDateStr = statisDate.get(j);
//这个是依据key进行数据的填充,(根据前面填写的statisKey2进行填充数据)
hashMap.put("statisKey2", statisDateStr);
//参数的验证
for (String paramKey : statisParamKey)
for (BiPlatformStatisRespDTO paramData : statisData.get(i).getStatisData().get(j))
if (paramKey.equals(paramData.getParamKey()))
hashMap.put(paramData.getParamKey(), paramData.getValue() + "(" + paramData.getRateValue() + ")");
datas.add(hashMap);
return datas;
excel的导出
//statisData就是我们查询出来的数据
public void downloadPlatformIncomeContrast(List<PlatformIncomeRespDTO> statisData, HttpServletResponse response)
if (CollectionUtils.isEmpty(statisData))
return;
//获取参数信息
final Map<String, PlatformStatisParamRespData> paramInfo = statisData.get(0).getParamInfo();
//拼装列头
List<ExcelExportEntity> colList = this.dynamicNewAddExcel(paramInfo);
//数据拼装
List<Map<String, Object>> list = this.dynamicListDataByKey(statisData);
final String xlsFileName = DateHelper.getNowString(FormatUnit.yyyyMMddHHmmss, true) + ".xls";
final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), colList, list);
//动态合并纵列[mergeMap key列索引(从0开始),value依赖的列,没有传空,startRow 开始行(从零开始)]
//Map<Integer, int[]> mer = new HashMap<>();
//mer.put(0, new int[]);
//PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), mer, 1);
EasypoiUtil.downLoadExcel(xlsFileName, response, workbook);
EasypoiUtil工具类
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook)
try
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
catch (IOException e)
throw new RuntimeException(e.getMessage());
PlatformIncomeRespDTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlatformIncomeRespDTO implements Serializable
private static final long serialVersionUID = 1100499105160261425L;
/**
* 平台别名
*/
private String platformNickName;
/*统计时间*/
private List<String> statisDate;
/*查询参数信息--[用户收入来源统计导出使用]*/
private Map<String, PlatformStatisParamRespData> paramInfo;
/*统计数据*/
private List<List<BiPlatformStatisRespDTO>> statisData;
PlatformStatisParamRespData
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlatformStatisParamRespData implements Serializable
private static final long serialVersionUID = 4263523446154995471L;
/**
* 参数名称
*/
private String dataName;
/**
* 参数key
*/
private String dateKey;
/**
* 参数描述
*/
private String dateDesc;
BiPlatformStatisRespDTO
@Data
@AllArgsConstructor
public class BiPlatformStatisRespDTO implements Serializable
private static final long serialVersionUID = 6070471415344415351L;
@Excel(name = "统计字段", orderNum = "1")
private String param;
/**
* 参数的key
*/
private String paramKey;
/**
* 参数描述
*/
private String paramDesc;
private String startDate;
private String endDate;
@Excel(name = "统计数据", orderNum = "2")
private String value;
private String rateValue;
private Long id;
private Integer riseOrFall;
public BiPlatformStatisRespDTO(String startDate, String paramKey, String value)
this.paramKey = paramKey;
this.startDate = startDate;
this.value = value;
public BiPlatformStatisRespDTO()
测试用例
测试特殊说明
导出的结果有个控制,是在拼装的时候没有填充此数据,不影响整体效果。扩展:接私活儿
测试结果示例

测试数据json示例
[
"paramInfo":
"userCount":
"dataName": "用户数",
"dateDesc": "用户信息",
"dateKey": "userCount"
,
"friendsCount":
"dataName": "好友数",
"dateDesc": "好友信息",
"dateKey": "friendsCount"
,
"platformNickName": "aaa",
"statisData": [
[
"paramKey": "userCount",
"startDate": "2019-12-26",
"value": "100"
,
"paramKey": "friendsCount",
"startDate": "2019-12-26",
"value": "200"
],
[
"paramKey": "userCount",
"startDate": "2019-12-27",
"value": "300"
,
"paramKey": "friendsCount",
"startDate": "2019-12-27",
"value": "400"
]
],
"statisDate": [
"2019-12-26",
"2019-12-27"
]
,
"paramInfo":
"userCount":
"dataName": "用户数",
"dateDesc": "用户信息",
"dateKey": "userCount"
,
"friendsCount":
"dataName": "好友数",
"dateDesc": "好友信息",
"dateKey": "friendsCount"
,
"platformNickName": "bbb",
"statisData": [
[
"paramKey": "userCount",
"startDate": "2019-12-26",
"value": "500"
,
"paramKey": "friendsCount",
"startDate": "2019-12-26",
"value": "600"
],
[
"paramKey": "userCount",
"startDate": "2019-12-27",
"value": "700"
,
"paramKey": "friendsCount",
"startDate": "2019-12-27",
"value": "800"
]
],
"statisDate": [
"2019-12-26",
"2019-12-27"
]
]
测试用例代码 扩展:接私活必备
public class Simple
/**
* @Description: 拼接表头
* @Param: paramInfo :表头信息
* @return: java.util.List<cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity>
* @Author: peikunkun
* @Date: 2019/12/26 0026 上午 10:42
*/
private static List<ExcelExportEntity> dynamicNewAddExcel(Map<String, PlatformStatisParamRespData> paramInfo)
//表头的集合,用于添加表头
List<ExcelExportEntity> entityList = new ArrayList<>();
//ExcelExportEntity构造参数【第一个是列名头的统计字段,第二个是需要指定的一个key在填充数据的时候是需要根据这个key进行填充值,第三个参数是列宽】
ExcelExportEntity platformXh = new ExcelExportEntity("统计字段1", "statisKey1", 30);
//列的合并(纵向列的同名称会进行合并,效果见上图的平台名称的变化)
platformXh.setMergeVertical(true);
entityList.add(platformXh);
ExcelExportEntity statisDateXh = new ExcelExportEntity("统计字段2", "statisKey2", 30);
entityList.add(statisDateXh);
//参数信息--[用于动态拼接列头]
final Iterator<String> iterator = paramInfo.keySet().iterator();
while (iterator.hasNext())
final String paramKeyStr = iterator.next();
final String paramNameStr = paramInfo.get(paramKeyStr).getDataName();
//列头由参数汉字名称,参数key为列key
entityList.add(new ExcelExportEntity(paramNameStr, paramKeyStr, 30));
return entityList;
/**
* @Description: 拼接数据
* @Param: statisData :拼接数据
* @Author: peikunkun
* @Date: 2019/12/26 0026 上午 10:42
*/
private static List<Map<String, Object>> dynamicListDataByKey(List<PlatformIncomeRespDTO> statisData)
//参数类型
final Set<String> statisParamKey = statisData.get(0).getParamInfo().keySet();
final List<String> statisDate = statisData.get(0).getStatisDate();
final int platformNum = statisData.size();
//最终的数据
List<Map<String, Object>> datas = new ArrayList<>();
for (int i = 0; i < platformNum; i++)
for (int j = 0; j < statisDate.size(); j++)
Map<String, Object> hashMap = new LinkedHashMap<>(10);
//这个是依据key进行数据的填充,(根据前面填写的statisKey1进行填充数据)
hashMap.put("statisKey1", statisData.get(i).getPlatformNickName());
String statisDateStr = statisDate.get(j);
//这个是依据key进行数据的填充,(根据前面填写的statisKey2进行填充 数据)
hashMap.put("statisKey2", statisDateStr);
//参数的验证
for (String paramKey : statisParamKey)
for (BiPlatformStatisRespDTO paramData : statisData.get(i).getStatisData().get(j))
if (paramKey.equals(paramData.getParamKey()))
hashMap.put(paramData.getParamKey(), paramData.getValue() + "(" + paramData.getRateValue() + ")");
datas.add(hashMap);
return datas;
@Test
public void Administrator_84_20191226095523() throws IOException
System.out.println("欢迎使用单元测试方法【Administrator_84()_20191226095523】");
System.out.println("此方法测试描述:【】");
//拼装第一个数据---------------------------------------------------------------------
final PlatformIncomeRespDTO platformIncomeRespDTO1 = new PlatformIncomeRespDTO();
platformIncomeRespDTO1.setPlatformNickName("aaa");
//拼装时间维度
platformIncomeRespDTO1.setStatisDate(Lists.newArrayList("2019-12-26","2019-12-27"));
//拼装头信息
Map<String, PlatformStatisParamRespData> paramInfo1=new HashMap<>();
paramInfo1.put("userCount", new PlatformStatisParamRespData("用户数","userCount","用户信息"));
paramInfo1.put("friendsCount", new PlatformStatisParamRespData("好友数","friendsCount","好友信息"));
platformIncomeRespDTO1.setParamInfo(paramInfo1);
//拼装数据
final ArrayList<List<BiPlatformStatisRespDTO>> data1 = Lists.newArrayList();
data1.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-26","userCount","100"),new BiPlatformStatisRespDTO("2019-12-26","friendsCount","200")));
data1.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-27","userCount","300"),new BiPlatformStatisRespDTO("2019-12-27","friendsCount","400")));
platformIncomeRespDTO1.setStatisData(data1);
//拼装第二个数据---------------------------------------------------------------------
final PlatformIncomeRespDTO platformIncomeRespDTO2 = new PlatformIncomeRespDTO();
platformIncomeRespDTO2.setPlatformNickName("bbb");
//拼装时间维度
platformIncomeRespDTO2.setStatisDate(Lists.newArrayList("2019-12-26","2019-12-27"));
//拼装头信息
Map<String, PlatformStatisParamRespData> paramInfo2=new HashMap<>();
paramInfo2.put("userCount", new PlatformStatisParamRespData("用户数","userCount","用户信息"));
paramInfo2.put("friendsCount", new PlatformStatisParamRespData("好友数","friendsCount","好友信息"));
platformIncomeRespDTO2.setParamInfo(paramInfo2);
//拼装数据
final ArrayList<List<BiPlatformStatisRespDTO>> data2 = Lists.newArrayList();
data2.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-26","userCount","500"),new BiPlatformStatisRespDTO("2019-12-26","friendsCount","600")));
data2.add(Lists.newArrayList(new BiPlatformStatisRespDTO("2019-12-27","userCount","700"),new BiPlatformStatisRespDTO("2019-12-27","friendsCount","800")));
platformIncomeRespDTO2.setStatisData(data2);
final ArrayList<PlatformIncomeRespDTO> platformIncomeRespDTOS = Lists.newArrayList(platformIncomeRespDTO1, platformIncomeRespDTO2);
System.out.println(JSONObject.toJSONString(platformIncomeRespDTOS));
//拼装列头
List<ExcelExportEntity> colList = dynamicNewAddExcel(paramInfo2);
//数据拼装
List<Map<String, Object>> list = dynamicListDataByKey(platformIncomeRespDTOS);
//文件名称
final Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), colList, list);
//此功能与【拼装列头】中的 platformXh.setMergeVertical(true);功能效果一样,可直接使用 platformXh.setMergeVertical(true);进行纵向合并
//动态合并纵列[mergeMap key列索引(从0开始),value依赖的列,没有传空,startRow 开始行(从零开始)]
//Map<Integer, int[]> mer = new HashMap<>();
//mer.put(0, new int[]);
//PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), mer, 1);
final FileOutputStream fileOutputStream = new FileOutputStream("C:\\\\Users\\\\Administrator\\\\Desktop\\\\1.xls");
//导出excel
downLoadExcel(null, fileOutputStream, workbook);
/**
* @Description: 下载文件
* @Param: fileName
* @Param outputStream
* @Param workbook
* @return: void
* @Author: peikunkun
* @Date: 2019/12/26 0026 上午 10:44
*/
public static void downLoadExcel(String fileName, FileOutputStream outputStream, Workbook workbook)
throws IOException
try
workbook.write(outputStream);
catch (IOException e)
throw new RuntimeException(e.getMessage());
finally
outputStream.close();
嘿,你在看吗?
以上是关于使用EasyPoi导出Excel的主要内容,如果未能解决你的问题,请参考以下文章