easyExcell

easyexcell准备工作

用到的实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private String name;
    private int age;
    private int weight;
    private String address;
}

导入相关依赖,此处只给easyexcell的依赖

 <!-- easyexcel依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
        </dependency>
导出测试
    @Test
    void test11() {
        Teacher t1 = new Teacher("1", 11, 22, "zz");
        Teacher t2 = new Teacher("2", 22, 33, "aa");
        Teacher t3 = new Teacher("3", 33, 25, "vv");
        Teacher t4 = new Teacher("4", 28, 11, "aa");
        Teacher t5 = new Teacher("1", 22, 11, "zz");
        Teacher t6 = new Teacher("1", 22, 11, "zz");
        //拿到的数据(真实情况是从db拿数据)
        ArrayList<Teacher> teachers = Lists.newArrayList(t1, t2, t3, t4, t5, t6);

        //1.xlsx为导出文件名字,应封装传参进行设置
        EasyExcel.write("D://1.xlsx")
                //excell表头,即实体类的属性名,在实体类注解定义的
                .head(Teacher.class)
                //导出格式,xlsx为07版excell文件后缀
                .excelType(ExcelTypeEnum.XLSX)
                //设置excell第一页sheet名称
                .sheet("老师信息")
        //设置标题,合并头行单元格,此处没用到
//              .registerWriteHandler(自定义处理器)
        //设置写信息从第几行开始
//              .relativeHeadRowIndex(2)
                //自定义表格策略
                .registerWriteHandler(createTableStyle())
                //设置列宽
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                //设置表头行高,内容行高
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short)20,(short)20))
                //导出数据源
                .doWrite(teachers);
    }


    /**
     * 自定义表格策略
     */
    public static WriteHandler createTableStyle() {
        // 头的策略*************************************
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 表头边框:底边框,右边框,左边框,顶边框
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);
        // 表头边框颜色:底边框颜色,右边框颜色,左边框颜色,顶边框颜色
        headWriteCellStyle.setBottomBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        headWriteCellStyle.setRightBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        headWriteCellStyle.setLeftBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        headWriteCellStyle.setTopBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        // 字体策略*************************************
        WriteFont headWriteFont = new WriteFont();
        // 表头字体大小
        headWriteFont.setFontHeightInPoints((short) 10);
        // 字体样式
        headWriteFont.setFontName("等线");
        // 默认关闭字体加粗 false
        headWriteFont.setBold(false);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景颜色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.index);
        // 内容策略*************************************
        WriteFont contentWriteFont = new WriteFont();
        // 内容 字体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        // 内容 字体样式
        contentWriteFont.setFontName("等线");
        // 内容 默认关闭字体加粗 false
        contentWriteFont.setBold(false);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 内容 水平对齐居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        // 内容 垂直对齐居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 边框样式*************************************
        // 底边框,右边框,左边框,顶边框
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        // 底边框颜色,右边框颜色,左边框颜色,顶边框颜色
        contentWriteCellStyle.setBottomBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        contentWriteCellStyle.setRightBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        contentWriteCellStyle.setLeftBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        contentWriteCellStyle.setTopBorderColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.index);
        // 自动换行 默认关闭 false
        contentWriteCellStyle.setWrapped(false);
        // 文本收缩至合适 默认关闭 false
        contentWriteCellStyle.setShrinkToFit(false);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        return horizontalCellStyleStrategy;
    }

在这里插入图片描述

导入测试

@Service
public class TeacherImport {

    public static void test() throws FileNotFoundException {
        //每一条数据的载体
        Teacher teacher = new Teacher();
        //拿到文件
        File file = new File("D://1.xlsx");
        //获取文件输入流
        FileInputStream fo = new FileInputStream(file);
        //读取文件
        ExcelReader build = EasyExcelFactory.read(fo)
                //按照实体类去读
                .head(Teacher.class)
                //导入需要自定义监听器
                .registerReadListener(new EasyExcelReadUtils.TeacherListener(teacher))
                .build();

        //读取第一个sheet
        ReadSheet readSheet = EasyExcelFactory.readSheet(0).build();
        build.read(readSheet);
    }

    public void insertMatnrGroup(List<Teacher> teacherList, Teacher teacher, Set<String> matnrSet, Map<String, String> errorFieldNameMap) {
        //业务处理,一般就是存到数据库,这里就直接打印了
        teacherList.stream().forEach(item->{
            System.out.println(item.toString());
        });
    }
}

其中用到的自定义监听器

package com.example.utils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.example.entity.Teacher;
import com.example.examples.TeacherImport;
import com.google.common.collect.Sets;

import javax.annotation.Resource;
import java.util.*;

public class EasyExcelReadUtils {

    /**
     * 组合零件维护监听器 matnrGroup
     */
    public static class TeacherListener implements ReadListener<Teacher> {

        @Resource
        private TeacherImport excelBll = SpringUtil.getBean(TeacherImport.class);

        /**
         * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
         */
        private static final int BATCH_COUNT = 100;
        /**
         * 缓存的数据
         */
        private List<Teacher> teacherList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        //全局set(业务需要,可不写)
        private Set<String> matnrSet = Sets.newHashSet();
        //存储异常信息(同上)
        Map<String, String> errorFieldNameMap = new HashMap<>(16);
        /**
         *
         */
        private Teacher teacher;

        /**
         * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
         *
         * @param
         */
        public TeacherListener(Teacher teacher) {
            this.teacher = teacher;
        }


        @Override
        public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
//            List<String> list=new ArrayList<>();
//            list.add(SysConstants.MATNR_FIELD);
//            templateValid(headMap,list);
        }

        /**
         * 这个每一条数据解析都会来调用
         *
         * @param teacher    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
         * @param context
         */
        @Override
        public void invoke(Teacher teacher, AnalysisContext context) {
            teacherList.add(teacher);

            // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
            if (teacherList.size() >= BATCH_COUNT) {
                saveData();
                // 存储完成清理 list
                teacherList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            }
        }

        /**
         * 所有数据解析完成了 都会来调用
         *
         * @param context
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            // 这里也要保存数据,确保最后遗留的数据也存储到数据库
            saveData();
        }

        /**
         * 加上存储数据库
         */
        private void saveData() {
            excelBll.insertMatnrGroup(teacherList,teacher,matnrSet,errorFieldNameMap);
        }
    }
}

监听器中用到的SpringUtil类

package com.example.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.applicationContext = applicationContext;
    }

    /**
     * 通过class获取Bean
     *
     * @param clazz class
     * @param <T>   泛型
     * @return bean
     */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
}

测试一下

 @Test
    void test13(){
        try {
            TeacherImport.test();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //打印结果
        //Teacher(name=1, age=11, weight=22, address=zz)
        //Teacher(name=2, age=22, weight=33, address=aa)
        //Teacher(name=3, age=33, weight=25, address=vv)
        //Teacher(name=4, age=28, weight=11, address=aa)
        //Teacher(name=1, age=22, weight=11, address=zz)
        //Teacher(name=1, age=22, weight=11, address=zz)
    }

其中要注意的是每次insert业务处理拿到的list不是全部数据,是定义的batch条数据,类似分页

多sheet导出

用到的实体类

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {

    //    @ExcelIgnore  此注释为导出时忽略本字段
//    @ColumnWidth(value = 40) 此注释可单独设置本字段单元格的宽度,高度也类似,自行百度
    @ExcelProperty(value = "姓名")
    private String name;

    @ExcelProperty(value = "年龄")
    private int age;

    @ExcelProperty(value = "体重")
    private int weight;

    @ExcelProperty(value = "地址")
    private String address;
}
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    @ExcelProperty(value = "姓名")
    private String name;

    @ExcelProperty(value = "年龄")
    private int age;

    @ExcelProperty(value = "成绩")
    private int score;

    @ExcelProperty(value = "班级")
    private String classNumber;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AllData {

    private List<Teacher> teacherList;

    private List<Student> studentsList;
}

导出测试(其中自定义策略在上面单sheet导出里)

@Test
    void test14(){
        //获得数据,真实环境应该从数据库读
        //创建一个AllData,其中两个属性分别是老师list和学生list
        AllData allData = new AllData();
        //捏造几条老师数据
        Teacher t1 = new Teacher("1", 11, 22, "zz");
        Teacher t2 = new Teacher("2", 22, 33, "aa");
        Teacher t3 = new Teacher("3", 33, 25, "vv");
        Teacher t4 = new Teacher("4", 28, 11, "aa");
        Teacher t5 = new Teacher("1", 22, 11, "zz");
        Teacher t6 = new Teacher("1", 22, 11, "zz");
        ArrayList<Teacher> teachers = Lists.newArrayList(t1, t2, t3, t4, t5, t6);
        //捏造几条学生数据
        Student s1 = new Student("11",11,342,"一班");
        Student s2 = new Student("22",22,314,"二班");
        Student s3 = new Student("33",33,421,"三班");
        Student s4 = new Student("44",44,521,"四班");
        Student s5 = new Student("55",55,123,"五班");
        Student s6 = new Student("66",66,234,"六班");
        ArrayList<Student> students = Lists.newArrayList(s1, s2, s3, s4, s5, s6);
        //放进alldata里面
        allData.setTeacherList(teachers);
        allData.setStudentsList(students);

        //1.xlsx为导出文件名字,应封装传参进行设置
        ExcelWriter excelWriter = EasyExcel.write("D://2.xlsx")
                //导出格式,xlsx为07版excell文件后缀
                .excelType(ExcelTypeEnum.XLSX)
                //设置写信息从第几行开始
                .relativeHeadRowIndex(1)
                //自定义表格策略
                .registerWriteHandler(createTableStyle())
                //设置列宽
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                //设置表头行高,内容行高
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
                .build();

        excelWriter.write(allData.getTeacherList(), EasyExcel.writerSheet(0,"老师信息").head(Teacher.class).build())
                .write(allData.getStudentsList(), EasyExcel.writerSheet(1,"学生信息").head(Student.class).build());
        excelWriter.finish();
    }

效果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值