整体流程:

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包:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>easyexcel</artifactId>
  4. <version>3.0.5</version>
  5. </dependency>

2.配置文件:

// springMVC.xml里面

  1. <!-- 配置文件上传 -->
  2. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  3. <!-- 最大可上传的文件大小 单位:byte 超出后会抛出MaxUploadSizeExceededException异常,可以异常解析器捕获 -->
  4. <property name="maxUploadSize" value="1048576"/>
  5. </bean>

3.配置线程池在工具包里面:

ThreadPoolSingle类

  1. package com.qyz.common.util;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.ThreadPoolExecutor;
  5. import java.util.concurrent.TimeUnit;
  6. public class ThreadPoolSingle {
  7. public ThreadPoolExecutor poolExecutor;//原生的线程池对象
  8. //私有构造器
  9. private ThreadPoolSingle(){
  10. poolExecutor=new ThreadPoolExecutor(4,10,
  11. 3, TimeUnit.SECONDS,
  12. new ArrayBlockingQueue<>(20),
  13. Executors.defaultThreadFactory(),
  14. new ThreadPoolExecutor.AbortPolicy());
  15. }
  16. //静态内部类
  17. static class ThreadPoolSingleFactory{
  18. public static ThreadPoolSingle single=new ThreadPoolSingle();
  19. }
  20. //公有静态方法
  21. public static ThreadPoolSingle getInstance(){
  22. return ThreadPoolSingleFactory.single;
  23. }
  24. //新增任务
  25. public void addTask(Runnable runnable){
  26. poolExecutor.submit(runnable);
  27. }
  28. }

解释:
单例模式:
作用:创建类的对象,唯一对象
实现方式:
1.懒汉式
2.饿汉式
3.双锁
4.IoDH(静态内部类)
5.枚举
4.线程池
池化技术:1.提高复用率 2.控制数量
线程池:可以提高线程的使用率,还可以有效控制线程的数量
实际开发中,使用线程的话,都是使用线程池,而且用原生线程池

  1. poolExecutor=new ThreadPoolExecutor(
  2. 核心线程数 最小线程数(不回收)
  3. 4,
  4. 最大线程数
  5. 10,
  6. 空闲时间
  7. 3,
  8. 空闲的时间单位,分钟
  9. TimeUnit.SECONDS,
  10. 阻塞队列 7
  11. new ArrayBlockingQueue<>(20),
  12. 线程创建工厂
  13. Executors.defaultThreadFactory(),
  14. 拒绝策略,4
  15. new ThreadPoolExecutor.AbortPolicy());
  16. 1.先触发核心线程数 2.添加到阻塞队列 3.触发最大线程数 4.触发拒绝策略*/

4.设置监听工具类

TypeReadListener 在listener包里面

  1. package com.qyz.common.listener;
  2. import com.alibaba.excel.context.AnalysisContext;
  3. import com.alibaba.excel.read.listener.ReadListener;
  4. import com.qyz.common.util.ThreadPoolSingle;
  5. import com.qyz.dao.TypeDao;
  6. import com.qyz.entity.Type;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class TypeReadListener implements ReadListener<Type> {
  10. private TypeDao dao;
  11. public TypeReadListener(TypeDao dao) {
  12. this.dao = dao;
  13. }
  14. //初始容量
  15. private List<Type> list1 = new ArrayList<>(1010);
  16. //读取的每一行
  17. @Override
  18. public void invoke(Type type, AnalysisContext analysisContext) {
  19. list1.add(type);
  20. if (list1.size() >= 1000) {
  21. //实现集合的复制,把需要线程池干的集合生成出来
  22. List<Type> child1 = new ArrayList<>(list1);
  23. //list代码清空复用list集合放止list调用自增方法减少效率
  24. list1.clear();//清理原集合
  25. //执行批处理
  26. ThreadPoolSingle.getInstance().addTask(() -> {
  27. dao.insertBatch(child1);
  28. });
  29. }
  30. }
  31. //整个表格读取结束
  32. @Override
  33. public void doAfterAllAnalysed(AnalysisContext analysisContext) {
  34. //执行最后不足1000条的数据
  35. dao.insertBatch(list1);
  36. }
  37. }

5.设置Controller里面的url

  1. @RequestMapping(value = "/upload.do",method = {RequestMethod.POST})
  2. @ResponseBody
  3. public JsonResult upload(MultipartFile file) throws IOException {
  4. return service.saveBatchV2(file);
  5. }

6.设置实体类属性和表格字段的匹配

  1. private Integer id;
  2. @ExcelProperty("类别名称")
  3. private String s_name; //类别名称
  4. @ExcelProperty("类别id")
  5. private Integer S_id; //类别id

7.设置service层的代码

  1. JsonResult saveBatchV2(MultipartFile file) throws IOException;

serviceImpl:

数据量比较大的时候使用这个:

  1. //可以抗住大文件的上传
  2. @Override
  3. public JsonResult saveBatchV2(MultipartFile file) throws IOException {
  4. //将上传的内容解析并添加到数据库
  5. EasyExcel.read(
  6. file.getInputStream(),//上传的文件内容-Excel表格
  7. Type.class,//每一行对应的类型
  8. new TypeReadListener(typeDao)).sheet().doRead();
  9. return JsonResult.ok();
  10. }

数据量较小的时候使用:

  1. @Override
  2. public JsonResult saveBatch(MultipartFile file) throws IOException {
  3. //将上传的内容解析并添加到数据库
  4. EasyExcel.read(
  5. file.getInputStream(),//上传的文件内容-Excel表格
  6. Type.class,//每一行对应的类型
  7. new PageReadListener(list -> {//获取的数据
  8. dao.insertBatch((List<Type>) list);
  9. })).sheet().doRead();
  10. return JsonResult.success(null);
  11. }

8.设置dao层的映射方法

  1. //批量新增
  2. int insertBatch(List<Type> list);

9.设置mapper的sql语句实现数据的

  1. <insert id="insertBatch" parameterType="list">
  2. insert into s_type(s_name,s_id) values
  3. <foreach collection="list" item="a" separator=",">
  4. (#{a.s_name},#{a.s_id})
  5. </foreach>
  6. </insert>

数据库数据的批量下载:

Controller层:

  1. @RequestMapping(value = "/download.do",method = {RequestMethod.GET})
  2. public void download(HttpServletResponse response) throws IOException {
  3. service.download(response);
  4. }

service层:

  1. @Override
  2. public void download(HttpServletResponse response) throws IOException {
  3. //设置响应头信息
  4. response.setContentType("application/vnd.ms-excel");
  5. response.setCharacterEncoding("utf-8");
  6. response.setHeader("Content-disposition", "attachment;filename=" + System.currentTimeMillis() + ".xlsx");
  7. //基于EasyExcel实现Excel表格的生成
  8. EasyExcel.write(response.getOutputStream(), Type.class).sheet("自动导出").doWrite(dao.selectAll());
  9. }