SpringBoot整合easyexcel实现Excel的导出

在一般不管大的或者小的系统中,各家的产品都一样,闲的无聊的时候都喜欢让我们这些程序员导出一些数据出来供他观赏,非说这是必须需求,非做不可,那么我们就只能苦逼的哼哧哼哧的写bug喽。

之前使用POI导出excel需要自己先去创建excel文件,还要创建sheet,写表头,操作起来确实很麻烦,针对产品这种随心而欲的需求我们能不能快速的做完这样一个产品看起来挺简单的功能。

基于这样一个快速开发的场景,我们来看看easyexcel应该如何使用。

首先我们创建一个springboot(版本是 2.1.4.RELEASE)项目,在此就不过多的啰嗦,创建好之后,首先需要引入easyexcel的maven坐标。

1<dependency> 2 <groupId>com.alibaba</groupId> 3 <artifactId>easyexcel</artifactId> 4 <version>1.1.2-beta5</version> 5</dependency>

导入好了之后,我们接下来需要创建一个导出的模板类,首先要集成BaseRowModel,set、get省略,@ExcelProperty注解中的value就是表头的信息,index是在第几列,没有加注解的不会导出。

1public class OrderExcelBO extends BaseRowModel { 2 3 @ExcelProperty(value = {"订单ID"}, index = 0) 4 private String id; 5 6 /** 7 * 订单描述 8 */ 9 @ExcelProperty(value = {"订单描述"}, index = 2) 10 private String description; 11 12 /** 13 * 订单对应产品id 14 */ 15 @ExcelProperty(value = {"产品ID"}, index = 2) 16 private Integer productId; 17 18 /** 19 * 支付方式描述,如:apple pay 20 */ 21 @ExcelProperty(value = {"支付方式"}, index = 3) 22 private String payMethod; 23 24 /** 25 * create_time 26 */ 27 @ExcelProperty(value = {"时间"}, index = 4) 28 private String createTime; 29 30 /** 31 * update_time 32 */ 33 private String updateTime; 34 35 /** 36 * 产生订单的用户 37 */ 38 @ExcelProperty(value = {"用户ID"}, index = 5) 39 private Integer userId; 40 41 /** 42 * 支付状态:0 未支付、1支付成功支付完成、-1支付失败 43 */ 44 @ExcelProperty(value = {"支付状态"}, index = 6) 45 private String status; 46 47 /** 48 * 订单来源描述,如:ios 安卓 49 */ 50 @ExcelProperty(value = {"手机型号"}, index = 7) 51 private String platform; 52 53 /** 54 * 订单流水 55 */ 56 @ExcelProperty(value = {"订单流水号"}, index = 8) 57 private String flowNum; 58 59 /** 60 * 订单金额 61 */ 62 @ExcelProperty(value = {"金额"}, index = 9) 63 private BigDecimal price; 64 65 // @ExcelProperty(value = {"收据字段"}, index = 10) 66 private String receipt; 67 68 @ExcelProperty(value = {"APP来源"}, index = 10) 69 private String sources; 70}

导出的模板定义好之后,接下来就是一些封装好的工具类的调用

  1. 查出我们需要导出的数据;

  2. 生成Excel文件名和sheet名称;

  3. 直接调用封装好的工具类导出文件即可;

我们来看下导出的效果

如果你的表头比较复杂,那么根据需求,你也可自行定义,例如如下这种复杂的表头,应该如何设置

首先要修改模板类,如果合并的单元格最大为2,那么所有的表格都需要设置为2,不合并的单元格用空字符串填充,需要合并的单元格将合并部分写上相同的名称,并且排列的序号要连续,不能分开。

我们来看下导出的效果,这样就可以满足我们平时开发需要的excel导出功能。简单易上手。

工具类:

1import com.alibaba.excel.context.AnalysisContext; 2import com.alibaba.excel.event.AnalysisEventListener; 3 4import java.util.ArrayList; 5import java.util.List; 6 7public class ExcelListener extends AnalysisEventListener { 8 9 /** 10 * 自定义用于暂时存储data。 11 * 可以通过实例获取该值 12 */ 13 private List<Object> datas = new ArrayList<>(); 14 15 /** 16 * 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据 17 */ 18 @Override 19 public void invoke(Object object, AnalysisContext context) { 20 //数据存储到list,供批量处理,或后续自己业务逻辑处理。 21 datas.add(object); 22 //根据业务自行 do something 23 doSomething(); 24 /* 25 如数据过大,可以进行定量分批处理 26 if(datas.size()<=100){ 27 datas.add(object); 28 }else { 29 doSomething(); 30 datas = new ArrayList<Object>(); 31 } 32 */ 33 } 34 35 /** 36 * 根据业务自行实现该方法 37 */ 38 private void doSomething() { 39 } 40 41 @Override 42 public void doAfterAllAnalysed(AnalysisContext context) { 43 /* 44 datas.clear(); 45 解析结束销毁不用的资源 46 */ 47 } 48 49 public List<Object> getDatas() { 50 return datas; 51 } 52 53 public void setDatas(List<Object> datas) { 54 this.datas = datas; 55 } 56} 57 58import com.alibaba.excel.ExcelReader; 59import com.alibaba.excel.ExcelWriter; 60import com.alibaba.excel.metadata.BaseRowModel; 61import com.alibaba.excel.metadata.Font; 62import com.alibaba.excel.metadata.Sheet; 63import com.alibaba.excel.metadata.TableStyle; 64import com.alibaba.excel.support.ExcelTypeEnum; 65import com.mochu.exception.ExcelException; 66import org.apache.poi.poifs.filesystem.FileMagic; 67import org.apache.poi.ss.usermodel.IndexedColors; 68import org.springframework.web.multipart.MultipartFile; 69 70import javax.servlet.http.HttpServletResponse; 71import java.io.BufferedInputStream; 72import java.io.IOException; 73import java.io.InputStream; 74import java.io.OutputStream; 75import java.util.List; 76 77public class ExcelUtil { 78 /** 79 * 读取 Excel(多个 sheet) 80 * 81 * @param excel 文件 82 * @param rowModel 实体类映射,继承 BaseRowModel 类 83 * @return Excel 数据 list 84 */ 85 public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel) { 86 ExcelListener excelListener = new ExcelListener(); 87 ExcelReader reader = getReader(excel, excelListener); 88 89 if (reader == null) { 90 return null; 91 } 92 93 for (Sheet sheet : reader.getSheets()) { 94 if (rowModel != null) { 95 sheet.setClazz(rowModel.getClass()); 96 } 97 reader.read(sheet); 98 } 99 100 return excelListener.getDatas(); 101 } 102 103 /** 104 * 读取某个 sheet 的 Excel 105 * 106 * @param excel 文件 107 * @param rowModel 实体类映射,继承 BaseRowModel 类 108 * @param sheetNo sheet 的序号 从1开始 109 * @return Excel 数据 list 110 */ 111 public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo) { 112 return readExcel(excel, rowModel, sheetNo, 1); 113 } 114 115 /** 116 * 读取某个 sheet 的 Excel 117 * 118 * @param excel 文件 119 * @param rowModel 实体类映射,继承 BaseRowModel 类 120 * @param sheetNo sheet 的序号 从1开始 121 * @param headLineNum 表头行数,默认为1 122 * @return Excel 数据 list 123 */ 124 public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo, int headLineNum) { 125 ExcelListener excelListener = new ExcelListener(); 126 ExcelReader reader = getReader(excel, excelListener); 127 128 if (reader == null) { 129 return null; 130 } 131 132 reader.read(new Sheet(sheetNo, headLineNum, rowModel.getClass())); 133 134 return excelListener.getDatas(); 135 } 136 137 /** 138 * 导出 Excel :一个 sheet,带表头 139 * 140 * @param response HttpServletResponse 141 * @param list 数据 list,每个元素为一个 BaseRowModel 142 * @param fileName 导出的文件名 143 * @param sheetName 导入文件的 sheet 名 144 * @param object 映射实体类,Excel 模型 145 */ 146 public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, String fileName, 147 String sheetName, BaseRowModel object) { 148 ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); 149 Sheet sheet = new Sheet(1, 0, object.getClass()); 150 sheet.setSheetName(sheetName); 151 152 TableStyle tableStyle = new TableStyle(); 153 tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE); 154 Font font = new Font(); 155 font.setFontHeightInPoints((short) 9); 156 tableStyle.setTableHeadFont(font); 157 tableStyle.setTableContentFont(font); 158 sheet.setTableStyle(tableStyle); 159 160 writer.write(list, sheet); 161 writer.finish(); 162 } 163 164 /** 165 * 导出 Excel :多个 sheet,带表头 166 * 167 * @param response HttpServletResponse 168 * @param list 数据 list,每个元素为一个 BaseRowModel 169 * @param fileName 导出的文件名 170 * @param sheetName 导入文件的 sheet 名 171 * @param object 映射实体类,Excel 模型 172 */ 173 public static ExcelWriterFactory writeExcelWithSheets(HttpServletResponse response, 174 List<? extends BaseRowModel> list, String fileName, 175 String sheetName, BaseRowModel object) { 176 ExcelWriterFactory writer = new ExcelWriterFactory(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); 177 Sheet sheet = new Sheet(1, 0, object.getClass()); 178 sheet.setSheetName(sheetName); 179 sheet.setTableStyle(getTableStyle()); 180 writer.write(list, sheet); 181 182 return writer; 183 } 184 185 /** 186 * 导出融资还款情况表 187 * 188 * @param response 189 * @param list 190 * @param fileName 191 * @param sheetName 192 * @param object 193 */ 194 public static void writeFinanceRepayment(HttpServletResponse response, List<? extends BaseRowModel> list, 195 String fileName, String sheetName, BaseRowModel object) { 196 ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); 197 Sheet sheet = new Sheet(1, 0, object.getClass()); 198 sheet.setSheetName(sheetName); 199 sheet.setTableStyle(getTableStyle()); 200 writer.write(list, sheet); 201 202 for (int i = 1; i <= list.size(); i += 4) { 203 writer.merge(i, i + 3, 0, 0); 204 writer.merge(i, i + 3, 1, 1); 205 } 206 207 writer.finish(); 208 } 209 210 /** 211 * 导出文件时为Writer生成OutputStream 212 */ 213 private static OutputStream getOutputStream(String fileName, HttpServletResponse response) { 214 //创建本地文件 215 fileName = fileName + ".xls"; 216 217 try { 218 fileName = new String(fileName.getBytes(), "ISO-8859-1"); 219 response.addHeader("Content-Disposition", "filename=" + fileName); 220 221 return response.getOutputStream(); 222 } catch (Exception e) { 223 224 throw new ExcelException("导出异常!"); 225 } 226 } 227 228 /** 229 * 返回 ExcelReader 230 * 231 * @param excel 需要解析的 Excel 文件 232 * @param excelListener new ExcelListener() 233 */ 234 private static ExcelReader getReader(MultipartFile excel, ExcelListener excelListener) { 235 String filename = excel.getOriginalFilename(); 236 237 if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) { 238 throw new ExcelException("文件格式错误!"); 239 } 240 InputStream inputStream; 241 242 try { 243 inputStream = new BufferedInputStream(excel.getInputStream()); 244 245 return new ExcelReader(inputStream, null, excelListener, false); 246 } catch (IOException e) { 247 e.printStackTrace(); 248 } 249 250 return null; 251 } 252 253 /** 254 * 资金收支导出 Excel :一个 sheet,带表头 255 * 256 * @param response HttpServletResponse 257 * @param list 数据 list,每个元素为一个 BaseRowModel 258 * @param fileName 导出的文件名 259 * @param sheetName 导入文件的 sheet 名 260 * @param object 映射实体类,Excel 模型 261 */ 262 public static void exportFundBudgetExcel(HttpServletResponse response, List<? extends BaseRowModel> list, 263 String fileName, String sheetName, BaseRowModel object) throws IOException { 264 ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); 265 Sheet sheet = new Sheet(1, 0, object.getClass()); 266 sheet.setSheetName(sheetName); 267 sheet.setTableStyle(getTableStyle()); 268 269 writer.write(list, sheet); 270 writer.merge(2, 3, 0, 0); 271 writer.merge(4, 13, 0, 0); 272 writer.merge(14, 14, 0, 1); 273 writer.finish(); 274 } 275 276 /** 277 * 读取Excel表格数据,封装成实体 278 * 279 * @param inputStream 280 * @param clazz 281 * @param sheetNo 282 * @param headLineMun 283 * @return 284 */ 285 public static Object readExcel(InputStream inputStream, Class<? extends BaseRowModel> clazz, Integer sheetNo, 286 Integer headLineMun) { 287 if (null == inputStream) { 288 289 throw new NullPointerException("the inputStream is null!"); 290 } 291 292 ExcelListener listener = new ExcelListener(); 293 ExcelReader reader = new ExcelReader(inputStream, valueOf(inputStream), null, listener); 294 reader.read(new Sheet(sheetNo, headLineMun, clazz)); 295 296 return listener.getDatas(); 297 } 298 299 /** 300 * 根据输入流,判断为xls还是xlsx,该方法原本存在于easyexcel 1.1.0 的ExcelTypeEnum中。 301 */ 302 public static ExcelTypeEnum valueOf(InputStream inputStream) { 303 try { 304 FileMagic fileMagic = FileMagic.valueOf(inputStream); 305 306 if (FileMagic.OLE2.equals(fileMagic)) { 307 return ExcelTypeEnum.XLS; 308 } 309 310 if (FileMagic.OOXML.equals(fileMagic)) { 311 return ExcelTypeEnum.XLSX; 312 } 313 314 throw new ExcelException("excelTypeEnum can not null"); 315 316 } catch (IOException e) { 317 throw new RuntimeException(e); 318 } 319 } 320 321 /** 322 * 设置全局样式 323 * 324 * @return 325 */ 326 private static TableStyle getTableStyle() { 327 TableStyle tableStyle = new TableStyle(); 328 329 tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE); 330 Font font = new Font(); 331 font.setBold(true); 332 font.setFontHeightInPoints((short) 9); 333 tableStyle.setTableHeadFont(font); 334 Font fontContent = new Font(); 335 fontContent.setFontHeightInPoints((short) 9); 336 tableStyle.setTableContentFont(fontContent); 337 338 return tableStyle; 339 } 340} 341 342import com.alibaba.excel.ExcelWriter; 343import com.alibaba.excel.metadata.BaseRowModel; 344import com.alibaba.excel.metadata.Sheet; 345import com.alibaba.excel.support.ExcelTypeEnum; 346 347import java.io.IOException; 348import java.io.OutputStream; 349import java.util.List; 350 351public class ExcelWriterFactory extends ExcelWriter { 352 private OutputStream outputStream; 353 private int sheetNo = 1; 354 355 public ExcelWriterFactory(OutputStream outputStream, ExcelTypeEnum typeEnum) { 356 super(outputStream, typeEnum); 357 this.outputStream = outputStream; 358 } 359 360 public ExcelWriterFactory write(List<? extends BaseRowModel> list, String sheetName, BaseRowModel object) { 361 this.sheetNo++; 362 try { 363 Sheet sheet = new Sheet(sheetNo, 0, object.getClass()); 364 sheet.setSheetName(sheetName); 365 this.write(list, sheet); 366 } 367 catch(Exception ex) { 368 ex.printStackTrace(); 369 try { 370 outputStream.flush(); 371 } 372 catch(IOException e) { 373 e.printStackTrace(); 374 } 375 } 376 return this; 377 } 378 379 @Override 380 public void finish() { 381 super.finish(); 382 try { 383 outputStream.flush(); 384 } 385 catch(IOException e) { 386 e.printStackTrace(); 387 } 388 } 389}

由于篇幅原因,如果需要分享Excel导入功能,下方留言。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript日期

日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用

SpringBoot整合easyexcel实现Excel的导出 - HelloWorld