愿你如阳光,明媚不忧伤。
目録
1. EasyExcel & 语雀
EasyExcel 是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。该技术重写了poi对07版Excel的解析,使内存从百兆降低到KB级别,并且再大的excel不会出现内存溢出。解决了POI技术的耗内存问题,并且提供了较好的API使用。不需要大量的代码就可以实现excel的操作功能。在上层做了模型转换的封装,让使用者更加简单方便。
语雀(yuque)是支付宝内部孵化的一款文档与知识管理工具。语雀使用了“结构化知识库管理”,形式上类似书籍的目录。与其他产品可以随意建立文档不同,语雀上的每一篇文档必须属于某一个知识库,语雀希望通过这样的产品设计,来从源头上帮助用户建立起知识管理的意识,培养良好的知识管理习惯。
了解更多 → EasyExcel 语雀
了解更多 → EasyExcel github
2. 快速感受
2.1 读Excel
/**
* 简单的读取excel文件
*/
public void read() {
String fileName = "demo.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
// 参数一:读取的excel文件路径
// 参数二:读取sheet的一行,将参数封装在DemoData实体类中
// 参数三:读取每一行的时候会执行DemoDataListener监听器
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
}
2.2 写Excel
/**
* 简单的写入数据到excel
*/
public void simpleWrite() {
String fileName = "demo.xlsx";
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03则传入excelType参数即可
// 参数一:写入excel文件路径
// 参数二:写入的数据类型是DemoData
// data()方法是写入的数据,结果是List<DemoData>集合
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}
2.3 Web上传与下载
/**
* excel文件的下载
*/
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
}
/**
* excel文件的上传
*/
@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), DemoData.class, new DemoDataListener()).sheet().doRead();
return "success";
}
3. 详解读取Excel
使用之前需要引入依赖,最新的稳定版本为 2.2.11
- pom.xml
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.11</version>
</dependency>
3.1 简单读取Excel
- EasyExcelData.xlsx
- EasyExcelData.java
创建与Excel标题相对应的实体类
public class EasyExcelData {
private String stringData;
private Date dateData;
private Double doubleData;
// 省略get和set
}
- EasyExcelDataListener.java
监听器:有个很重要的点 EasyExcelDataListener 不能被spring管理,每次读取excel都要new,如果使用了spring,请使用有参构造方法,把要被管理的类传进去。
@Component
public class EasyExcelDataListener extends AnalysisEventListener<EasyExcelData> {
// 用来操作Excel的每一条数据
List<EasyExcelData> list = new ArrayList<EasyExcelData>();
public EasyExcelDataListener() {
}
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*/
// public EasyExcelDataListener(EasyExcelDataDao easyExcelDataDao) {
// this.easyExcelDataDao = easyExcelDataDao;
// }
/**
* 每一条数据解析时会来调用
*
* @param easyExcelData
* @param analysisContext
*/
@Override
public void invoke(EasyExcelData easyExcelData, AnalysisContext analysisContext) {
System.out.println("解析到一条数据:" + JSON.toJSONString(easyExcelData));
list.add(easyExcelData);
}
/**
* 所有数据解析完成后会来调用
*
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据解析完成!" + JSON.toJSONString(list));
}
public List<EasyExcelData> getList() {
return list;
}
}
- EasyExcelDataController.java
读取Excel,这里提供两种方式读取
@RestController
@RequestMapping("/easyExcel")
public class EasyExcelDataController extends BaseController {
@Resource
EasyExcelDataListener easyExcelDataListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/read")
public JsonResult<List<EasyExcelData>> simpleRead(int mode) {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
if (mode == 1) {
// 写法1(默认第一个Sheet):
// 这里需要指定用哪个class去读,读取第一个sheet文件流后会自动关闭
EasyExcel.read(fileName, EasyExcelData.class, easyExcelDataListener).sheet().doRead();
} else {
// 一个文件一个reader
ExcelReader excelReader = null;
// 写法2(指定读取Sheet):
try {
excelReader = EasyExcel.read(fileName, EasyExcelData.class, easyExcelDataListener).build();
// 构建一个sheet 这里可以指定名字或者No
ReadSheet readSheet = EasyExcel.readSheet(0).build();
// 读取一个sheet
excelReader.read(readSheet);
} finally {
if (excelReader != null) {
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
}
}
}
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataListener.getList(), "读取Excel数据成功!");
}
}
浏览器访问 http://localhost:8080/easyExcel/read?mode=2
3.2 指定列的下标或列名
- EasyExcelDataIndexOrName.java
修改对应实体类
public class EasyExcelDataIndexOrName {
/**
* 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
*/
@ExcelProperty(index = 2)
private Double doubleData;
/**
* 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
*/
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
// 省略get和set
}
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/indexOrName")
public JsonResult<List<EasyExcelDataIndexOrName>> indexOrNameRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(fileName, EasyExcelDataIndexOrName.class, easyExcelDataReadListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataReadListener.getList(), "读取Excel数据成功!(指定列的下标或列名)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/indexOrName
3.3 读取多个sheet
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/multiSheets")
public JsonResult<List<EasyExcelDataIndexOrName>> multiSheets(String model) {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
if ("all".equals(model)) {
// 读取全部sheet
// 这里需要注意 EasyExcelDataReadListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个EasyExcelDataReadListener里面写
EasyExcel.read(fileName, EasyExcelDataIndexOrName.class, easyExcelDataReadListener).doReadAll();
} else {
// 读取部分sheet
ExcelReader excelReader = null;
try {
excelReader = EasyExcel.read(fileName).build();
// 这里为了简单注册了同样的head和Listener
ReadSheet readSheet1 =
EasyExcel.readSheet(0).head(EasyExcelDataIndexOrName.class).registerReadListener(easyExcelDataReadListener).build();
ReadSheet readSheet2 =
EasyExcel.readSheet(1).head(EasyExcelDataIndexOrName.class).registerReadListener(easyExcelDataReadListener).build();
// 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
excelReader.read(readSheet1, readSheet2);
} finally {
if (excelReader != null) {
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
}
}
}
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataReadListener.getList(), "读取Excel数据成功!(读多个sheet)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/multiSheets
3.4 日期,数字或自定义格式转换
- EasyExcelDataConverter.java
创建对应实体类,需要指定自定格式转换器
public class EasyExcelDataConverter {
/**
* 自定义转换器
*/
@ExcelProperty(converter = CustomStringStringConverter.class)
private String string;
/**
* 这里用string去接日期才能格式化
*/
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
private String date;
/**
* 接收百分比的数字
*/
@NumberFormat("#.##%")
private String doubleData;
// 省略get和set
}
- CustomStringStringConverter.java
自定义转换器,需要实现Converter接口
public class CustomStringStringConverter implements Converter<String> {
@Override
public Class supportJavaTypeKey() {
return String.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
/**
* 这里读的时候会调用
*
* @param cellData NotNull
* @param contentProperty Nullable
* @param globalConfiguration NotNull
* @return customString
*/
@Override
public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return "自定义格式:" + cellData.getStringValue();
}
/**
* 这里是写的时候会调用 不用管
*
* @param value NotNull
* @param contentProperty Nullable
* @param globalConfiguration NotNull
* @return
*/
@Override
public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return new CellData(value);
}
}
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
@Resource
EasyExcelDataConverterListener easyExcelDataConverterListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/converterRead")
public JsonResult<List<EasyExcelDataConverter>> converterRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
// 这里注意 我们也可以registerConverter来指定自定义转换器(.registerConverter(new CustomStringStringConverter())), 但是这个转换变成全局了, 所有java为string,excel为string的都会用这个转换器。
// 如果就想单个字段使用请使用@ExcelProperty 指定converter
EasyExcel.read(fileName, EasyExcelDataConverter.class, easyExcelDataConverterListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataConverterListener.getList(), "读取Excel数据成功!(自定义格式转换)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/converterRead
3.5 多行头
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
@Resource
EasyExcelDataConverterListener easyExcelDataConverterListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/multiHeaders")
public JsonResult<List<EasyExcelDataConverter>> multiHeaders() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
// 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,EasyExcelDataConverter 来解析,他没有指定头,也就是默认1行
EasyExcel.read(fileName, EasyExcelDataConverter.class, easyExcelDataConverterListener).sheet().headRowNumber(1).doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataConverterListener.getList(), "读取Excel数据成功!(多行头)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/multiHeaders
3.6 读取表头数据
- EasyExcelDataReadController.java
监听器里面多了一个方法,只要重写invokeHeadMap方法即可。
@Override
public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
System.out.println("解析到一条头数据:" + JSON.toJSONString(headMap));
}
- EasyExcelDataReadController.java
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
@Resource
EasyExcelDataConverterListener easyExcelDataConverterListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/headerRead")
public JsonResult<Map<Integer, CellData>> headerRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(fileName, EasyExcelDataConverter.class, easyExcelDataConverterListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataConverterListener.getHeadMap(), "读取Excel数据成功!(读取表头数据)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/headerRead
3.7 额外信息(批注,超链接,合并单元格信息)
- EasyExcelData.xlsx
在Excel中添加好超链接,批注,合并单元格等内容。
- EasyExcelExtraData.java
创建对应实体类
public class EasyExcelExtraData {
private String column1;
private String column2;
// 省略get和set
}
- EasyExcelDataExtraListener.java
监听器:里面多了一个 extra 方法
@Component
public class EasyExcelDataExtraListener extends AnalysisEventListener<EasyExcelExtraData> {
// 用来操作Excel的额外数据
List<EasyExcelExtraData> list = new ArrayList<>();
// 用来显示Excel的额外数据的详细信息
List<String> listExtra = new ArrayList<>();
public EasyExcelDataExtraListener() {
}
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*/
// public EasyExcelDataListener(EasyExcelDataDao easyExcelDataDao) {
// this.easyExcelDataDao = easyExcelDataDao;
// }
/**
* 每一条数据解析时会来调用
*
* @param easyExcelData
* @param analysisContext
*/
@Override
public void invoke(EasyExcelExtraData easyExcelData, AnalysisContext analysisContext) {
System.out.println("解析到一条数据:" + JSON.toJSONString(easyExcelData));
list.add(easyExcelData);
}
/**
* 所有数据解析完成后会来调用
*
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据解析完成!" + JSON.toJSONString(list));
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
listExtra.add("读取到了一条额外信息:" + JSON.toJSONString(extra));
System.out.println("读取到了一条额外信息:" + JSON.toJSONString(extra));
switch (extra.getType()) {
case COMMENT:
listExtra.add("额外信息是批注,在rowIndex:" + extra.getRowIndex() + ",columnIndex:" + extra.getColumnIndex() +
"内容是:" + extra.getText());
System.out.println("额外信息是批注,在rowIndex:" + extra.getRowIndex() + ",columnIndex:" + extra.getColumnIndex() +
"内容是:" + extra.getText());
break;
case HYPERLINK:
if ("Sheet1!A1".equals(extra.getText())) {
listExtra.add("额外信息是超链接,在rowIndex:" + extra.getRowIndex() + ",columnIndex:" + extra.getColumnIndex() +
"内容是:" + extra.getText());
System.out.println("额外信息是超链接,在rowIndex:" + extra.getRowIndex() + ",columnIndex:" + extra.getColumnIndex() +
"内容是:" + extra.getText());
} else if ("Sheet2!A1:B2".equals(extra.getText())) {
listExtra.add("额外信息是超链接,而且覆盖了一个区间,在firstRowIndex:" + extra.getFirstRowIndex() + ",firstColumnIndex:"
+ extra.getFirstColumnIndex() + ",lastRowIndex:" + extra.getLastRowIndex() + ",lastColumnIndex:"
+ extra.getLastColumnIndex() + ",内容是:" + extra.getText());
System.out.println(
"额外信息是超链接,而且覆盖了一个区间,在firstRowIndex:" + extra.getFirstRowIndex() + ",firstColumnIndex:"
+ extra.getFirstColumnIndex() + ",lastRowIndex:" + extra.getLastRowIndex() + ",lastColumnIndex:"
+ extra.getLastColumnIndex() + ",内容是:" + extra.getText());
} else {
listExtra.add("Unknown hyperlink!");
System.out.println("Unknown hyperlink!");
}
break;
case MERGE:
listExtra.add("额外信息是合并单元格,而且覆盖了一个区间在firstRowIndex:" + extra.getFirstRowIndex() + ",firstColumnIndex:"
+ extra.getFirstColumnIndex() + ",lastRowIndex:" + extra.getLastRowIndex() + ",lastColumnIndex:"
+ extra.getLastColumnIndex());
System.out.println(
"额外信息是合并单元格,而且覆盖了一个区间在firstRowIndex:" + extra.getFirstRowIndex() + ",firstColumnIndex:"
+ extra.getFirstColumnIndex() + ",lastRowIndex:" + extra.getLastRowIndex() + ",lastColumnIndex:"
+ extra.getLastColumnIndex());
break;
default:
}
}
public List<String> getExtraInfo() {
listExtra.add(JSON.toJSONString(list));
return listExtra;
}
}
- EasyExcelDataReadController.java
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataReadListener easyExcelDataReadListener;
@Resource
EasyExcelDataConverterListener easyExcelDataConverterListener;
@Resource
EasyExcelDataExtraListener easyExcelDataExtraListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/extraRead")
public JsonResult<List<String>> extraRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(fileName, EasyExcelExtraData.class, easyExcelDataExtraListener)
// 需要读取批注 默认不读取
.extraRead(CellExtraTypeEnum.COMMENT)
// 需要读取超链接 默认不读取
.extraRead(CellExtraTypeEnum.HYPERLINK)
// 需要读取合并单元格信息 默认不读取
.extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataExtraListener.getExtraInfo(), "读取Excel数据成功!(额外信息)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/extraRead
3.8 读取公式和单元格类型
- EasyExcelData.xlsx
在Excel中添加好公式等内容。
- EasyExcelExtraData.java
创建对应实体类
public class EasyExcelCellData {
private CellData<String> string;
private CellData<Date> date;
private CellData<Double> doubleData;
private CellData<String> formulaValue;
// 省略get和set
}
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelCellDataListener easyExcelCellDataListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/cellDataRead")
public JsonResult<List<EasyExcelCellData>> cellDataRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(fileName, EasyExcelCellData.class, easyExcelCellDataListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelCellDataListener.getList(), "读取Excel数据成功!(读取公式和单元格类型)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/cellDataRead
3.9 数据转换等异常处理
- EasyExcelExtraData.java
创建错误的实体类(数据类型不匹配)
public class ExceptionEasyExcelData {
// 第一列数据是字符串类型,但是指定了日期类型
private Date date;
// 省略get和set
}
- ExceptionEasyExcelDataListener.java
监听器:里面多了一个方法,只要重写onException方法即可
@Component
public class ExceptionEasyExcelDataListener extends AnalysisEventListener<ExceptionEasyExcelData> {
// 用来操作Excel的每一条数据
List<ExceptionEasyExcelData> list = new ArrayList<>();
StringBuffer sb = new StringBuffer();
/**
* 在转换异常获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则继续读取下一行。
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) {
System.out.println("解析失败,但是继续解析下一行:" + exception.getMessage());
// 如果是某一个单元格的转换异常 能获取到具体行号
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
System.err.println("第" + excelDataConvertException.getRowIndex() + "行,第" + excelDataConvertException.getColumnIndex()
+ "列解析异常");
sb.append("解析失败,但是继续解析下一行:").append(exception.getMessage()).append("第").append(excelDataConvertException.getRowIndex()).append("行,第").append(excelDataConvertException.getColumnIndex()).append("列解析异常");
}
}
}
- EasyExcelDataReadController.java
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
ExceptionEasyExcelDataListener exceptionEasyExcelDataListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@RequestMapping("/exceptionRead")
public JsonResult<StringBuffer> exceptionRead() {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(fileName, ExceptionEasyExcelData.class, exceptionEasyExcelDataListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(exceptionEasyExcelDataListener.getExceptionInfo(), "读取Excel数据成功!(数据转换等异常处理)");
}
}
浏览器访问 http://localhost:8080/easyExcelRead/exceptionRead
3.10 web中的读
- EasyExcelDataReadController.java
监听器只是泛型变了,请参照上面的监听器,具体代码不再展示。
@RestController
@RequestMapping("/easyExcelRead")
public class EasyExcelDataReadController extends BaseController {
@Resource
EasyExcelDataMultipartFileListener easyExcelDataMultipartFileListener;
// 指定需要读的excel文件
String fileName = "C:/Users/ISCCF_A/Desktop/EasyExcelData.xlsx";
@PostMapping("/multipartFileRead")
@ResponseBody
public JsonResult<List<EasyExcelDataMultipartFile>> multipartFileRead(MultipartFile file) throws IOException {
log.info(startLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
EasyExcel.read(file.getInputStream(), EasyExcelDataMultipartFile.class, easyExcelDataMultipartFileListener).sheet().doRead();
log.info(endLog(Thread.currentThread().getStackTrace()[1].getMethodName()));
return new JsonResult<>(easyExcelDataMultipartFileListener.getList(), "读取Excel数据成功!(web中的读)");
}