Skip to content

文件导入导出

通过集成 Excel 导入导出功能,您可以显著提升数据处理的效率和灵活性,满足多样化的业务需求。

使用场景

在项目中集成 Excel 文件导入导出功能,可以显著提升数据处理效率,适用于数据报表生成、批量数据导入等场景。通过使用 Apache POIEasyExcel 等工具。

您可以轻松实现以下功能:

Excel 导出:
1. 将数据库中的数据导出为 Excel 文件,支持自定义表头和格式。
2. 适用于生成报表、数据备份等场景。

Excel 导入:
1. 将 Excel 文件中的数据导入到数据库,支持批量处理和校验。
2. 适用于批量数据录入、数据迁移等场景。

高性能处理:
1. 使用 EasyExcel 可以实现高效的大数据量导入导出,避免内存溢出问题。

灵活配置:
1. 支持自定义数据映射、格式校验和错误处理,满足复杂业务需求。

AOP切面

在项目中使用 AOP(面向切面编程)注解实现文件导入、导出功能,具有以下优势:

1. 代码解耦:将日志记录逻辑与业务逻辑分离,避免代码重复,提升代码可读性和可维护性。
2. 灵活性与扩展性:通过注解可以灵活地控制哪些方法需要记录日志,便于扩展和修改日志记录逻辑。
3. 非侵入性:无需修改现有业务代码,只需在方法上添加注解即可实现日志记录。
4. 集中管理:日志记录逻辑集中在切面中,便于统一管理和维护。
5. 提高开发效率:通过注解方式快速实现日志功能,减少重复代码编写。

定义注解

xiaomayi-common/xiaomayi-excel 模块中定义的登录日志的 AOP 切面 RequestExcelResponseExcel 文件。

  1. RequestExcel 切面文件
js
package com.xiaomayi.excel.annotation;

import com.xiaomayi.excel.listener.DefaultListReadListener;
import com.xiaomayi.excel.listener.ListReadListener;

import java.lang.annotation.*;

/**
 * <p>
 * 自定义导入Excel注解
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2023-10-04
 */
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestExcel {

    /**
     * 文件上传接口参数名定义,默认:file
     *
     * @return 返回结果
     */
    String fileName() default "file";

    /**
     * 文件数据读取监听器
     *
     * @return 返回监听器
     */
    Class<? extends ListReadListener<?>> readListener() default DefaultListReadListener.class;

    /**
     * 文件表头行数,不指定默认:-1
     * 备注:
     * 1、读取一个ExcelProperty注解,value有值时取其长度;
     * 2、如果value没值,则head取值:1
     *
     * @return 返回表头行数
     */
    int headRowNumber() default -1;

}
  1. ResponseExcel 切面文件
js
package com.xiaomayi.excel.annotation;

import com.alibaba.excel.support.ExcelTypeEnum;

import java.lang.annotation.*;

/**
 * <p>
 * 自定义导出Excel注解
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2023-10-04
 */
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseExcel {

    /**
     * 文件名称
     *
     * @return 返回结果
     */
    String name();

    /**
     * 文件后缀,默认:.xlsx
     *
     * @return 返回结果
     */
    ExcelTypeEnum suffix() default ExcelTypeEnum.XLSX;

    /**
     * 文件SHEET名称
     *
     * @return 返回结果
     */
    String sheetName() default "";

    /**
     * 是否合并
     *
     * @return 是否合并列
     */
    boolean isMerge() default false;

    /**
     * 要合并的列
     *
     * @return 合并列数组
     */
    int[] mergeColumns() default {};

    /**
     * 文件表头行数
     * 备注:
     * 1、合并时需计算,不指定默认-1;
     * 2、不指定时取ExcelProperty注解value的长度;
     */
    int headRowNumber() default -1;

}

监听抽象类

js
package com.xiaomayi.excel.listener;

import com.alibaba.excel.read.listener.ReadListener;

import java.util.List;

/**
 * <p>
 * 自定义读取监听抽象类
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2023-10-04
 */
public abstract class ListReadListener<T> implements ReadListener<T> {

    /**
     * 自定义抽象方法,获取数据列表
     *
     * @return 返回结果
     */
    public abstract List<T> getList();

}

文件监听器

js
package com.xiaomayi.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;

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

/**
 * <p>
 * 自定义文件处理监听器
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2023-10-04
 */
public class DefaultListReadListener extends ListReadListener<Object> {

    /**
     * 定义数据对象列表
     */
    private final List<Object> dataList = new ArrayList<>();

    /**
     * 获取读取的数据列表
     *
     * @return 返回结果
     */
    @Override
    public List<Object> getList() {
        return dataList;
    }

    /**
     * 文件头处理
     *
     * @param headMap 文件头Map
     * @param context 分析内容
     */
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        super.invokeHead(headMap, context);
    }

    /**
     * 数据源处理
     *
     * @param object          数据对象
     * @param analysisContext 分析内筒
     */
    @Override
    public void invoke(Object object, AnalysisContext analysisContext) {
        // 加入列表
        dataList.add(object);
    }

    /**
     * 异常处理
     *
     * @param exception 异常参数
     * @param context   分析内筒
     * @throws Exception 抛出异常
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        super.onException(exception, context);
    }

    /**
     * 数据处理完毕后调用
     *
     * @param analysisContext 分析内容
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

}

添加依赖

pom.xml 配置文件中引入以下依赖:

js
<!-- Excel依赖模块 -->
<dependency>
    <groupId>com.xiaomayi</groupId>
    <artifactId>xiaomayi-excel</artifactId>
</dependency>

注解使用

为了企业和开发者更好的了解和熟练运用注解的方式实现导入、导出功能,在用户管理模块专门编写了案例,在需要导入、导出的方法上添加对应的注解即可。

  1. RequestExcel 导入注解使用

在需要实现导入的方法上添加注解 @RequestExcel

js
R importExcel(@RequestExcel List<UserExcelVO> userExcelVOList);

使用案例:

js
package com.xiaomayi.admin.controller;

import cn.hutool.core.util.RandomUtil;
import com.itextpdf.text.DocumentException;
import com.xiaomayi.core.config.AppConfig;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.core.utils.StringUtils;
import com.xiaomayi.excel.annotation.RequestExcel;
import com.xiaomayi.excel.annotation.ResponseExcel;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import com.xiaomayi.security.utils.SecurityUtils;
import com.xiaomayi.system.dto.user.*;
import com.xiaomayi.system.service.UserService;
import com.xiaomayi.system.utils.ParamResolver;
import com.xiaomayi.system.vo.user.UserExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-03-23
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理")
@AllArgsConstructor
public class UserController {

    private final UserService userService;

    /**
     * 导入用户
     *
     * @param userExcelVOList 导入Excel
     * @return 返回结果
     */
    @Operation(summary = "导入用户", description = "导入用户")
    @RequestLog(title = "导入用户", type = RequestType.IMPORT)
    @PreAuthorize("@pms.hasAuthority('sys:user:import')")
    @PostMapping("/import")
    public R importExcel(@RequestExcel List<UserExcelVO> userExcelVOList) {
        return userService.importExcel(userExcelVOList);
    }

}
  1. ResponseExcel 注解使用
js
@ResponseExcel(name = "用户信息", sheetName = "用户信息")

使用案例:

js
package com.xiaomayi.admin.controller;

import cn.hutool.core.util.RandomUtil;
import com.itextpdf.text.DocumentException;
import com.xiaomayi.core.config.AppConfig;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.core.utils.StringUtils;
import com.xiaomayi.excel.annotation.RequestExcel;
import com.xiaomayi.excel.annotation.ResponseExcel;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import com.xiaomayi.security.utils.SecurityUtils;
import com.xiaomayi.system.dto.user.*;
import com.xiaomayi.system.service.UserService;
import com.xiaomayi.system.utils.ParamResolver;
import com.xiaomayi.system.vo.user.UserExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-03-23
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户管理")
@AllArgsConstructor
public class UserController {

    private final UserService userService;

    /**
     * 导出用户
     *
     * @return 返回结果
     */
    @Operation(summary = "导出用户", description = "导出用户")
    @RequestLog(title = "导出用户", type = RequestType.EXPORT)
    @PreAuthorize("@pms.hasAuthority('sys:user:export')")
    @ResponseExcel(name = "用户信息", sheetName = "用户信息")
    @GetMapping("/export")
    public List<UserExcelVO> exportExcel() {
        return userService.exportExcel();
    }

}

导入导出

进入用户管理模块,在导航操作栏上有导入、导出按钮,分别实现了 Excel 文件的导入和导出功能。

  1. 导入文件

可以从导入弹窗中点击 下载模板,然后在 Excel模板文件 中录入需要导入的用户数据,切记登录账号请保持系统中唯一性,否则会导入报错。

以下是下载后的模板文件:

  1. 导出文件

点击 导出 按钮实现用户数据的导出。

输出 Excel 格式文件:

小蚂蚁云团队 · 提供技术支持

小蚂蚁云 新品首发
新品首发,限时特惠,抢购从速! 全场95折
赋能开发者,助理企业发展,提供全方位数据中台解决方案。
获取官方授权