easyExcel导入导出

目录

EasyExcel工具类

pom导入依赖

1.相关代码

1.1 EasyExcel导出工具类

1.2CommonListener导入侦听器

1.3CustomMergeStrategy 合并策略

1.4 DownHandler 下拉处理

1.5 CustomMerge 合并单元格的注解

1.6 FieldDispose 导入自定义解析注解

1.7 DropDown 下拉注解

1.8 ExcelFieldType自定义数据解析常量

2 .使用方法

2.1 导出导入实体--注解使用

2.2 Controller

2.3 service 调用

2.4 自定义批量方法 


EasyExcel工具类

       项目中常见的导出 一般使用 EasyExcel/POI,这里简单的列出了easyExcel 的用,easyExcel 使用简单方便,内存占用低,不会导致oom,不过导入导出要求多的话,写解析器也难受,哎本来写了很多的,结果好多找不到,然后暂时又没用到。在这里取出了常用的一些工具类,导出添加下拉框,单元格合并,多sheet导出等。导入则通过注解 解析字典值或校验唯一值,通过自定义的批量方法每500条插入一次

pom导入依赖


    com.alibaba
    easyexcel
    2.2.6

1.相关代码

1.1 EasyExcel导出工具类

/**
 * Excel相关处理
 * @author pw
 */
public class ExcelUtil {
	/**
	 *  单个sheet页导出
	 */
	public static void writeExcel(HttpServletResponse response, List data, String fileName, String sheetName, Class clazz) throws Exception {
		 EasyExcel.write(getOutputStream(fileName, response), clazz)
				.excelType(ExcelTypeEnum.XLSX).sheet(sheetName)
				.registerWriteHandler(getCellStyle()).doWrite(data);
	}

	/**
	 *  sheet页导出.设置下拉框
	 */
	public static void writeExcel(HttpServletResponse response, List data, String fileName, String sheetName,Map> dropDownMap, Class clazz) throws Exception {
	 EasyExcel.write(getOutputStream(fileName, response), clazz)
				.excelType(ExcelTypeEnum.XLSX).sheet(sheetName)
			 	.registerWriteHandler(new DownHandler(dropDownMap))
				.registerWriteHandler(getCellStyle()).doWrite(data);
	}
	/**
	 *  合并导出
	 */
	public static void writeExcelCustomMerge(HttpServletResponse response, List data, String fileName, String sheetName, Class clazz) throws Exception {
		EasyExcel.write(getOutputStream(fileName, response), clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(getCellStyle())
				.head(clazz)
				.registerWriteHandler(new CustomMergeStrategy(clazz))
				.doWrite(data);
	}

	/**
	 *   多个sheet页导出
	 */
	public static void writeExcels(HttpServletResponse response,List> data, String fileName, Class clazz) throws Exception{
		ExcelWriter excelWriter = null;
		try{
			excelWriter = EasyExcel.write(getOutputStream(fileName, response), clazz).excelType(ExcelTypeEnum.XLSX).registerWriteHandler(getCellStyle()).build();
			for(int i=0;i> data, String fileName,String templateFile) throws Exception{
		//excel模板
		File file = new File(templateFile);
		ExcelWriter excelWriter = null;
		try (FileInputStream fileInputStream = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
			//通过poi复制出需要的sheet个数的模板
			XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
			workbook.setSheetName(0, "sheet1");
			for (int i = 1; i < data.size();i++) {
				workbook.cloneSheet(0, "sheet"+(i+1));
			}
			workbook.write(bos);
			byte[] bArray = bos.toByteArray();
			InputStream is = new ByteArrayInputStream(bArray);
			//通过easyExcel塞入参数
			excelWriter = EasyExcel.write(getOutputStream(fileName, response)).withTemplate(is).build();
			fillTemplateData(excelWriter,data);
		} finally {
			if(excelWriter != null){
				excelWriter.finish();
			}
		}
	}

	/**
	 * 模板导出
	 */
	public static void fillTemplate(HttpServletResponse response,List> data, String fileName,String templateFile) throws Exception{
		ExcelWriter excelWriter = null;
		try  {
			excelWriter = EasyExcel.write(getOutputStream(fileName, response)).withTemplate(new File(templateFile) ).build();
			fillTemplateData(excelWriter,data);
		} finally {
			if(excelWriter != null){
				excelWriter.finish();
			}
		}
	}
	/**
	 * 填充模板数据
	 * @param data 数据结构最外层为需要导出的sheet页个数,里层为多种数据格式的集合,一般为list和map组合成的混合list
	 */
	private static void fillTemplateData(ExcelWriter excelWriter, List> data){
		for (int i = 0; i < data.size(); i++) {
			WriteSheet writeSheet = EasyExcel.writerSheet(i).build();
			for(Object o:data.get(i)){
				excelWriter.fill(o, writeSheet);
			}
		}
	}

	/**
	 * 设置请求
	 */
	private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
		fileName = URLEncoder.encode(fileName +"."+ ExcelTypeEnum.XLSX, "UTF-8");
		// 告诉浏览器用什么软件可以打开此文件
		response.setHeader("content-Type", "application/vnd.ms-excel");
		response.setCharacterEncoding("utf8");
		response.setHeader("content-disposition",  "attachment;filename="+fileName+";"+"filename*=utf-8''"+fileName);
		return response.getOutputStream();
	}
	/**
	 * 设置样式
	 */
	private static HorizontalCellStyleStrategy getCellStyle(){
		//表头样式
		WriteCellStyle headWriteCellStyle = new WriteCellStyle();
		//设置表头居中对齐
		headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
		//内容样式
		WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
		//设置内容靠左对齐
		contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
		return new HorizontalCellStyleStrategy(headWriteCellStyle,contentWriteCellStyle);
	}
}

1.2CommonListener导入侦听器

插入方法已优化,使用的是1.8的consumer,传入自定义方法

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.cloud.common.core.excel.annotation.FieldDispose;
import com.cloud.common.core.exception.CommonException;
import lombok.Getter;

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Consumer;

/**
 * 基于EasyExcel的导入工具类,插入使用批量插入,BATCH_COUNT=500
 * @author pw
 * @param  中间接收类
 */
@Getter
public class CommonListener extends AnalysisEventListener {
    /**
     *  执行的插入的service
     */
    private final Consumer> p;
    /**
     * 字典
     */
    private final Map> itemMap;
    /**
     * 中间类的字段
     */
    Field[] fields ;
    /**
     * 初始化参数,server 执行
     * @param itemMap 字典数据,从里面去对应的数据
     * @param p 执行方法
     */
    public CommonListener(Map> itemMap,Class tClass, Consumer> p) {
        this.p = p;
        this.itemMap = itemMap;
        this.fields = tClass.getDeclaredFields();
    }
    /**
     * 批量插入数据的大小
     */
    private final int BATCH_COUNT = 500;
    /**
     * 存储数据的集合
     */
    private final List rows = new ArrayList<>();
    /**
     * 存储数据的集合
     */
    private final Map> unique = new HashMap<>();
    /**
     * 存放失败的数据及原因
     */
    private final List msgList = new ArrayList<>();

    @Override
    public void onException(Exception exception, AnalysisContext context) {
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            msgList.add(String.format("第%s行,第%s列解析异常,数据为:%s",excelDataConvertException.getRowIndex(),
                    excelDataConvertException.getColumnIndex(),excelDataConvertException.getCellData()));
        }
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        ReadRowHolder readRowHolder = context.readRowHolder();
        try {
            for ( Field field : fields )  {
                //得到属性值
                field.setAccessible(true);
                String value = (String) field.get(data);
                if(field.isAnnotationPresent(FieldDispose.class)){
                    //获取字段注解
                    FieldDispose annotation = field.getAnnotation(FieldDispose.class);
                    switch (annotation.type()){
                        //字典替换
                        case DICT:
                            if(!itemMap.get(annotation.value()).containsKey(value)){
                                msgList.add(String.format("第%s行异常,原因%s,数据为:%s",readRowHolder.getRowIndex()+1,annotation.errorMessage(),value));
                                return;
                            }
                            field.set(data, itemMap.get(annotation.value()).get(value));
                            break;
                        //唯一值判断
                        case UNIQUE:
                            if(unique.containsKey(annotation.value())){
                                if(unique.get(annotation.value()).contains(value)){
                                    msgList.add(String.format("第%s行异常,原因%s,数据为:%s",readRowHolder.getRowIndex()+1,annotation.errorMessage(),value));
                                    return;
                                }
                            }else {
                                Set m = new HashSet<>();
                                m.add(value);
                                unique.put(annotation.value(),m);
                            }
                            break;
                        default:break;
                    }
                }
            }
            rows.add(data);
            if(rows.size()>=BATCH_COUNT){
                this.saveBatch();
            }
        }catch (Exception e){
            msgList.add(String.format("第%s行异常,原因:%s",readRowHolder.getRowIndex()+1,e.getMessage()));
        }
    }

    /**
     * 数据解析完成执行
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if(rows.size()>0){
            this.saveBatch();
        }
    }

    private void saveBatch(){
        try {
            p.accept(rows);
        }catch (CommonException e){
            rows.clear();
            msgList.add(e.getMessage());
        }
    }
}

1.3CustomMergeStrategy 合并策略(已改)

/**
 * 自定义单元格合并策略
 * @author pw
 */
public class CustomMergeStrategy implements RowWriteHandler {
    /**
     * 主键下标
     */
    private Integer pkIndex;

    /**
     * 需要合并的列的下标集合
     */
    private final List needMergeColumnIndex = new ArrayList<>();

    /**
     * DTO数据类型
     */
    private final Class elementType;

    public CustomMergeStrategy(Class elementType) {
        this.elementType = elementType;
    }

    @Override
    public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {

    }

    @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
        // 如果是标题,则直接返回
        if (isHead) {
            return;
        }
        // 获取当前sheet
        Sheet sheet = writeSheetHolder.getSheet();
        if (null == pkIndex) {
            this.lazyInit(writeSheetHolder);
        }
        // 判断是否需要和上一行进行合并
        // 不能和标题合并,只能数据行之间合并
        int rowNum = row.getRowNum();
        if (rowNum <= 1) {
            return;
        }
        // 获取上一行数据
        Row lastRow = sheet.getRow(row.getRowNum() - 1);
        // 将本行和上一行是同一类型的数据(通过主键字段进行判断),则需要合并
        if (lastRow.getCell(pkIndex).getStringCellValue().equalsIgnoreCase(row.getCell(pkIndex).getStringCellValue())) {
            boolean isMerged = false;
            for (Integer needMerIndex : needMergeColumnIndex) {
                //获得合并的区域
                List mergeRegions = sheet.getMergedRegions();
                for (int i = 0; i < mergeRegions.size(); i++) {
                    CellRangeAddress cellRangeAddress = mergeRegions.get(i);
                    // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                    if (cellRangeAddress.isInRange(rowNum - 1, needMerIndex)) {
                        sheet.removeMergedRegion(i);
                        cellRangeAddress.setLastRow(rowNum);
                        sheet.addMergedRegionUnsafe(cellRangeAddress);
                        isMerged = true;
                    }
                }
                if (!isMerged) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(rowNum - 1, row.getRowNum(),
                            needMerIndex, needMerIndex);
                    sheet.addMergedRegionUnsafe(cellRangeAddress);
                }
            }
        }
    }
    /**
     * 初始化主键下标和需要合并字段的下标
     */
    private void lazyInit(WriteSheetHolder writeSheetHolder) {

        // 获取当前sheet
        Sheet sheet = writeSheetHolder.getSheet();

        // 获取标题行
        Row titleRow = sheet.getRow(0);

        // 获取DTO所有的属性
        Field[] fields = this.elementType.getDeclaredFields();

        // 遍历所有的字段,因为是基于DTO的字段来构建excel,所以字段数 >= excel的列数
        for (Field theField : fields) {
            // 获取@ExcelProperty注解,用于获取该字段对应在excel中的列的下标
            ExcelProperty easyExcelAnn = theField.getAnnotation(ExcelProperty.class);
            // 为空,则表示该字段不需要导入到excel,直接处理下一个字段
            if (null == easyExcelAnn) {
                continue;
            }
            // 获取自定义的注解,用于合并单元格
            CustomMerge customMerge = theField.getAnnotation(CustomMerge.class);

            // 没有@CustomMerge注解的默认不合并
            if (null == customMerge) {
                continue;
            }
            for (int index = 0; index < fields.length; index++) {
                Cell theCell = titleRow.getCell(index);
                // 当配置为不需要导出时,返回的为null,这里作一下判断,防止NPE
                if (null == theCell) {
                    continue;
                }
                // 将字段和excel的表头匹配上
                if (easyExcelAnn.value()[0].equalsIgnoreCase(theCell.getStringCellValue())) {
                    if (customMerge.isPk()) {
                        pkIndex = index;
                    }
                    if (customMerge.needMerge()) {
                        needMergeColumnIndex.add(index);
                    }
                }
            }
        }
        // 没有指定主键,则异常
        if (null == this.pkIndex) {
            throw new IllegalStateException("使用@CustomMerge注解必须指定主键");
        }

    }
}

1.4 DownHandler 下拉处理(已解决大数据问题)

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.cloud.common.core.excel.annotation.DropDown;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * @author admin
 * @date 2020/5/17
 * @desc
 */
public class DownHandler implements SheetWriteHandler {

    private final Map dropDownMap;

    private int index;

    public DownHandler(Map dropDownMap) {
        this.dropDownMap = dropDownMap;
        this.index = 0;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Sheet sheet = writeSheetHolder.getSheet();
        ///开始设置下拉框 HSSFWorkbook
        DataValidationHelper helper = sheet.getDataValidationHelper();
        Field[] fields = writeWorkbookHolder.getClazz().getDeclaredFields();
        int length = fields.length;
        for (int i = 0; i < length; i++) {
           if(fields[i].isAnnotationPresent(DropDown.class)){
               dropDown(helper, sheet, i, fields[i].getDeclaredAnnotation(DropDown.class).value());
           }
        }
        if (dropDownMap == null) {
            return;
        }
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        dropDownMap.forEach((celIndex, value) -> {
            if(value.length>20){
                dropDownBigData( helper, workbook ,sheet,celIndex, value);
            }else {
                dropDown(helper, sheet,celIndex, value);
            }
        });
    }

    private void dropDown(DataValidationHelper helper, Sheet sheet, Integer celIndex, String[] value) {
        if(null== value || value.length<=0){
            return;
        }
        this.dropDown(helper, sheet,celIndex, helper.createExplicitListConstraint(value));
    }

    private void dropDownBigData(DataValidationHelper helper,Workbook workbook,Sheet sheet, Integer celIndex, String[] v) {
        // 定义sheet的名称
        String sheetName = "sheet" + celIndex;
        // 1.创建一个隐藏的sheet 名称为 proviceSheet
        Sheet sheet1 = workbook.createSheet(sheetName);
        // 从第二个工作簿开始隐藏
        this.index++;
        // 设置隐藏
        workbook.setSheetHidden(this.index, true);
        // 2.循环赋值
        for (int i = 0, length = v.length; i < length; i++) {
            // i:表示你开始的行数 0表示你开始的列数
            sheet1.createRow(i).createCell(0).setCellValue(v[i]);
        }
        Name name = workbook.createName();
        name.setNameName(sheetName);
        //代表 以A列1行开始获取N行下拉数据
        name.setRefersToFormula(sheetName + "!$A$1:$A$" + (v.length));
        // 设置下拉
        this.dropDown(helper, sheet,celIndex,  helper.createFormulaListConstraint(sheetName));
    }

    private void dropDown(DataValidationHelper helper, Sheet sheet, Integer celIndex, DataValidationConstraint constraint) {
        // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList addressList = new CellRangeAddressList(1, 100, celIndex, celIndex);
        // 数据有效性对象
        DataValidation dataValidation = helper.createValidation(constraint, addressList);
        // 处理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation) {
            //数据校验
            dataValidation.setSuppressDropDownArrow(true);
            //错误提示
            dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
            dataValidation.createErrorBox("提示", "此值与单元格定义数据不一致");
            dataValidation.setShowErrorBox(true);
            //选定提示
            dataValidation.createPromptBox("填写说明:","填写内容只能为下拉中数据,其他数据将导致导入失败");
            dataValidation.setShowPromptBox(true);
            sheet.addValidationData(dataValidation);
        } else {
            dataValidation.setSuppressDropDownArrow(false);
        }
        sheet.addValidationData(dataValidation);
    }
}

1.5 CustomMerge 合并单元格的注解

/**
 * 自定义注解,用于判断是否需要合并以及合并的主键
 * @author pw
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CustomMerge {

    /**
     * 是否需要合并单元格
     */
    boolean needMerge() default false;

    /**
     * 是否是主键,即该字段相同的行合并
     */
    boolean isPk() default false;
}

1.6 FieldDispose 导入自定义解析注解

/**
 * 数据来源解析
 * @author pw
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD})
@Documented
public @interface FieldDispose {
    /**
     * 解析类型
     */
    AnalyticalType type() default AnalyticalType.DICT;
    /**
     *绑定的数据,类型dict对应字典(传入的map),其他类型对应实体类字段
     */
    String[] value();
    /**
     * 错误提示
     */
    String errorMessage() default "";
    /**
     *仅拼接下使用,拼接间隔符,数组第几位即代表第几位后添加
     */
    String[] mark() default {};
}

1.7 DropDown 下拉注解

/**
 * @author pw
 * @date 2022/11/17
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface DropDown {
    String[] value();
}

1.8 ExcelFieldType自定义数据解析常量

/**
 * @author pw
 */

public enum ExcelFieldType{
    /**
     * 字典
     */
    DICT ,
/**
     * 唯一值
     */
    UNIQUE
}

2 .使用方法

2.1 导出导入实体--注解使用

/**
 * @author pw
 */
@Data
@ApiModel(value = "用户信息")
@ColumnWidth(20)
public class UserModel implements Serializable {

	@ApiModelProperty(value = "登录账号")
	@ExcelProperty(value = "登录账号",index=0)
	@FieldDispose(type = ExcelFieldType.UNIQUE,value = "username",errorMessage = "登录账号不允许重复" )
	private String username;

	@ApiModelProperty(value = "姓名")
	@ExcelProperty(value = "姓名",index=1)
	@FieldDispose(type = ExcelFieldType.UNIQUE,value ="nickName",errorMessage = "姓名不允许重复" )
	private String nickName;

	@ApiModelProperty(value = "性别")
	@ExcelProperty(value = "性别",index=2)
	@FieldDispose(value = DictCodeConstants.SEX,errorMessage = "该性别标识不存在" )
	private String sex;

	@ApiModelProperty(value = "手机号")
	@ExcelProperty(value = "手机号",index=3)
	private String phone;

	@ApiModelProperty(value = "密码")
	@ExcelProperty(value = "初始密码",index = 4)
	private String password;

	@ApiModelProperty(value = "职务")
	@ExcelProperty(value = "职务",index = 5)
	@FieldDispose(value = DictCodeConstants.USER_POST,errorMessage = "该职务标识不存在")
	private String post;

	@ApiModelProperty(value = "角色")
	@ExcelProperty(value ="角色",index = 6)
	@FieldDispose(value = "role",errorMessage = "该角色标识不存在")
	private String role;

	@ApiModelProperty("状态标识")
	@ExcelProperty(value = "状态标识",index = 7)
	@FieldDispose(value = DictCodeConstants.F_STATE,errorMessage = "该状态标识不存在")
	private String fstate;

	@ApiModelProperty("备注")
	@ExcelProperty(value = "备注",index = 8)
	private String remarks;
}

2.2 Controller

	@ApiOperation(value = "导入数据")
	@PostMapping("/importData")
	public R importData(@RequestParam("file") MultipartFile file) throws IOException {
		return userService.importData(file);
	}

	@ApiOperation(value = "模板下载和导出数据")
	@GetMapping("/exportData")
	public void exportData(HttpServletResponse response, UserDTO dto, @RequestParam("type") int type) throws Exception {
		userService.exportData(response,dto,type);
	}

2.3 service 调用

    @Override
    public R importData(MultipartFile file) throws IOException {
        //填充对应词典
        Map> map = new HashMap<>();
        map.put(DictCodeConstants.SEX,this.getDictItemKey(DictCodeConstants.SEX));
        map.put(DictCodeConstants.USER_POST,this.getDictItemKey(DictCodeConstants.USER_POST));
        map.put(DictCodeConstants.USER_CLASSIFY,this.getDictItemKey(DictCodeConstants.USER_CLASSIFY));
        map.put(DictCodeConstants.F_STATE,this.getDictItemKey(DictCodeConstants.F_STATE));
        map.put("role",sysRoleService.getRoleNameMap());
        //解析器
        CommonListener commonListener = new CommonListener<>(map, UserModel.class,this::excelBatch);
        EasyExcel.read(file.getInputStream()).head(UserModel.class).registerReadListener(commonListener).sheet().doRead();
        List msgList = commonListener.getMsgList();
        if(msgList.size()>0){
            return R.failed(StringUtils.join(msgList,","));
        }
        return R.ok();
    }

    @Override
    public void exportData(HttpServletResponse response, UserDTO dto, int type) throws Exception {
        List list = new ArrayList<>();
        Map dropDownMap = new HashMap<>(4);
        if(type == 1) {
            //查询需导出数据
            list = this.baseMapper.getExcelList(dto);
        }else {
            //填充下拉框
            dropDownMap.put(2,this.getDictItem(DictCodeConstants.SEX));
            dropDownMap.put(5,this.getDictItem(DictCodeConstants.USER_POST));
            dropDownMap.put(6,sysRoleService.getRoleName());
            dropDownMap.put(7,this.getDictItem(DictCodeConstants.USER_CLASSIFY));
            dropDownMap.put(8,this.getDictItem(DictCodeConstants.F_STATE));
        }
        ExcelUtil.writeExcel(response,list, String.valueOf(System.currentTimeMillis()), "科室人员", dropDownMap, UserModel.class);
    }
   /**
     * 获取下拉框字典
     * @param type 字典code
     * @return  String[]
     */
    private String[] getDictItem(String type){
  List dictByType = DictUtil.getDictItemList(type);
      //  List dictByType = dictItemService.getDictByType(type);
        if(null!=dictByType){
           return dictByType.stream().map(SysDictItem::getDictItemName).toArray(String[]::new);
        }
        return null;
    }
    
    /**
     * 获取字典 -name,key
     * @param type 字典code
     * @return  List
     */
    private Map getDictItemKey(String type){
//优化后的接口 DictUtil 字典工具类,其它文章里https://blog.csdn.net/weixin_42653892/article/details/126827174
  return DictUtil.getDictItemNameMap(type);
      //  List dictByType = dictItemService.getDictByType(type);
      //  if(null!=dictByType){
         //  return //dictByType.stream().collect(Collectors.toMap(SysDictItem::getDictItemName, SysDictItem::getDictItemCode));
  //      }
  //      return new HashMap<>(4);
    }

2.4 自定义批量方法 

  @Override
    public boolean excelBatch(Collection userList) {
         //数据处理及批量添加
        //返回提示
        String  returnMsg= "";
        if(b.length()>0){
            b.append("表格存在重复数据:");
            returnMsg=b.toString();
        }
        if(repeatData.size()>0){
            returnMsg+="数据库已存在数据:";
            returnMsg+=StringUtils.join(repeatData,",");
        }
        if(returnMsg.length()>0){
            throw new CommonException(returnMsg);
        }
        return true;
    }

你可能感兴趣的:(execl,java,spring,boot)