1.什么是easyExcel
2.如何使用
1.引入pom包
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beat1</version>
</dependency>
3.导入使用
1.定义实体类
@ExcelProperty(index = 0 , value = "时间")
private String TIME;
@ExcelProperty(index = 1 , value = "开盘")
private String OPENING;
@ExcelProperty(index = 2 , value = "最高")
private String MAXHIGH;
@ExcelProperty(index = 3 , value = "最低")
private String MINLOWEST;
@ExcelProperty(index = 4 , value = "收盘")
private String CLOSE_PAN;
@ExcelProperty(index = 5 , value = "成交量")
private String VOLUME;
@ExcelProperty(index = 6 , value = "股票代码")
private String STOCK_SYMBOL;
//@ExcelProperty(index = 0 , value = "时间")
//index:表示第几列
//value:表示这一列对于的名字
2.添加导入数据监听类
/**
* 监听类,可以自定义
*
* @author liuyi
* @Created 2019-7-18 18:01:53
**/
public class ExcelListener extends AnalysisEventListener {
/**
* 自定义用于暂时存储data。
* 可以通过实例获取该值
*/
private List<Object> datas = new ArrayList<>();
/**
* 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据
*/
@Override
public void invoke(Object object, AnalysisContext context) {
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
datas.add(object);
//根据业务自行 do something
doSomething();
/*
如数据过大,可以进行定量分批处理
if(datas.size()<=100){
datas.add(object);
}else {
doSomething();
datas = new ArrayList<Object>();
}
*/
}
/**
* 根据业务自行实现该方法
*/
private void doSomething() {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
/*
datas.clear();
解析结束销毁不用的资源
*/
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
}
3.编写导入导出工具类
/**
* Excel工具类
*
* @author liuyi
* @Created 2019-7-18 18:01:53
**/
public class ExcelUtil {
/**
* 读取 Excel(多个 sheet)
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel) throws ExcelException {
ExcelListener excelListener = new ExcelListener();
ExcelReader reader = getReader(excel, excelListener);
if (reader == null) {
return null;
}
for (Sheet sheet : reader.getSheets()) {
if (rowModel != null) {
sheet.setClazz(rowModel.getClass());
}
reader.read(sheet);
}
return excelListener.getDatas();
}
/**
* 读取某个 sheet 的 Excel
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @param sheetNo sheet 的序号 从1开始
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo) throws ExcelException {
return readExcel(excel, rowModel, sheetNo, 1);
}
/**
* 读取某个 sheet 的 Excel
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @param sheetNo sheet 的序号 从1开始
* @param headLineNum 表头行数,默认为1
* @return Excel 数据 list
*/
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo, int headLineNum) throws ExcelException {
ExcelListener excelListener = new ExcelListener();
ExcelReader reader = getReader(excel, excelListener);
if (reader == null) {
return null;
}
reader.read(new Sheet(sheetNo, headLineNum, rowModel.getClass()));
return excelListener.getDatas();
}
/**
* 导出 Excel :一个 sheet,带表头
*
* @param response HttpServletResponse
* @param list 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param object 映射实体类,Excel 模型
*/
public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, String fileName,
String sheetName, BaseRowModel object) throws ExcelException {
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
TableStyle tableStyle = new TableStyle();
tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE);
Font font = new Font();
font.setFontHeightInPoints((short) 9);
tableStyle.setTableHeadFont(font);
tableStyle.setTableContentFont(font);
sheet.setTableStyle(tableStyle);
writer.write(list, sheet);
writer.finish();
}
/**
* 导出 Excel :多个 sheet,带表头
*
* @param response HttpServletResponse
* @param list 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param object 映射实体类,Excel 模型
*/
public static ExcelWriterFactory writeExcelWithSheets(HttpServletResponse response,
List<? extends BaseRowModel> list, String fileName,
String sheetName, BaseRowModel object) throws ExcelException {
ExcelWriterFactory writer = new ExcelWriterFactory(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
sheet.setTableStyle(getTableStyle());
writer.write(list, sheet);
return writer;
}
/**
* 导出融资还款情况表
*
* @param response
* @param list
* @param fileName
* @param sheetName
* @param object
*/
public static void writeFinanceRepayment(HttpServletResponse response, List<? extends BaseRowModel> list,
String fileName, String sheetName, BaseRowModel object) throws ExcelException {
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
sheet.setTableStyle(getTableStyle());
writer.write(list, sheet);
for (int i = 1; i <= list.size(); i += 4) {
writer.merge(i, i + 3, 0, 0);
writer.merge(i, i + 3, 1, 1);
}
writer.finish();
}
/**
* 导出文件时为Writer生成OutputStream
*/
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws ExcelException {
//创建本地文件
fileName = fileName + ".xls";
try {
fileName = new String(fileName.getBytes(), "ISO-8859-1");
response.addHeader("Content-Disposition", "filename=" + fileName);
return response.getOutputStream();
} catch (Exception e) {
throw new ExcelException("导出异常!");
}
}
/**
* 返回 ExcelReader
*
* @param excel 需要解析的 Excel 文件
* @param excelListener new ExcelListener()
*/
private static ExcelReader getReader(MultipartFile excel, ExcelListener excelListener) throws ExcelException {
String filename = excel.getOriginalFilename();
if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) {
throw new ExcelException("文件格式错误!");
}
InputStream inputStream;
try {
inputStream = new BufferedInputStream(excel.getInputStream());
return new ExcelReader(inputStream, null, excelListener, false);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 资金收支导出 Excel :一个 sheet,带表头
*
* @param response HttpServletResponse
* @param list 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param object 映射实体类,Excel 模型
*/
public static void exportFundBudgetExcel(HttpServletResponse response, List<? extends BaseRowModel> list,
String fileName, String sheetName, BaseRowModel object) throws IOException, ExcelException {
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);
Sheet sheet = new Sheet(1, 0, object.getClass());
sheet.setSheetName(sheetName);
sheet.setTableStyle(getTableStyle());
writer.write(list, sheet);
writer.merge(2, 3, 0, 0);
writer.merge(4, 13, 0, 0);
writer.merge(14, 14, 0, 1);
writer.finish();
}
/**
* 读取Excel表格数据,封装成实体
*
* @param inputStream
* @param clazz
* @param sheetNo
* @param headLineMun
* @return
*/
public static Object readExcel(InputStream inputStream, Class<? extends BaseRowModel> clazz, Integer sheetNo,
Integer headLineMun) throws ExcelException {
if (null == inputStream) {
throw new NullPointerException("the inputStream is null!");
}
ExcelListener listener = new ExcelListener();
ExcelReader reader = new ExcelReader(inputStream, valueOf(inputStream), null, listener);
reader.read(new Sheet(sheetNo, headLineMun, clazz));
return listener.getDatas();
}
/**
* 根据输入流,判断为xls还是xlsx,该方法原本存在于easyexcel 1.1.0 的ExcelTypeEnum中。
*/
public static ExcelTypeEnum valueOf(InputStream inputStream) throws ExcelException {
try {
FileMagic fileMagic = FileMagic.valueOf(inputStream);
if (FileMagic.OLE2.equals(fileMagic)) {
return ExcelTypeEnum.XLS;
}
if (FileMagic.OOXML.equals(fileMagic)) {
return ExcelTypeEnum.XLSX;
}
throw new ExcelException("excelTypeEnum can not null");
} catch (IOException e) {
throw new RuntimeException(e);
}
// return null;
}
/**
* 设置全局样式
*
* @return
*/
private static TableStyle getTableStyle() {
TableStyle tableStyle = new TableStyle();
tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE);
Font font = new Font();
font.setBold(true);
font.setFontHeightInPoints((short) 9);
tableStyle.setTableHeadFont(font);
Font fontContent = new Font();
fontContent.setFontHeightInPoints((short) 9);
tableStyle.setTableContentFont(fontContent);
return tableStyle;
}
}
4.编写异常扩展类
public class ExcelException extends Exception {
public ExcelException() {
// TODO Auto-generated constructor stub
}
public ExcelException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ExcelException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public ExcelException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
}
5.调用方法
// excel:MultipartFile
// ExcelEntity:对应的实体类
// d调用导入方法后吧objLiest强转为List<ExcelEntity> ,此对象存储了所有的数据
Object objList = readExcel(excel, new ExcelEntity(),3);
List<ExcelEntity> orderList = (List<ExcelEntity>) objList;
4.easyExcel导出字典值的映射转换
主要通过制定converter来实现
/**
* easyexcel关于导出的字典值转换
*/
public class ExcelDictConverter implements Converter {
private String[] dictCodIsYesNoArr ={"afterSalesStatus", ""};
/**
* 返回Java中的对象类型
* @return Support for Java class
*/
@Override
public Class supportJavaTypeKey() {
return Integer.class;
}
/**
* 返回excel中的对象枚举
* @return Support for {@link CellDataTypeEnum}
*/
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
/**
* 将Excel对象转换为Java对象
* @param cellData Excel单元格数据。
* @param contentProperty 内容属性。可为空。
* @param globalConfiguration 全局配置。
* @return 放入Java对象的数据
* @throws Exception Exception.
*/
@Override
public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
// 1、获取解析的某个excel字符内容
// String value = cellData.getStringValue();
//return DataTranferEnum.getValue(value);
return null;
}
/**
* 将Java对象转换为Excel对象
* @param value Java Data.NotNull。
* @param contentProperty 内容属性。可为空。
* @param globalConfiguration 全局配置。
* @return 数据放入Excel
* @throws Exception Exception.
*/
@Override
public CellData convertToExcelData(Integer dictKey, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
// 1、获取属性名
// String attributeName = contentProperty.getField().getName();
// 2、通过属性名和java属性值获取对应的Excel字符值
// String excelValue = DataTranferEnum.getExcelValueByProperName(attributeName,value); DataTranferEnum 自定义类
// if(StringUtils.isNotBlank(excelValue)){
// return new CellData(excelValue);
// }
// return new CellData(value);
// 类里需要转换的字段
Field field = excelContentProperty.getField();
String fieldName = field.getName();
String excelValue;
// 字典值为yes_no的字段
if (StringUtils.equalsAnyIgnoreCase(fieldName, dictCodIsYesNoArr)) {
excelValue = DictCache.getValue(DictEnum.YES_NO, dictKey);
}else {
// 将字段名转换成下划线连接(也就是字典表里的code
String dictCode = camelToUnderline(fieldName);
// 当前字段对应的字典值
excelValue = DictCache.getValue(dictCode, dictKey);
}
return new CellData(StringUtil.isBlank(excelValue) ? dictKey.toString() : excelValue);
}
/**
* 驼峰转成下划线
*
* @param sourStr 需要转换的字符串,如:orderStatus
* @return 转换后的字符串,如:order_status
*/
public String camelToUnderline(String sourStr) {
if (sourStr == null || "".equals(sourStr.trim())) {
return "";
}
int len = sourStr.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = sourStr.charAt(i);
if (Character.isUpperCase(c)) {
sb.append('_');
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
}