signed

QiShunwang

“诚信为本、客户至上”

SpringBoot1.5.3.RELEASE整合2.1.6easyexcel导入导出.xlsx文件

2021/6/3 17:33:27   来源:

Easyexcel文档

注意:easyexcel必须导入对应版本的poi,否则会报错

<dependency>
		  <groupId>com.alibaba</groupId>
		  <artifactId>easyexcel</artifactId>
		  <version>2.1.6</version>
	  </dependency>
	  <dependency>
		  <groupId>org.apache.poi</groupId>
		  <artifactId>poi</artifactId>
		  <version>3.17</version>
	  </dependency>
	  <dependency>
		  <groupId>org.apache.poi</groupId>
		  <artifactId>poi-scratchpad</artifactId>
		  <version>3.17</version>
	  </dependency>
	  <dependency>
		  <groupId>org.apache.poi</groupId>
		  <artifactId>poi-ooxml</artifactId>
		  <version>3.17</version>
	  </dependency>

创建实体

public class dict implements BaseEntity {

    @ExcelProperty(value = "序号",index = 0)
    private String serialNo;

    @ExcelProperty(value = "编码",index = 1)
    private String code;

	//标识忽略
    @ExcelIgnore
    private String desc;

}

创建监听对象

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.dao.Dao;
import com.entity.Dict;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yhh
 * @Description:
 * @date 2021/6/1 10:19
 */
@Component
public class DictListener extends AnalysisEventListener<Dict> {

    @Autowired
    private Dao dao ;

    private static final Logger LOGGER =
            LoggerFactory.getLogger(com.listener.DictListener.class);

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<Dict> list = new ArrayList<Dict>();

    /**
     * 每次创建Listener的时候需要把spring管理的类传进来
     * @param dao
     */
    public DictListener(Dao dao){
        this.dao =dao ;
    }

	//一条数据就会被调用一次
    @Override
    public void invoke(Dict dict, AnalysisContext analysisContext) {
        System.out.println("invoke方法被调用");
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(dict));
        list.add(dict);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("doAfterAllAnalysed方法 被调用");
        // 这里也要保存数据,分批次后最后几条不足5条避免丢失,确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    public void saveData() {
        LOGGER.info("{}条数据,开始存储数据库!", list.size());
        dao.batchSave(list);
        LOGGER.info("存储数据库成功!");
    }
}

controller

/**
 * @author yhh
 * @Description:导入excel文档数据
 * @date 2021/6/1 9:32
 */
@RestController
@RequestMapping("excel")
public class ExcelController  {

    @Autowired
    private dao dao ;

    /**
     * 读取 excel
     * @return
     */
    @PostMapping("upload")
    @Transactional
    public String upload(MultipartFile file) throws IOException {
//         sheet里面可以传参 根据sheet下标读取或者根据名字读取 不传默认读取第一个
        EasyExcel.read(file.getInputStream(), Dict.class,
                new DictListener(dao)).sheet().doRead();
        return "success";
    }

    @GetMapping("download")
    @Transactional
    public void download(HttpServletResponse response) throws Exception {
        // 这里注意 可能使用swagger 会导致各种问题,请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("模板", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), Dict.class).sheet("模板").doWrite(dao.getDate());
    }

}

postman测试

在这里插入图片描述

成功导入保存到数据库