对于阿里巴巴的这个包,由于没有用过其他的解析文件的包,也是最近在写解析Excel表的才学的觉得还是方便的,我做的最主要的导入Excel表。
我们来看一看这个包,这个包是阿里巴巴下的
<!-- easyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
导入Excel表的话,我们首先要写一个监听器,监听器可以自己定义,不过我觉得这样写一个泛型约定还是多方便的
/**
* ExcelListener:监听类,可以自定义
* @author 小黎同学
* @date 2020/10/09
*/
public class ExcelListener<T extends BaseRowModel> extends AnalysisEventListener<T> {
public List<T> getDatas() {
return datas;
}
public void setDatas(List<T> datas) {
this.datas = datas;
}
/**
* 自定义用于暂时存储data。可以通过实例获取该值
*/
private List<T> datas = new ArrayList<>();
@Override
public void invoke(T t, AnalysisContext analysisContext) {
//将数据储存在datas中
datas.add(t);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
工具类主要有读取、写出的功能
public class ExcelUtil {
/**
* 读取 Excel(多个 sheet)
*
* @param excel 文件
* @param rowModel 实体类映射,继承 BaseRowModel 类
* @return Excel 数据 list
*/
/**
* @param is 导入文件输入流
* @param clazz Excel实体映射类
* @return
*/
public static <T extends BaseRowModel> List<T> readExcel(InputStream is, final Class<? extends BaseRowModel> clazz){
List<T> rowsList = null;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(is);
// 解析每行结果在listener中处理
ExcelListener listener = new ExcelListener();
ExcelReader excelReader = EasyExcelFactory.getReader(bis, listener);
excelReader.read(new Sheet(1, 1, clazz));
rowsList = listener.getDatas();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return rowsList;
}
/**
*
* @param os 文件输出流
* @param clazz Excel实体映射类
* @param data 导出数据
* @return
*/
public static Boolean writeExcel(OutputStream os, Class clazz, List<? extends BaseRowModel> data){
BufferedOutputStream bos= null;
try {
bos = new BufferedOutputStream(os);
ExcelWriter writer = new ExcelWriter(bos, ExcelTypeEnum.XLSX);
//写第一个sheet, sheet1 数据全是List<String> 无模型映射关系
Sheet sheet1 = new Sheet(1, 0,clazz);
writer.write(data, sheet1);
writer.finish();
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
}
这儿主要是将流转为File类的工具类
public class InputStreamToFileUtill {
public static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
接下来看看我的service层,对于这个类来说我们不能直接将MultipartFile类直接用于,就要调用上面那个工具类。创建一个临时文件在该工程里面,最后将这个文件删除就可以了
@Service
public class ExcelBO {
/**
* @author 小黎
* @date 2020/10/2 23:00
* @description 读取Excel表,将Excel表的内容存储在List中
*/
public List<ExcelDTO> importUserExcel(MultipartFile excel) throws IOException {
//将MultipartFile转化为File
File file = null;
if (excel.equals("")|| excel.getSize()<=0) {
excel = null;
}else {
InputStream ins = excel.getInputStream();
file = new File(excel.getOriginalFilename());
InputStreamToFileUtill.inputStreamToFile(ins,file);
}
FileInputStream fis = null;
String path = excel.getOriginalFilename();
try {
fis = new FileInputStream(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<ExcelDTO> userExcelModelList = ExcelUtil.readExcel(fis, ExcelDTO.class);
File del = new File(file.toURI());
del.delete();
return userExcelModelList;
}
}
这儿是DTO对象类,主要用来储存解析出来的Excel表的数据
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ExcelDTO extends BaseRowModel {
@ExcelProperty(index = 0,value = "题目序号")
private String subjectNumber;
@ExcelProperty(index = 1,value = "题目描述")
private String subjectD;
@ExcelProperty(index = 2,value = "选项A")
private String oprionA;
@ExcelProperty(index = 3,value = "选项A跳转题目")
private String anextSubjectId;
@ExcelProperty(index = 4,value = "选项B")
private String oprionB;
@ExcelProperty(index = 5,value = "选项B跳转题目")
private String bnextSubjectId;
@ExcelProperty(index = 6,value = "选项C")
private String oprionC;
@ExcelProperty(index = 7,value = "选项C跳转题目")
private String cnextSubjectId;
@ExcelProperty(index = 8,value = "选项D")
private String oprionD;
@ExcelProperty(index = 9,value = "选项D跳转题目")
private String dnextSubjectId;
}
这里附上我的Excel表的格式
由于我主要是写一个问卷调查系统,其实我还有部分存储数据的代码没有贴出来。我用的是Oracle数据库,是比较麻烦的,建议可以用MongoDB数据库进行对json文件的直接存储,是特别舒服的。