
关于导出 Excel
文件,可以说是大多数服务中都需要集成的功能。那么,要如何优雅快速地去实现这个功能呢?
一、项目准备
1.1 步骤
1.创建Excel
导出对应的数据模型对象(本文的ExportModel.java
);2.将数据写入到数据模型对象中;3.导出Excel
。
1.2 导出数据模型对象
该类必须也要继承自
BaseRowModel.java
@Datapublic class ExportModel extends BaseRowModel {/*** 通过 @ExcelProperty 的value 指定每个字段的列名称,index 为列的序号。*/@ExcelProperty(value = "姓名", index = 0)private String studentName;@ExcelProperty(value = "年级", index = 1)private String grade;@ExcelProperty(value = "学科", index = 2)private String subject;@ExcelProperty(value = "分数", index = 3)private Integer fraction;public ExportModel() {}public ExportModel(String studentName, String grade, String subject, Integer fraction) {this.studentName = studentName;this.grade = grade;this.subject = subject;this.fraction = fraction;}}
1.3 根据时间戳生产文件名
private static String createFileName() {Long time = System.currentTimeMillis();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");return sdf.format(new Date()) + time;}
1.4 导出文件时为Writer
生成OutputStream
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) {response.reset();response.setContentType("application/vnd.ms-excel");try {fileName = URLEncoder.encode(fileName, "UTF-8");response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");return response.getOutputStream();} catch (IOException e) {throw new ExcelException("创建文件失败!");}}
1.5 导出文件时为File
生成OutputStream
private static OutputStream getFileOutputStream(String fileName) {try {String filePath = fileName + ".xlsx";File dbfFile = new File(filePath);if (!dbfFile.exists() || dbfFile.isDirectory()) {dbfFile.createNewFile();}OutputStream out = new FileOutputStream(filePath);return out;} catch (Exception e) {throw new RuntimeException("创建文件失败!");}}
1.6 造数据的方法
实际情况:从数据库查询动态数据。
public static List<ExportModel> getList() {List<ExportModel> list = new ArrayList<>();ExportModel model1 = new ExportModel("张三", "高三", "语文", 130);ExportModel model2 = new ExportModel("张三", "高三", "数学", 140);ExportModel model3 = new ExportModel("张三", "高三", "英语", 125);ExportModel model4 = new ExportModel("张三", "高三", "化学", 90);list.add(model1);list.add(model2);list.add(model3);list.add(model4);return list;}public static List<ExportModel> getAnotherList() {List<ExportModel> list = new ArrayList<>();ExportModel model1 = new ExportModel("李四", "高二", "语文", 120);ExportModel model2 = new ExportModel("李四", "高二", "数学", 125);ExportModel model3 = new ExportModel("李四", "高二", "英语", 140);ExportModel model4 = new ExportModel("李四", "高二", "化学", 85);list.add(model1);list.add(model2);list.add(model3);list.add(model4);return list;}
二、核心实现
2.1 导出的到一个 sheet
的 Excel
public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list,String fileName, String sheetName, BaseRowModel object) {// WriteModel 是 写入 Excel 的数据模型对象ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);Sheet sheet = new Sheet(1, 0, object.getClass());sheet.setSheetName(sheetName);// 异常处理writer.write(list, sheet);writer.finish();}
2.2 导出的到多个 sheet
的 Excel
•重写导出方法
public class ExcelWriterFactory extends ExcelWriter {private OutputStream outputStream;private int sheetNo = 1;public ExcelWriterFactory(OutputStream outputStream, ExcelTypeEnum typeEnum) {super(outputStream, typeEnum);this.outputStream = outputStream;}public ExcelWriterFactory write(List<? extends BaseRowModel> list, String sheetName,BaseRowModel object) {this.sheetNo++;try {Sheet sheet = new Sheet(sheetNo, 0, object.getClass());sheet.setSheetName(sheetName);this.write(list, sheet);} catch (Exception ex) {ex.printStackTrace();try {outputStream.flush();} catch (IOException e) {e.printStackTrace();}}return this;}@Overridepublic void finish() {super.finish();try {outputStream.flush();} catch (IOException e) {e.printStackTrace();}}}
•导出两个 sheet
示例
public static ExcelWriterFactory writeExcelWithSheets(HttpServletResponse response, List<? extends BaseRowModel> list,String fileName, String sheetName, BaseRowModel object) {ExcelWriterFactory writer = new ExcelWriterFactory(getOutputStream(fileName, response), ExcelTypeEnum.XLSX);Sheet sheet = new Sheet(1, 0, object.getClass());sheet.setSheetName(sheetName);writer.write(list, sheet);return writer;}
2.3 异步导出
1.如果数据量大,可能导出等待时间较长;2.同步导出必须实时下载,异步导出可以保存到系统,需要时再进行下载。
public static String asyWriteExcel(List<? extends BaseRowModel> list,String sheetName, BaseRowModel object) {// 先将数据导出excel到本地try {String fileName = URLEncoder.encode(createFileName(), "UTF-8");ExcelWriter writer = new ExcelWriter(getFileOutputStream(fileName), ExcelTypeEnum.XLSX);Sheet sheet = new Sheet(1, 0, object.getClass());sheet.setSheetName(sheetName);writer.write(list, sheet);writer.finish();// 读取该excel,并上传到oss,返回下载链接// File file = readFileByLines(fileName + ".xlsx");// return FileUploadUtil.upload(file, fileName + ".xlsx");} catch (UnsupportedEncodingException e) {throw new RuntimeException("创建excel失败!");}return null;}
三、测试
导出的测试比较简单,这里直接放出接口,具体业务实现见文末源码
@RestController@Api(tags = "EasyExcel 导出")@RequestMapping("/export")public class ExportExcelController {@ResourceExportExcelService exportExcelService;/*** 导出 Excel(一个 sheet)* @param response* @throws IOException*/@ApiOperation(value = "导出 Excel", httpMethod = "GET")@GetMapping(value = "/exportWithOneSheet")public void exportWithOneSheet(HttpServletResponse response) {exportExcelService.exportWithOneSheet(response);}/*** 导出 Excel(多个 sheet)*/@ApiOperation(value = "导出 Excel(多个 sheet)", httpMethod = "GET")@GetMapping(value = "/exportWithSheets")public void exportWithSheets(HttpServletResponse response) {exportExcelService.exportWithSheets(response);}/*** 异步导出 Excel(一个 sheet)* @param* @throws IOException*/@ApiOperation(value = "异步导出 Excel", httpMethod = "GET")@GetMapping(value = "/asyExportWithOneSheet")public void asyExportWithOneSheet() {exportExcelService.asyExportWithOneSheet();}}
四、待优化
本次分享的读取和导出只是基本的使用,面对复杂需求的时候还需要继续加工,更多内容,下次分享,大概包括:
1.导出合并单元格,单元格格式自定义;2.读取和导出自定义转换器;3.读取时指定表头行数、读取表头数据;4.转换异常处理。
Github 示例代码[1]
文中链接
[1]
Github 示例代码: https://github.com/vanDusty/SpringBoot-Home/tree/master/springboot-demo-excel
文章转载自风尘博客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




