首页 > 编程语言 >java 实现Excel导入导出功能

java 实现Excel导入导出功能

时间:2022-12-12 10:56:17浏览次数:48  
标签:java Excel private 导入 importUser import class

本文记录

首先需要准备一个导入模板的实体类

import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

/**
 * 用户 Excel 导入 VO
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题
public class UserImportExcelVO {

    @ExcelProperty("登录名称")
    private String username;

    @ExcelProperty("用户名称")
    private String nickname;

    @ExcelProperty("部门编号")
    private Long deptId;

    @ExcelProperty("用户邮箱")
    private String email;

    @ExcelProperty("手机号码")
    private String mobile;

    @ExcelProperty(value = "用户性别", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.USER_SEX)
    private Integer sex;

    @ExcelProperty(value = "账号状态", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.COMMON_STATUS)
    private Integer status;

}

有了实体就可以直接写接口了

@GetMapping("/get-import-template")
    @ApiOperation("获得导入用户模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        // 手动创建导出 demo
        List<UserImportExcelVO> list = Arrays.asList(
                UserImportExcelVO.builder().username("admin").deptId(1L).email("[email protected]").mobile("15601691300")
                        .nickname("超级管理员").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(),
                UserImportExcelVO.builder().username("test").deptId(2L).email("[email protected]").mobile("15601701300")
                        .nickname("测试管理员").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build()
        );

        // 输出
        ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list);
    }

导入模板完成,那么接下来就是导入了,用户导入,如果是有部门、角色这些存在,就需要把部门和角色这两个字段设置为必须存在,不然就会报错

导入这里的返回根据自己来定,我这里使用了三个list来封装,一个更新、添加,还有一个失败

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;

import java.util.List;
import java.util.Map;

@ApiModel("管理后台 - 用户导入 Response VO")
@Data
@Builder
public class UserImportRespVO {

    @ApiModelProperty(value = "创建成功的用户名数组", required = true)
    private List<String> createUsernames;

    @ApiModelProperty(value = "更新成功的用户名数组", required = true)
    private List<String> updateUsernames;

    @ApiModelProperty(value = "导入失败的用户集合", required = true, notes = "key 为用户名,value 为失败原因")
    private Map<String, String> failureUsernames;

}

文件处理的工具类ExcelUtils

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * Excel 工具类
 *
 * @author Dshzs月
 */
public class ExcelUtils {

    /**
     * 将列表以 Excel 响应给前端
     *
     * @param response 响应
     * @param filename 文件名
     * @param sheetName Excel sheet 名
     * @param head Excel head 头
     * @param data 数据列表哦
     * @param <T> 泛型,保证 head 和 data 类型的一致性
     * @throws IOException 写入失败的情况
     */
    public static <T> void write(HttpServletResponse response, String filename, String sheetName,
                                 Class<T> head, List<T> data) throws IOException {
        // 输出 Excel
        EasyExcel.write(response.getOutputStream(), head)
                .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
                .sheet(sheetName).doWrite(data);
        // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
    }

    public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
       return EasyExcel.read(file.getInputStream(), head, null)
                .autoCloseStream(false)  // 不要自动关闭,交给 Servlet 自己处理
                .doReadAllSync();
    }

}

 

导入接口importExcel

@PostMapping("/import")
    @ApiOperation("导入用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class),
            @ApiImplicitParam(name = "updateSupport", value = "是否支持更新,默认为 false", example = "true", dataTypeClass = Boolean.class)
    })
    @PreAuthorize("@ss.hasPermission('system:user:import')")
    public CommonResult<UserImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
        return success(userService.importUsers(list, updateSupport));
    }
@Override
    @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
    public UserImportRespVO importUsers(List<UserImportExcelVO> importUsers, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(importUsers)) {
            throw exception(USER_IMPORT_LIST_IS_EMPTY);
        }
        UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
                .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
        importUsers.forEach(importUser -> {
            // 校验,判断是否有不符合的原因
            try {
                checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
                        importUser.getDeptId(), null);
            } catch (ServiceException ex) {
                respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
                return;
            }
            // 判断如果不存在,在进行插入
            AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
            if (existUser == null) {
                userMapper.insert(UserConvert.INSTANCE.convert(importUser)
                        .setPassword(encodePassword(userInitPassword)).setPostIds(new HashSet<>())); // 设置默认密码及空岗位编号数组
                respVO.getCreateUsernames().add(importUser.getUsername());
                return;
            }
            // 如果存在,判断是否允许更新
            if (!isUpdateSupport) {
                respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
                return;
            }
            AdminUserDO updateUser = UserConvert.INSTANCE.convert(importUser);
            updateUser.setId(existUser.getId());
            userMapper.updateById(updateUser);
            respVO.getUpdateUsernames().add(importUser.getUsername());
        });
        return respVO;
    }

到此就结束了,逻辑的话就看自己的业务来定了

标签:java,Excel,private,导入,importUser,import,class
From: https://www.cnblogs.com/Dshzs17/p/16975477.html

相关文章

  • java可以开发电脑桌面应用吗?java开发用什么软件?
    java开发PC桌面程序 Java是一门面向对象编程语言,作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程,那java可以开发电......
  • JAVA8 lambda之groupby三种用法
    一,有一个参数的groupby第一个参数:按照该参数规则进行分组。结果返回一个Map集合,Map的key是按照该规则执行后返回的每个结果,Map的value是一个List集合,该集合中的值是能满足......
  • 0停机迁移Nacos?Java字节码技术来帮忙
    摘要:本文介绍如何将SpringCloud应用从开源Consul无缝迁移至华为云Nacos。本文分享自华为云社区《0停机迁移Nacos?Java字节码技术来帮忙》,作者:华为云PaaS服务小智。1.市场......
  • Kotlin 和 Java 泛型的局限性、泛型擦除、星投影
    Hi大家好,我是DHL。公众号:ByteCode,专注分享有趣硬核原创内容,Kotlin、Jetpack、性能优化、系统源码、算法及数据结构、动画、大厂面经全文分为视频版和文字版,文字版:文......
  • 144-git config 及 git 初步导入命令
    这是全局的gitconfig--globaluser.name"admin"gitconfig--globaluser.email"[email protected]"gitconfig--globaluser.passwordadmin当前目录的:gitconfig......
  • Java性能调优System的gc垃圾回收方法
    java性能调优System的gc垃圾回收方法java性能调优System的gc垃圾回收方法示例解一、什么是System.gc()?​​System.gc()​​是用Java,C#和许多其他流行的高级编程语言提供的API......
  • JavaScript中的eval()
    evalJavaScript中的eval()函数可以接受一个字符串作为参数,并将其中的内容视为好像在书写时就存在于程序中的这个位置的代码。换句话说,可以在你写的代码中用程序生成代码并......
  • java方法的笔记
    方法方法的概念方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集注意:方法必须先创建才可以使用,该过程成为方法定义方法创建后并不是......
  • Java面向对象基础
    面向对象基础一、什么是面向对象把大象放进冰箱分为三步1、打开冰箱2、把大象放进冰箱3、关上冰箱假设我想把大象放进冰箱,使用面向过程的思想,我首先需要先思考如何......
  • java基本语法(史上最全)
    java基本语法(史上最全)(一)关键字和保留字关键字的定义和特点定义:被java语言赋予了特殊含义,用作专门用途的字符串。特点:关键字中所有字母都为小写。关键字不能用作变量名,......