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,当前行等数据*/@Overridepublic void invoke(Object object, AnalysisContext context) {//数据存储到list,供批量处理,或后续自己业务逻辑处理。datas.add(object);//根据业务自行 do somethingdoSomething();/*如数据过大,可以进行定量分批处理if(datas.size()<=100){datas.add(object);}else {doSomething();datas = new ArrayList<Object>();}*/}/*** 根据业务自行实现该方法*/private void doSomething() {}@Overridepublic 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*/@Overridepublic Class supportJavaTypeKey() {return Integer.class;}/*** 返回excel中的对象枚举* @return Support for {@link CellDataTypeEnum}*/@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/*** 将Excel对象转换为Java对象* @param cellData Excel单元格数据。* @param contentProperty 内容属性。可为空。* @param globalConfiguration 全局配置。* @return 放入Java对象的数据* @throws Exception Exception.*/@Overridepublic 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.*/@Overridepublic 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 {// 将字段名转换成下划线连接(也就是字典表里的codeString 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();}}
