整体流程
1.依赖jar
2.定义要写成的类
3.写出Excel
调用方法完成生成Excel
EasyExcel.write(“路径或者输出流”,类对应的Class对象).sheet().doWirte(集合);
4.读取Excel
1.根据模板数据封装类,属性和列数据一一对应,使用@ExcelProperty标记表格中列名
2.定义读取监听器,创建类实现ReadListener接口,重写方法,获取读取到的内容
3.调用方法完成读取
EasyExcel.read(“路径或输入流”,封装类的Class,自定义监听器对象).sheet().doRead();
1.jar包
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version></dependency>
2.配置文件
//springMVC.xml里面
<!-- 配置文件上传 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 最大可上传的文件大小 单位:byte 超出后会抛出MaxUploadSizeExceededException异常,可以异常解析器捕获 --><property name="maxUploadSize" value="1048576"/></bean>
3.配置线程池在工具包里面
ThreadPoolSingle类
package com.qyz.common.util;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class ThreadPoolSingle {public ThreadPoolExecutor poolExecutor;//原生的线程池对象//私有构造器private ThreadPoolSingle(){poolExecutor=new ThreadPoolExecutor(4,10,3, TimeUnit.SECONDS,new ArrayBlockingQueue<>(20),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());}//静态内部类static class ThreadPoolSingleFactory{public static ThreadPoolSingle single=new ThreadPoolSingle();}//公有静态方法public static ThreadPoolSingle getInstance(){return ThreadPoolSingleFactory.single;}//新增任务public void addTask(Runnable runnable){poolExecutor.submit(runnable);}}
解释
单例模式:
作用:创建类的对象,唯一对象
实现方式:
1.懒汉式
2.饿汉式
3.双锁
4.IoDH(静态内部类)
5.枚举
4.线程池
池化技术:1.提高复用率 2.控制数量
线程池:可以提高线程的使用率,还可以有效控制线程的数量
实际开发中,使用线程的话,都是使用线程池,而且用原生线程池
poolExecutor=new ThreadPoolExecutor(
核心线程数 最小线程数(不回收)
4,
最大线程数
10,
空闲时间
3,
空闲的时间单位,分钟
TimeUnit.SECONDS,
阻塞队列 7种
new ArrayBlockingQueue<>(20),
线程创建工厂
Executors.defaultThreadFactory(),
拒绝策略,4种
new ThreadPoolExecutor.AbortPolicy());
1.先触发核心线程数 2.添加到阻塞队列 3.触发最大线程数 4.触发拒绝策略*/
4.设置监听工具类
AdminReadListener在listener包里面
package com.qyz.common.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.qyz.common.util.ThreadPoolSingle;
import com.qyz.dao.AdminDao;
import com.qyz.entity.Admin;
import java.util.ArrayList;
import java.util.List;
/**
* @author Feri
* @date 2021/12/20 14:51
* @description:TODO
*/
public class AdminReadListener implements ReadListener<Admin> {
private AdminDao dao;
public AdminReadListener(AdminDao dao){
this.dao = dao;
}
//初始容量
private List<Admin> list = new ArrayList<>(1010);
//读取的每一行
@Override
public void invoke(Admin admin, AnalysisContext analysisContext) {
list.add(admin);
if(list.size() >= 1000){
//实现集合的复制,把需要线程池干的集合生成出来
List<Admin> child = new ArrayList<>(list);
//list代码清空复用list集合放止list调用自增方法减少效率
list.clear();//清理原集合
//执行批处理
ThreadPoolSingle.getInstance().addTask(()->{
dao.insertBatch(child);
});
}
}
//整个表格读取结束
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//执行最后不足1000条的数据
dao.insertBatch(list);
}
}
6设置Controller里面的url
@RequestMapping(value = "/upload.do",method = {RequestMethod.POST})
@ResponseBody
public JsonResult upload(MultipartFile file) throws IOException {
return service.saveBatchV2(file);
}
7.设置实体类属性和表格字段的匹配
private Integer id;
@ExcelProperty("账号")
private String name;
@ExcelProperty("密码")
private String password;
@ExcelProperty("状态")
private Integer flag;
private Date ctime;
8.设置service层的代码
数据量比较大的时候使用这个
//可以抗住大文件的上传
@Override
public JsonResult saveBatchV2(MultipartFile file) throws IOException {
//将上传的内容解析并添加到数据库
EasyExcel.read(
file.getInputStream(),//上传的文件内容-Excel表格
Admin.class,//每一行对应的类型
new AdminReadListener(dao)).sheet().doRead();
return JsonResult.success(null);
}
8.设置service层的代码
数据量较小的时候使用
@Override
public JsonResult saveBatch(MultipartFile file) throws IOException {
//将上传的内容解析并添加到数据库
EasyExcel.read(
file.getInputStream(),//上传的文件内容-Excel表格
Admin.class,//每一行对应的类型
new PageReadListener(list -> {//获取的数据
dao.insertBatch((List<Admin>) list);
})).sheet().doRead();
return JsonResult.success(null);
}
9.设置dao层的映射方法
//批量新增
int insertBatch(List<Book> list);
10.设置mapper的sql语句实现数据的
<insert id="insertBatch" parameterType="list">
insert into admin(name,password,flag,ctime) values
<foreach collection="list" item="a" separator=",">
(#{a.name},#{a.password},#{a.flag},now())
</foreach>
</insert>
数据库数据的批量下载
Controller
@RequestMapping(value = "/download.do",method = {RequestMethod.GET})
public void download(HttpServletResponse response) throws IOException {
service.download(response);
}
service层
@Override
public void download(HttpServletResponse response) throws IOException {
//设置响应头信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + System.currentTimeMillis() + ".xlsx");
//基于EasyExcel实现Excel表格的生成
EasyExcel.write(response.getOutputStream(), Admin.class).sheet("自动导出").doWrite(dao.selectAll());
}
