赞
踩
目录
1.3CustomMergeStrategy 合并策略(已改)
1.4 DownHandler 下拉处理(已解决大数据问题)
项目中常见的导出 一般使用 EasyExcel/POI,这里简单的列出了easyExcel 的用,easyExcel 使用简单方便,内存占用低,不会导致oom,不过导入导出要求多的话,写解析器也难受,哎本来写了很多的,结果好多找不到,然后暂时又没用到。在这里取出了常用的一些工具类,导出添加下拉框,单元格合并,多sheet导出等。导入则通过注解 解析字典值或校验唯一值,通过自定义的批量方法每500条插入一次
<!--excel导入导出--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.6</version> </dependency>
- /**
- * 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<Integer,List<String>> 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);
- }
- /**
- * 自定义屏蔽字段加自定义标题
- */
- public static void downloadMergeTitle(OutputStream outputStream , String sheetName,Class<?> clazz, List<?> data, Set<String> set){
- EasyExcel.write(outputStream, clazz)
- .excludeColumnFiledNames(set)
- .relativeHeadRowIndex(1)
- .registerWriteHandler(new CustomTitleWriteHandler(clazz,sheetName,set))
- .registerWriteHandler(writeCenterStyleBorder())
- .autoCloseStream(Boolean.TRUE)
- .sheet(sheetName)
- .doWrite(data);
- }
- /**
- * 多个sheet页导出
- */
- public static void writeExcels(HttpServletResponse response,List<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.size();i++){
- WriteSheet writeSheet = EasyExcel.writerSheet(i, "sheet"+i).build();
- excelWriter.write(data.get(i), writeSheet);
- }
- } finally {
- if(excelWriter != null){
- excelWriter.finish();
- }
- }
- }
- /**
- * 模板复制导出
- * @param data 数据结构最外层为需要导出的sheet页个数,里层为多种数据格式的集合,一般为list和map组合成的混合list
- * @param templateFile 模板本地路径
- */
- public static void copyFillTemplate(HttpServletResponse response,List<List<?>> 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<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<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, "UTF-8");
- // 告诉浏览器用什么软件可以打开此文件
- response.setHeader("content-Type", "application/vnd.ms-excel");
- response.setCharacterEncoding("utf8");
- response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'"+fileName+ +"."+ ExcelTypeEnum.XLSX);
- 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.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 <T> 中间接收类
- */
- @Getter
- public class CommonListener<T> extends AnalysisEventListener<T> {
- /**
- * 执行的插入的service
- */
- private final Consumer<List<T>> p;
- /**
- * 字典
- */
- private final Map<String, Map<String,Object>> itemMap;
- /**
- * 中间类的字段
- */
- Field[] fields ;
- /**
- * 初始化参数,server 执行
- * @param itemMap 字典数据,从里面去对应的数据
- * @param p 执行方法
- */
- public CommonListener(Map<String,Map<String,Object>> itemMap,Class<T> tClass, Consumer<List<T>> p) {
- this.p = p;
- this.itemMap = itemMap;
- this.fields = tClass.getDeclaredFields();
- }
- /**
- * 批量插入数据的大小
- */
- private final int BATCH_COUNT = 500;
- /**
- * 存储数据的集合
- */
- private final List<T> rows = new ArrayList<>();
- /**
- * 存储数据的集合
- */
- private final Map<String, Set<String>> unique = new HashMap<>();
- /**
- * 存放失败的数据及原因
- */
- private final List<String> 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<String> 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());
- }
- }
- }
- /**
- * 自定义单元格合并策略
- * @author pw
- */
- public class CustomMergeStrategy implements RowWriteHandler {
- /**
- * 主键下标
- */
- private Integer pkIndex;
-
- /**
- * 需要合并的列的下标集合
- */
- private final List<Integer> 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<CellRangeAddress> 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注解必须指定主键");
- }
-
- }
- }
- 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<Integer, String[]> dropDownMap;
-
- private int index;
-
- public DownHandler(Map<Integer, String[]> 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);
- }
- }
- /**
- * 自定义注解,用于判断是否需要合并以及合并的主键
- * @author pw
- */
- @Target({ElementType.FIELD})
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- public @interface CustomMerge {
-
- /**
- * 是否需要合并单元格
- */
- boolean needMerge() default false;
-
- /**
- * 是否是主键,即该字段相同的行合并
- */
- boolean isPk() default false;
- }
- /**
- * 数据来源解析
- * @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 {};
- }
- /**
- * @author pw
- * @date 2022/11/17
- */
- @Documented
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.FIELD})
- public @interface DropDown {
- String[] value();
- }
- /**
- * @author pw
- */
-
- public enum ExcelFieldType{
- /**
- * 字典
- */
- DICT ,
- /**
- * 唯一值
- */
- UNIQUE
- }
- import com.alibaba.excel.annotation.ExcelIgnore;
- import com.alibaba.excel.write.handler.SheetWriteHandler;
- import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
- import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
- import lombok.var;
- import org.apache.poi.ss.usermodel.*;
- import org.apache.poi.ss.util.CellRangeAddress;
-
- import java.lang.reflect.Field;
- import java.util.Set;
-
- /**
- * @description: 表格标题处理
- * @author: pw
- * @date: 2023/3/2 17:00
- **/
- public class CustomTitleWriteHandler implements SheetWriteHandler {
-
- /**
- * 标题
- */
- private final String fileName;
-
- /**
- * DTO数据类型
- */
- private final Class<?> elementType;
-
- /**
- * 过滤的字段
- */
- private final Set<String> set;
- public CustomTitleWriteHandler(Class<?> elementType, String fileName, Set<String> set) {
- this.fileName = fileName;
- this.elementType = elementType;
- this.set = set;
- }
-
- @Override
- public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
-
- Workbook workbook = writeWorkbookHolder.getWorkbook();
- Sheet sheet = workbook.getSheetAt(0);
- Row row1 = sheet.createRow(0);
- row1.setHeight((short) 800);
- Cell cell = row1.createCell(0);
- //设置标题
- cell.setCellValue(fileName);
- CellStyle cellStyle = workbook.createCellStyle();
- cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
- cellStyle.setAlignment(HorizontalAlignment.CENTER);
- Font font = workbook.createFont();
- font.setBold(true);
- font.setFontHeight((short) 400);
- font.setFontName("宋体");
- cellStyle.setFont(font);
- cell.setCellStyle(cellStyle);
- // 获取clazz所有的属性
- Field[] fields = this.elementType.getDeclaredFields();
- //计算合并的长度
- int mergeLength = fields.length - 1 - (null != set ? set.size() : 0);
- //过滤注解屏蔽字段
- for(Field f:fields){
- if(f.isAnnotationPresent(ExcelIgnore.class)){
- mergeLength--;
- }
- }
- sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, mergeLength));
- }
- }
- /**
- * @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;
- }
- @ApiOperation(value = "导入数据")
- @PostMapping("/importData")
- public R<Object> 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);
- }
- @Override
- public R<Object> importData(MultipartFile file) throws IOException {
- //填充对应词典
- Map<String,Map<String,Object>> 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<UserModel> commonListener = new CommonListener<>(map, UserModel.class,this::excelBatch);
- EasyExcel.read(file.getInputStream()).head(UserModel.class).registerReadListener(commonListener).sheet().doRead();
- List<String> 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<UserModel> list = new ArrayList<>();
- Map<Integer,String[]> 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<SysDictItem> dictByType = DictUtil.getDictItemList(type);
- // List<SysDictItem> 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<String>
- */
- private Map<String,Object> getDictItemKey(String type){
- //优化后的接口 DictUtil 字典工具类,其它文章里https://blog.csdn.net/weixin_42653892/article/details/126827174
- return DictUtil.getDictItemNameMap(type);
- // List<SysDictItem> dictByType = dictItemService.getDictByType(type);
- // if(null!=dictByType){
- // return //dictByType.stream().collect(Collectors.toMap(SysDictItem::getDictItemName, SysDictItem::getDictItemCode));
- // }
- // return new HashMap<>(4);
- }
- @Override
- public boolean excelBatch(Collection<UserModel> 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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。