easyexcel实战

导入依赖


 	com.alibaba
	easyexcel
	2.0.5

下载模板(部分列数据需指定)

easyexcel实战_第1张图片

1.创建和实体类对应的excel放在项目某目录下

easyexcel实战_第2张图片

2.创建对应的实体类

使用 @ExcelProperty 注解使实体类对应excel表头
value:excel表头名
index:表头下标(从0开始)
可以只使用一个

public class CPMXEntity {
    @ExcelProperty("模型名称")
    private String mc;
    @ExcelProperty("描述")
    private String ms;
    @ExcelProperty("评分类型")
    private String pflx;
    
	省略构造器 get/set...
}

3.JS

easyexcel实战_第3张图片

4.创建对应的监听器

package cn.chinaunicom.util.listener;

import cn.chinaunicom.entity.PageData;
import cn.chinaunicom.entity.jxpc.CPMXEntity;
import cn.chinaunicom.service.jxpc.B_JXPC_CPMXService;
import cn.chinaunicom.service.system.DictionariesService;
import cn.chinaunicom.util.Jurisdiction;
import cn.chinaunicom.util.UuidUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;
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;
import java.util.Map;

/**
 * TODO 〈一句话功能简述〉
 * 

* 〈功能详细描述〉 描述 * * @author hekaiyun * @see [相关类/方法][可选] * @since [产品/模块版本] 2019/10/18 */ @Component public class B_JXPC_CPMXListener extends AnalysisEventListener implements SheetWriteHandler { private static final Logger LOGGER = LoggerFactory.getLogger(B_JXPC_CPMXListener.class); @Autowired private B_JXPC_CPMXService cpmxService; @Autowired private DictionariesService dictionariesService; /** * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 1; List list = new ArrayList(); @Override public void invoke(CPMXEntity b_jxpc_cpmxEntity, AnalysisContext analysisContext) { list.add(b_jxpc_cpmxEntity); if (list.size() >= BATCH_COUNT) { saveData(); list.clear(); } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { saveData(); } /** * 加上存储数据库 */ private void saveData() throws NullPointerException { //获取当前登录用户ID String userId = Jurisdiction.getUserId(); PageData pd = new PageData(); for (CPMXEntity cpmx : list) { pd = new PageData(); if (!"".equals(dictionariesTranslate(cpmx.getPflx()))) { pd.put("SYSTEMID", UuidUtil.get32UUID()); //主键 pd.put("MC", cpmx.getMc()); //模型名称 pd.put("MS", cpmx.getMs()); //描述 pd.put("PFLX", dictionariesTranslate(cpmx.getPflx())); //评分类型 pd.put("CJR", userId); //创建人 pd.put("XGR", userId); //修改人 try { cpmxService.save(pd); } catch (Exception e) { e.printStackTrace(); } } } } @Override public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { } @Override public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { //1.查询数据 List list = new ArrayList(); List> cpmx = dictionariesService.getField("a7287249410f42ec8efe5653795c1825"); if (cpmx.size() > 0) { for (Map map : cpmx) { list.add(map.get("NAME")); } } String[] pflx = list.toArray(new String[list.size()]); //2.填充数据 CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 9999, 2, 2); DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper(); DataValidationConstraint constraint = helper.createExplicitListConstraint(pflx); DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); writeSheetHolder.getSheet().addValidationData(dataValidation); } //字典翻译 private String dictionariesTranslate(String dictionaries) throws NullPointerException { String str = dictionariesService.queryBianma(dictionaries.trim()).getString("BIANMA"); if (str != null) { return str; } return ""; } }

  1. 核心代码解析
    easyexcel实战_第4张图片

  2. 下载监听器需实现 **SheetWriteHandler **接口
    重写 beforeSheetCreateafterSheetCreate方法

  3. 需注意:
    一般在监听器里会注入对应的sevice接口用于保存数据,但我们是从controller(如下)中接收到请求后会调用到监听器,由于controller中没有service接口,会出现空指针异常。
    因此,我们将整个监听器作为组件 @Component 注入到监听器中
    easyexcel实战_第5张图片

5.Controller

package cn.chinaunicom.controller.excel;

import cn.chinaunicom.controller.base.BaseController;
import cn.chinaunicom.entity.PageData;
import cn.chinaunicom.entity.jxpc.*;
import cn.chinaunicom.util.ExcelUtil;
import cn.chinaunicom.util.PathUtil;
import cn.chinaunicom.util.listener.*;
import com.alibaba.excel.EasyExcel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * excel相关操作
 */
@Controller
@RequestMapping("/excel")
public class ExcelController extends BaseController{

    @Autowired
    B_JXPC_CPZBListener cpzbListener;
   
    /**
     * 判断模板是否存在
     */
    @RequestMapping("/template")
    @ResponseBody
    public Object template() throws Exception{
        Mapmap = new HashMap();
        PageData pd = new PageData();
        pd = this.getPageData();
        //获取模板文件名
        String fileName = "/" + pd.getString("fileName") + ".xlsx";
        //模板存放路径
        String path = PathUtil.getClasspath() + "template";
        File file = new File(path + fileName);
        if (file.exists()){
            map.put("result","success");
        }else {
            map.put("result","error");
        }
        return map;
    }

    //下载excel模板(列数据需动态变化)
    @RequestMapping("/getTemplate")
    public void downloadZSD(HttpServletResponse response) throws IOException{
        PageData pd = new PageData();
        pd = this.getPageData();
        //获取页面参数
        String fileName = pd.getString("fileName");
        //拼接文件名
        String name = "/" + fileName + ".xlsx";
        String path = PathUtil.getClasspath() + "template";
        String templateFileName = path + name;
        //设置头部
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx");
        //根据参数选择不同的写入
        //测评模板
        if ("cpmx".equals(fileName)){
        	EasyExcel.write(response.getOutputStream()).withTemplate(templateFileName).sheet().registerWriteHandler(cpmxListener).doWrite(new ArrayList());
        }
        
		其他...
   
    /**
     * 下载Excel模板(其他,列数据没有限制)
     */
    @RequestMapping("/download")
    public void downloadTemplate (HttpServletResponse response) throws Exception {
        PageData pd = new PageData();
        pd = this.getPageData();
        //获取模板文件名
        String fileName = "/" + pd.getString("fileName") + ".xlsx";
        //模板存放路径
        String path = PathUtil.getClasspath() + "template";
        //调用下载模板工具
        ExcelUtil.download(fileName,path,response);
    }

注:

在这里插入图片描述
由于是前端发送请求下载excel,所以记得设置头部
easyexcel实战_第6张图片

根据模板写出文件

实体类(如上)

监听器

1.需继承 AnalysisEventListener
easyexcel实战_第7张图片
2. 泛型为对应的实体类
3. 重写 invokedoAfterAllAnalysed方法

@Component
public class B_JXPC_CPMXListener extends AnalysisEventListener implements SheetWriteHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(B_JXPC_CPMXListener.class);

    @Autowired
    private B_JXPC_CPMXService cpmxService;

    @Autowired
    private DictionariesService dictionariesService;

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

    @Override
    public void invoke(CPMXEntity b_jxpc_cpmxEntity, AnalysisContext analysisContext) {
        list.add(b_jxpc_cpmxEntity);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
    }

    /**
     * 加上存储数据库
     */
    private void saveData() throws NullPointerException {
        //获取当前登录用户ID
        String userId = Jurisdiction.getUserId();
        PageData pd = new PageData();
        for (CPMXEntity cpmx : list) {
            pd = new PageData();
            if (!"".equals(dictionariesTranslate(cpmx.getPflx()))) {
                pd.put("SYSTEMID", UuidUtil.get32UUID());               //主键
                pd.put("MC", cpmx.getMc());                             //模型名称
                pd.put("MS", cpmx.getMs());                             //描述
                pd.put("PFLX", dictionariesTranslate(cpmx.getPflx()));  //评分类型
                pd.put("CJR", userId);                                  //创建人
                pd.put("XGR", userId);                                  //修改人
                try {
                    cpmxService.save(pd);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

导入EXCEL

Controller

 @RequestMapping("/readPLMXData")
    @ResponseBody
    public Object readPLMXData(MultipartFile file) {
        Map map = new HashMap<>();
        String errInfo = "success";

        try {
            EasyExcel.read(file.getInputStream(), B_JXPC_PLMXEntity.class, b_jxpc_plmxListener).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String str = (String) transactional.get();
        if (null != str) {
            map.put("result", str);
            transactional.remove();
            return map;
        }

        map.put("result", errInfo);
        return map;
    }

listlistener

@Component
@SuppressWarnings("all")
@Scope(value = WebApplicationContext.SCOPE_REQUEST,proxyMode = ScopedProxyMode.TARGET_CLASS)
public class B_JXPC_PLMXListener extends AnalysisEventListener implements SheetWriteHandler {

    @Autowired
    private B_JXPC_PLMXService b_jxpc_plmxService;
    @Autowired
    private DictionariesService dictionariesService;

    private static final Logger LOGGER = LoggerFactory.getLogger(B_JXPC_PLMXEntity.class);

    //设置每隔多少条存储数据库
    private static final int BATCH_COUNT = 1;

    //定义List存储读取到的数据
    List list = new ArrayList();

    /**
     * 初始化调用
     * 读取excel数据:继承 AnalysisEventListener
     * invoke
     */
    @Override
    public void invoke(B_JXPC_PLMXEntity data, AnalysisContext context){
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        //解析到数据,存入list
        list.add(data);
    }

    /**
     * 读取完成调用
     * 读取excel数据:继承 AnalysisEventListener
     * doAfterAllAnalysed
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context){
        try {
           b_jxpc_plmxService.saveData(list);
        }catch (Exception e){
            e.printStackTrace();
        }
        LOGGER.info("所有数据解析完成!");
    }
    ...

  • 注:在监听器中需使用@Scope改为多例模式

在serviceImpl中保存即可

public void saveData(List list) throws Exception{
		PageData pd = null;

		//获取当前登录用户ID
		String userId = Jurisdiction.getUserId();

		for (int i = 0; i < list.size(); i++) {
			String num = String.valueOf(i+1);
			pd = new PageData();

			//获取字段(翻译)
			String plfs = Translation.findBianma(list.get(i).getPlfs(),null);
			if (num == plfs){
				ExcelController.transactional.set(num);
				throw new Exception("'评论模型':数据错误");
			}

			//获取字段(直接获取)
			String mxmc = list.get(i).getMxmc();
			String mxms = list.get(i).getMxms();

			//将字段设置到map
			pd.put("SYSTEMID", UuidUtil.get32UUID());
			pd.put("MXMC", mxmc);
			pd.put("PLFS", plfs);
			pd.put("MXMS", mxms);
			pd.put("CJR", userId);
			pd.put("XGR", userId);
			pd.put("SFQY", "0");

			try {
				save(pd);
			}catch (Exception e){
				ExcelController.transactional.set(num);
				throw new NullPointerException("'评论模型':保存错误");
			}
		}
		System.out.println("保存成功");
	}
  • 也可不创建实体类进行数据操作,具体参考easyExcel官方文档

你可能感兴趣的:(easyexcel实战)