整体流程:
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.设置监听工具类
TypeReadListener 在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.TypeDao;
import com.qyz.entity.Type;
import java.util.ArrayList;
import java.util.List;
public class TypeReadListener implements ReadListener<Type> {
private TypeDao dao;
public TypeReadListener(TypeDao dao) {
this.dao = dao;
}
//初始容量
private List<Type> list1 = new ArrayList<>(1010);
//读取的每一行
@Override
public void invoke(Type type, AnalysisContext analysisContext) {
list1.add(type);
if (list1.size() >= 1000) {
//实现集合的复制,把需要线程池干的集合生成出来
List<Type> child1 = new ArrayList<>(list1);
//list代码清空复用list集合放止list调用自增方法减少效率
list1.clear();//清理原集合
//执行批处理
ThreadPoolSingle.getInstance().addTask(() -> {
dao.insertBatch(child1);
});
}
}
//整个表格读取结束
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//执行最后不足1000条的数据
dao.insertBatch(list1);
}
}
5.设置Controller里面的url
@RequestMapping(value = "/upload.do",method = {RequestMethod.POST})
@ResponseBody
public JsonResult upload(MultipartFile file) throws IOException {
return service.saveBatchV2(file);
}
6.设置实体类属性和表格字段的匹配
private Integer id;
@ExcelProperty("类别名称")
private String s_name; //类别名称
@ExcelProperty("类别id")
private Integer S_id; //类别id
7.设置service层的代码
JsonResult saveBatchV2(MultipartFile file) throws IOException;
serviceImpl:
数据量比较大的时候使用这个:
//可以抗住大文件的上传
@Override
public JsonResult saveBatchV2(MultipartFile file) throws IOException {
//将上传的内容解析并添加到数据库
EasyExcel.read(
file.getInputStream(),//上传的文件内容-Excel表格
Type.class,//每一行对应的类型
new TypeReadListener(typeDao)).sheet().doRead();
return JsonResult.ok();
}
数据量较小的时候使用:
@Override
public JsonResult saveBatch(MultipartFile file) throws IOException {
//将上传的内容解析并添加到数据库
EasyExcel.read(
file.getInputStream(),//上传的文件内容-Excel表格
Type.class,//每一行对应的类型
new PageReadListener(list -> {//获取的数据
dao.insertBatch((List<Type>) list);
})).sheet().doRead();
return JsonResult.success(null);
}
8.设置dao层的映射方法
//批量新增
int insertBatch(List<Type> list);
9.设置mapper的sql语句实现数据的
<insert id="insertBatch" parameterType="list">
insert into s_type(s_name,s_id) values
<foreach collection="list" item="a" separator=",">
(#{a.s_name},#{a.s_id})
</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(), Type.class).sheet("自动导出").doWrite(dao.selectAll());
}