基于注解结合Easyexcel和文件服务完成文件的导出

前言

前面简单的整合了EasyExcel和Minio,业务的需求是希望报表导出的时候可以在文件服务器上保留备份,并将文件路径存入mysql中。这个业务,我的思路是这样的,导出的时候直接调用文件的上传方法,然后接口返回路径,前端直接调用下载接口完成文件的下载。对于简单的数据导出我想着简便点,想用注解的方式来完成。废话不多说,直接上代码

注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExportExl {

	String fileName() default "";

	ExcelTypeEnum excelType() default ExcelTypeEnum.XLSX;

	Class<?> classType();
}

切面:

@Aspect
@Component
public class ExportExlAspect {

    @Autowired
    private MinioUtils minioUtils;

    @Pointcut("@annotation(com.nnm.scaffold.common.annotation.ExportExl)")
    public void export() {
    }

    @Around("export() && @annotation(exportExl)")
    public Object handle(ProceedingJoinPoint point, ExportExl exportExl) {
        //获取文件名
        String fileName = exportExl.fileName();
        if (StringUtils.isBlank(fileName)) {
            fileName = IdUtil.randomUUID();
        }
        ExcelTypeEnum excelTypeEnum = exportExl.excelType();
        if (excelTypeEnum == null) {
            excelTypeEnum = ExcelTypeEnum.XLSX;
        }
        //获取导出类型
        Object result = null;
        try {
            result = point.proceed();
        } catch (Throwable e) {
            throw new BusinessException("查询数据异常!");
        }
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        try {
            this.setExcelRespProp(response, fileName, excelTypeEnum);
        } catch (UnsupportedEncodingException e) {
            throw new BusinessException("导出数据编码异常!");
        }
        try {
            // 创建临时文件
            String uuid = IdUtil.randomUUID();
            File temp = File.createTempFile(uuid, excelTypeEnum.getValue());
            EasyExcel.write(temp)
                    .head(exportExl.classType())
                    .excelType(excelTypeEnum)
                    .sheet(fileName)
                    .doWrite((Collection<?>) result);
            FileInputStream inputStream = new FileInputStream(temp);
            fileName = FileUtils.datePath() + "/" + fileName + System.currentTimeMillis() + excelTypeEnum.getValue();
            minioUtils.uploadFile("scaffold", fileName, inputStream);
            //立即删除文件
            inputStream.close();
            temp.delete();
            result = fileName;
        } catch (IOException e) {
            throw new BusinessException("导出数据异常!");
        } catch (Exception e) {
	        throw new BusinessException("导出数据异常");
        }
	    return result;
    }

    /**
     * 设置excel下载响应头属性
     */
    private void setExcelRespProp(HttpServletResponse response, String rawFileName, ExcelTypeEnum excelTypeEnum) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + excelTypeEnum.getValue());
    }
}

FileUtils

public class FileUtils {

    /**
     * 编码文件名
     * 日期路径 + UUID
     */
    public static final String extractUploadFilename(MultipartFile file)
    {
        String fileName = file.getOriginalFilename();
        String extension = FilenameUtils.getExtension(fileName);
        fileName = datePath() + "/" + UUIDUtils.fastUUID().toString(true) + "." + extension;
        return fileName;
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }
}

excel导出接口:

@GetMapping("/downloadexcel.do")
@ApiOperation(value = "excel下载接口")
@ExportExl(fileName = "汇总表", classType = Student.class)
public Object getExcel() {
    List<Student> list = data();
    return list;
}

ExportExl有两个属性,fileName 表的名字,classType 实体类。

结果:
在这里插入图片描述
成功上传到minio文件服务器
成功下载
之所以想用注解,实现让简单的文件导出可以变得简单,更加关注在业务上,当然复杂的业务场景不一定都可以使用注解,还是要根据实际情况来。目前的工作有挺多报表的导出功能,如若有碰到好玩的东西,后面还是会记录的。

EasyExcel 是一个基于注解的 Java Excel 操作库,可以方便地读写 Excel 文件。如果你想使用 EasyExcel 导出 CSV 文件,需要注意以下几点: 1. 需要使用 `@ExcelProperty` 注解来标记实体类中各个属性对应的列。例如: ```java public class User { @ExcelProperty("用户名") private String username; @ExcelProperty("年龄") private int age; @ExcelProperty("城市") private String city; // 省略 getter 和 setter 方法 } ``` 2. 需要使用 `@ExcelIgnore` 注解来忽略实体类中不需要导出的属性。例如: ```java public class User { @ExcelProperty("用户名") private String username; @ExcelProperty("年龄") private int age; @ExcelProperty("城市") private String city; @ExcelIgnore private String password; // 省略 getter 和 setter 方法 } ``` 3. 导出 CSV 文件时,需要使用 `ExcelWriterBuilder` 构建一个 `ExcelWriter` 对象,并调用 `write()` 方法写入数据。例如: ```java public class Main { public static void main(String[] args) { try (ExcelWriter writer = EasyExcel.write("output.csv").build()) { List<User> userList = new ArrayList<>(); // 添加数据到 userList Sheet sheet = new Sheet(1, 0, User.class); sheet.setSheetName("用户信息"); writer.write(userList, sheet); } } } ``` 注意,这里的 `User.class` 参数表示将 `User` 类作为 Excel 的一张表。如果你有多个表需要导出,可以创建多个 `Sheet` 对象并分别写入数据。 如果你遇到导出 CSV 文件注解失效的问题,可以检查以下几点: 1. 实体类中的属性是否正确标记了 `@ExcelProperty` 注解。 2. 实体类中的属性是否定义为了基本类型(如 `int`、`double` 等),而不是包装类型(如 `Integer`、`Double` 等)。由于基本类型无法为 null,导出时会忽略包含 null 值的行。 3. 是否正确使用了 `@ExcelIgnore` 注解忽略不需要导出的属性。 4. 是否正确使用 `ExcelWriterBuilder` 构建了 `ExcelWriter` 对象,并调用 `write()` 方法写入数据。 希望以上信息能够帮助到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值