1:导入依赖jar包
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
2:需要导出导入的实体类继承BaseRowModel
具体代码:
重点注意(//@Accessors(chain = true),//@Data:这两个注解不能同时使用,并且实体类的属性要使用驼峰命名)
/**
*
* @author MRYIN
* @since 2021-03-02
*/
//@Data
@EqualsAndHashCode(callSuper = false)
//@Accessors(chain = true)
@ApiModel(value="Task对象", description="")
public class Task extends BaseRowModel implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "零件编号")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
@ExcelProperty(value = "零件编号" , index = 0)
private String id;
@ApiModelProperty(value = "装配的单价")
@ExcelProperty(value = "装配的单价" , index = 1)
private Integer monovalent;
@ApiModelProperty(value = "任务负责人")
@ExcelProperty(value = "任务负责人" , index = 2)
private String name;
@ApiModelProperty(value = "装配任务状态")
@ExcelProperty("装配任务状态")
private Integer status;
@ApiModelProperty(value = "接单时间")
@ExcelProperty("接单时间")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@ApiModelProperty(value = "计划完成时间")
@ExcelProperty("计划完成时间")
private Date finishTime;
@ApiModelProperty(value = "更新时间")
@ExcelProperty("更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
private Map<Integer, CellStyle> cellStyleMap = new HashMap<Integer,CellStyle>();
`Get、Set`省略、、、、
}
3:编写一个监听类继承AnalysisEventListener
并重写其中的方法
具体代码:
/**
* 监听类,可以自定义
*
* @author MRYIN
* @Created 2021-3-10 22:01:53
**/
public class ExcelListener extends AnalysisEventListener {
/**
* 自定义用于暂时存储data。
* 可以通过实例获取该值
*/
private List<Object> datas = new ArrayList<>();
/**
* 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据
*/
@Override
public void invoke(Object object, AnalysisContext context) {
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
datas.add(object);
//根据业务自行 do something
doSomething();
/*
如数据过大,可以进行定量分批处理
if(datas.size()<=100){
datas.add(object);
}else {
doSomething();
datas = new ArrayList<Object>();
}
*/
}
/**
* 根据业务自行实现该方法
*/
private void doSomething() {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
/*
datas.clear();
解析结束销毁不用的资源
*/
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
}
4:包含有多种导入导出的工具方法,可自行根据具体要求来选择,其中我只是用到的是导入方法,导出解和LayUI的表格导出使用
具体代码:
/**
* Excel工具类
*
* @@author MRYIN
* * @Created 2021-3-10 22:05: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) {
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) {
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 | ExcelException e) {
throw new RuntimeException(e);
}
}
/**
* 设置全局样式
*
* @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;
}
}
5:controller
控制器
file为前端传递过来的的excel文件,DataGridView为json数据的返回值工具类。具体用于LayUI
注意事项:如果需要对都进来的数据进行保存操作的时候,如果使用的是mybatisplus的语法会报错,提示没有cellStyleMap
这个属性。
解决方法:
1:`private Map<Integer, CellStyle> cellStyleMap = new HashMap<Integer,CellStyle>();`在实体类上加上这个属性。不过我没
有成功。
2:自己在持久层上写上自己的方法,不用mybatisplus的方法即可。
public DataGridView read(MultipartFile file) throws ExcelException {
Object objList = ExcelUtil.readExcel(file, new Task(), 1, 1);
if (objList == null) {
return new DataGridView(-1, "读取失败");
}
List orderList = (List) objList;
if (orderList == null || orderList.size() <= 0) {
return new DataGridView(-1, "读取失败");
}
orderList.forEach(System.out::println);
for (Object o : orderList) {
Task task = (Task) o;
//System.out.println(task.getId());
//System.out.println(task.getMonovalent());
//System.out.println(task.getName());
taskService.addTask(task);
}
return new DataGridView(0, "读取成功");
}