SpringBoot中使用Easyexcel实现Excel导入导出功能(三)

导出的数据包含有图片

        导出excel表格的数据包含有图片,这种场景比较少。通Easyexcel实现这样的需求,我认为最简便的方法就是使用前面提到的自定义转换器(com.alibaba.excel.converters.Converter);假如有这样一个场景,导出员工的信息,还要包括员工的一寸照。通常情况下,数据库并不会真的存一张图片,而是图片存储位置的相对路径。

1、新建一个类EmpHeadPhotoConverter,实现com.alibaba.excel.converters.Converter接口,并重写convertToExcelData()方法;

2、在重写convertToExcelData()方法中,根据图片的相同路径或网络地址读取出图片的字节流作为构建WriteCellData对象的参数然后返回;

3、在员工信息的实体类Employee的照片列引入自定义的类型转换器(EmpHeadPhotoConverter)

4、使用EasyExcel的工厂方法把数据写出到excel表格中;

注:这里是使用默认的样式,所以看起来可能点丑;@ContentRowHeight()用于调节数据行的高度;@ColumnWidth用于调节数据列的宽度;

public class EmpHeadPhotoConverter implements Converter<String> {
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        //根据图片的相对路径或网络地址读取图片到byte输出流(ByteArrayOutputStream)
        ByteArrayOutputStream byteArrayOutputStream = null;
        InputStream inputStream=null;
        try {
             inputStream = ClassLoader.getSystemResourceAsStream(value);
            byteArrayOutputStream = new ByteArrayOutputStream();
            int len=-1;
            byte[] bytes = new byte[1024];
            while ((len=inputStream.read(bytes))!=-1){
                byteArrayOutputStream.write(bytes);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        //把输出流中的图片字节数组作为参数构建writeCellData对象并返回
        //WriteCellData是EasyExcel对单元格数据的封装
        return  new WriteCellData<>(byteArrayOutputStream.toByteArray());
    }
}
@Data
@ContentRowHeight(50)//数据行的高度
public class Employee implements Serializable {
    @ExcelProperty("姓名")
    private String realName;
    @ExcelProperty("员工编号")
    private String empNo;
    @ExcelProperty("性别")
    private String sex;
    @ExcelProperty("家庭地址")
    private String address;
    @ExcelProperty("联系电话")
    private String phone;
    @ExcelProperty("电子邮箱")
    private String email;
    @ExcelProperty(value = "照片",converter = EmpHeadPhotoConverter.class)
    @ColumnWidth(10)//列宽
    private String headPhoto;
}
@Test
public void writeImage(){
    String exportPath=this.getExportPath();
    String exportFile=exportPath+File.separator+"员工基本信息(包含照片).xlsx";
    List<Employee> list = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        Employee employee = new Employee();
        employee.setRealName("张三"+i);
        employee.setEmpNo("CH"+(i+1));
        employee.setAddress("北京");
        employee.setEmpNo("zhangsan@163.com");
        employee.setSex("女");
        employee.setPhone("17777xxxxxx");
        //这里是示例,因为我把示例图片放在了classpath下,后面可以根据图片名字在classpath下找到
        //在实际的业务开发过程中,这里应该是图片的相对路径或网络地址
        employee.setHeadPhoto("zhangsan.jpeg");
        list.add(employee);
    }
    EasyExcel.write(exportFile,Employee.class).sheet().doWrite(list);
}

导出表格自定义样式

        我比较喜欢使用easyexcel的一个很重要的原因就是,easyexcel在poi的基础上,封装的比较友好。就比如,在导出的时候,很多情况下需要自定义表格的样式,easyexcel就提供了多种的实现方式。主要有三种:1、通过注解;2、编程式;3、自定义类型转换器。不同的方式,侧重的场景也有所不同,下面通过示例梳理一下使用方法:

编程式自定义样式

        通过编程式来自定义导出表格的样式中,有一个非常关键类HorizontalCellStyleStrategy。

1、通过HorizontalCellStyleStrategy可以配置好表头的样式和数据行的样式;

2、使用Easyexcel的工厂方法写出数据前,把通过HorizontalCellStyleStrategy构建好的样式策略注册到表格写出构建器里;

3、使用使用Easyexcel的工厂方法写出数据;

总结:这种方法的优点就是比较简单,且容易理解构建样式的过程;缺点就是不太灵活;比较适合那些导出表格前可以明确知道导出的表格的样式特点;

@Test
    public void writeWithStyle2() {
        String exportPath = this.getExportPath();
        String exportFile = exportPath + File.separator + "员工基本信息v2.xlsx";
        List<Employee> list = new ArrayList<>();
        Employee employee = new Employee();
        employee.setRealName("张三");
        employee.setEmpNo("CH001");
        employee.setSex("女");
        Employee employee2 = new Employee();
        employee2.setRealName("李四");
        employee2.setEmpNo("CH002");
        employee2.setSex("男");
        list.add(employee);
        list.add(employee2);
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)20);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)20);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        EasyExcel.write(exportFile, Employee.class)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .sheet()
                .doWrite(list);
    }

注解形式自定义样式

        通过注解的形式来自定义导出表格的样式,和编程式的比较类似,明显的区别是一个需要通过在编写代码来定义样式并应用这个样式;另一个是需要 使用注解定义好表格样式,应用样式的过程easyexcel内部已经实现了,不用自己编写代码来实现。总体上特点是一样的:使用简单,且比较好理解,缺点就是不灵活,不能动态的设置导出表格内单元格的样式。比较常用的注解有以下(有的是作用在类上,有的是作用在属性上,注解需要设置哪些属性可以点以注解的源里一看就很清楚):

作用在类上:

@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)

// 头字体设置成20

@HeadFontStyle(fontHeightInPoints = 20)

// 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()

@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17)

// 内容字体设置成20

@ContentFontStyle(fontHeightInPoints = 20)

作用在属性上

// 字符串的头背景设置成粉红 IndexedColors.PINK.getIndex()

@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)

// 字符串的头字体设置成20

@HeadFontStyle(fontHeightInPoints = 30)

// 字符串的内容的背景设置成天蓝 IndexedColors.SKY_BLUE.getIndex()

@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)

// 字符串的内容字体设置成20

@ContentFontStyle(fontHeightInPoints = 30)

自定义类型转换器形式定义样式

        前两种的样式定义方法,都比较固定,不能根据导出数据的规则来动态设置表格内单元格的样式,如导出员工信息表格里如果性别是女的员工数据行,则使用红色字体,如果是男性,则是使用蓝色;因为导出数据通常是从数据源里动态取出的,在导出前没办法确定哪些行是男性,哪些员工是女性,所以需要动态的设置导出表格的样式,自定义类型转换器就可以很好的解决这个问题。

        1、新建一个类SexColourConverter,实现com.alibaba.excel.converters.Converter接口,并重写convertToExcelData()方法;

        2、重写convertToExcelData()方法中,根据单元格的内容设置不同的样式,示例中:如果性别是男,则字体为蓝色;如果性别是女,则字体颜色是红色;

        3、在员工信息的实体类Employee的性别(sex)属性上,通过@ExcelProperty()引入自定义的类型转换器SexColourConverter;

        4、使用Easyexcel的工厂方法实现表格数据的写出;

        总结:这种方法很灵活,非常适合一些报表中,要求导出表格中数据达到在不同规则就要求有不同的样式的场景。在我做过的项目里,有不少导出都有类似的规则:某个属性达到预警阈值时,要导出数据的单元格格式标成红色。

public class SexColourConverter implements Converter<String> {
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        WriteFont writeFont = new WriteFont();
        if ("男".equals(value)) {
            writeFont.setColor((short) 12);
        }
        if ("女".equals(value)) {
            writeFont.setColor((short) 10);
        }
        writeCellStyle.setWriteFont(writeFont);
        WriteCellData<Object> cellData = new WriteCellData<>();
        cellData.setWriteCellStyle(writeCellStyle);
        cellData.setType(CellDataTypeEnum.STRING);
        cellData.setStringValue(value);
        return cellData;
    }
}
@Data
public class Employee implements Serializable {
    @ExcelProperty("姓名")
    private String realName;
    @ExcelProperty("员工编号")
    private String empNo;
    @ExcelProperty(value = "性别",converter = SexColourConverter.class)
    private String sex;
}
@Test
public void writeWithStyle() {
    String exportPath = this.getExportPath();
    String exportFile = exportPath + File.separator + "员工基本信息v2.xlsx";
    List<Employee> list = new ArrayList<>();
    Employee employee = new Employee();
    employee.setRealName("张三");
    employee.setEmpNo("CH001");
    employee.setSex("女");
    Employee employee2 = new Employee();
    employee2.setRealName("李四");
    employee2.setEmpNo("CH002");
    employee2.setSex("男");
    list.add(employee);
    list.add(employee2);
    EasyExcel.write(exportFile, Employee.class).sheet().doWrite(list);
}

在设置单元格背景或字体的颜色的时候,颜色会对应一个short类型的数据,下面就具体对应关系:

SpringBoot中使用Easyexcel实现Excel导入导出功能(一)_凡夫贩夫的博客-CSDN博客excel表格的导入与导出,可以说是业务系统里比较常见的功能了,早些时候相信很多人都是使用POI实现excel的导入与导出功能,后来出现了easyexcel,从我自己的使用感受来说,我更喜欢使用easyexcel,除了封装的比较好外,最重要的是对超级大excel导入有了更好的方案,与POI相比,速度更快,占用内存更少。https://blog.csdn.net/fox9916/article/details/128242237?spm=1001.2014.3001.5502SpringBoot中使用Easyexcel实现Excel导入导出功能(二)_凡夫贩夫的博客-CSDN博客自定义格式转换的后导出可以参考上一篇《Springboot+Easyexcel:导入excl》中的日期、数字及其他自定义格式的转换部分,SalaryDateConverter#convertToExcelData(),导出时候的数据格式转换逻辑可以写在这里面;SalaryDateConverter#convertToJavaData()导入时候的数据格式转换的实现逻辑可以写在这里;SalaryDateConverter实现了com.alibaba.excel.converters.Converter接口;https://blog.csdn.net/fox9916/article/details/128258929?spm=1001.2014.3001.5502SpringBoot中使用Easyexcel实现Excel导入导出功能(三)_凡夫贩夫的博客-CSDN博客我比较喜欢使用easyexcel的一个很重要的原因就是,easyexcel在poi的基础上,封装的比较友好。就比如,在导出的时候,很多情况下需要自定义表格的样式,easyexcel就提供了多种的实现方式。主要有三种:1、通过注解;2、编程式;3、自定义类型转换器。通过编程式来自定义导出表格的样式中,有一个非常关键类HorizontalCellStyleStrategy。1、通过HorizontalCellStyleStrategy可以配置好表头的样式和数据行的样式;https://blog.csdn.net/fox9916/article/details/128270689?spm=1001.2014.3001.5502

Springboot扩展点系列实现方式、工作原理集合:

Springboot扩展点之ApplicationContextInitializer

Springboot扩展点之BeanDefinitionRegistryPostProcessor

Springboot扩展点之BeanFactoryPostProcessor

Springboot扩展点之BeanPostProcessor

Springboot扩展点之InstantiationAwareBeanPostProcessor

Springboot扩展点之SmartInstantiationAwareBeanPostProcessor

Springboot扩展点之ApplicationContextAwareProcessor

Springboot扩展点之@PostConstruct

Springboot扩展点之InitializingBean

Springboot扩展点之DisposableBean

Springboot扩展点之SmartInitializingSingleton

Springboot核心功能工作原理:

Springboot实现调度任务的工作原理

Springboot事件监听机制的工作原理

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
你好!对于使用Spring Boot和EasyExcel实现Excel导入导出,你可以按照以下步骤进行操作: 1. 添加依赖:在你的Spring Boot项目的pom.xml文件添加EasyExcel的依赖。 ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.11</version> </dependency> ``` 2. 创建实体类:创建一个实体类,用于映射Excel的数据。 ```java public class User { private String name; private Integer age; // 省略 getter 和 setter 方法 } ``` 3. 导出Excel使用EasyExcel提供的工具类进行导出操作。 ```java public void exportExcel(List<User> userList, HttpServletResponse response) throws IOException { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); String fileName = URLEncoder.encode("用户列表", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); EasyExcel.write(response.getOutputStream(), User.class).sheet("用户列表").doWrite(userList); } ``` 4. 导入Excel使用EasyExcel提供的监听器类进行导入操作。 ```java public void importExcel(MultipartFile file) throws IOException { EasyExcel.read(file.getInputStream(), User.class, new AnalysisEventListener<User>() { @Override public void invoke(User user, AnalysisContext context) { // 处理每一行数据 } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 所有数据处理完成后的操作 } }).sheet().doRead(); } ``` 以上就是使用Spring Boot和EasyExcel实现Excel导入导出的基本步骤。你可以根据自己的需求对代码进行适当的调整和扩展。希望对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凡夫贩夫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值