項目地址:https://github.com/changxueyi/springbootcrud
1.准備
項目的整體架構和圖中的類似

2. 導入依賴

當然,基本的mysql-connector-java、mybaits、springboot的也需要導入,最重要的就是上面的
3、導出excel
dept實體類
導出 Excel 時,若需要表頭,那么相應的實體類需要繼承 BaseRowModel,並加入 @ExcelProperty(value = “id”, index = 0) 注解。其中 value 代表在導出 Excel 時,該字段對應的表頭名稱;index 代表該字段對應的表頭位置(從0開始)。如下圖:

1. 重要的代碼
實體類對象

2. 控制層 DeptController

2.service業務層

3. 實現層
package com.cxy.service.Impl;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.cxy.common.poi.ExcelListener;
import com.cxy.dao.DeptMapper;
import com.cxy.domin.Dept;
import com.cxy.service.DeptService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Random;
/**
* @ClassName DeptServiceImpl
* @Description TODO
* @Author changxueyi
* @Date 2020/11/12 17:43
*/
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public void excelExport(HttpServletResponse response) throws IOException {
List<Dept> list = deptMapper.queryAllDept();
String fileName = "用戶名單";
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xls");
ServletOutputStream out = response.getOutputStream();
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLS,true);
Sheet sheet = new Sheet(1,0,Dept.class);
//設置自適應寬度
sheet.setAutoWidth(Boolean.TRUE);
sheet.setSheetName("用戶名單");
writer.write(list,sheet);
writer.finish();
out.flush();
response.getOutputStream().close();
out.close();
}
@Override
public void excelImport(MultipartFile file) throws IOException {
if(!file.getOriginalFilename().equals("用戶名單.xls") && !file.getOriginalFilename().equals("用戶名單.xlsx") ){
return;
}
InputStream inputStream = new BufferedInputStream(file.getInputStream());
//實例化實現了AnalysisEventListener接口的類
ExcelListener excelListener = new ExcelListener(deptMapper);
ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
//讀取信息
reader.read(new Sheet(1,1,Dept.class));
}
}
4.Mapper層

5.Mapper實現層
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cxy.dao.DeptMapper">
<select id="queryAllDept" resultType="com.cxy.domin.Dept">
select * from dept
</select>
<insert id="addDept" parameterType="com.cxy.domin.Dept">
insert into dept values (#{deptNo},#{deptName},#{localtion})
</insert>
</mapper>
6.ExcelListener 工具類
package com.cxy.common.poi;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.cxy.dao.DeptMapper;
import com.cxy.domin.Dept;
import org.springframework.stereotype.Controller;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName ExcelListener
* @Description TODO
* @Author changxueyi
* @Date 2020/11/12 17:57
*/
@Controller
public class ExcelListener extends AnalysisEventListener<Dept> {
private List<Dept> datas = new ArrayList<>();
private static final int BATCH_COUNT = 3000;
private DeptMapper deptMapper;
public ExcelListener(DeptMapper deptMapper){
this.deptMapper = deptMapper;
}
@Override
public void invoke(Dept dept, AnalysisContext analysisContext) {
//數據存儲到datas,供批量處理,或后續自己業務邏輯處理。
datas.add(dept);
//達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
if(datas.size() >= BATCH_COUNT){
saveData();
// 存儲完成清理datas
datas.clear();
}
}
private void saveData() {
for(Dept dept : datas){
deptMapper.addDept(dept);
}
}
public List<Dept> getDatas() {
return datas;
}
public void setDatas(List<Dept> datas) {
this.datas = datas;
}
/**
* 所有數據解析完成了 都會來調用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();//確保所有數據都能入庫
}
/* @Override
public void invoke(Dept dept, AnalysisContext analysisContext) {
}*/
}
7. 導入的時候,文件名一定要固定
用戶名單.xls
8.通過postMan使用的時候,需要注意以下幾點

頭部信息

9.導出功能
再用postman測試導出功能:#
沒有參數,直接send,然后可以看到:


將其下載下來查看(本來這里的文件名應該是代碼中命名的“用戶名單.xls”,但我嘗試了很久總是沒有變。。。)
與數據庫表數據一致,說明導出成功!
特別說明:
這里的excel名字的命名必須是這個,而且里面的主鍵可以不寫,因為可能會遇到主鍵沖突的問題


![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-X87m7MCo-1575975083497)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20191210182033780.png)]](/image/aHR0cHM6Ly9pbWctYmxvZy5jc2RuaW1nLmNuLzIwMTkxMjEwMTkxNTM2ODI4LnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3dhdGVybWFyayx0eXBlX1ptRnVaM3BvWlc1bmFHVnBkR2ssc2hhZG93XzEwLHRleHRfYUhSMGNITTZMeTlpYkc5bkxtTnpaRzR1Ym1WMEwwWmxiR2w0WDJGeSxzaXplXzE2LGNvbG9yX0ZGRkZGRix0Xzcw.png)

