項目地址: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名字的命名必須是這個,而且里面的主鍵可以不寫,因為可能會遇到主鍵沖突的問題