EasyExcel 实现读写 Excel 超多案例

文档必读:https://www.yuque.com/easyexcel/doc/fillicon-default.png?t=N2N8https://www.yuque.com/easyexcel/doc/fill

1. pom.xml 依赖

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.9.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
</dependencies>

2. 实体类

@Data
@NoArgsConstructor
@HeadRowHeight(value= 20) //指定行高
//设置表头文本样式
@HeadFontStyle(fontName="黑体",color = 45,underline = Font.U_SINGLE)
//设置表头除了单元格文本外其他的样式
@HeadStyle(leftBorderColor = 10 ,borderLeft = BorderStyleEnum.THIN,
    rightBorderColor = 13 , borderRight = BorderStyleEnum.MEDIUM_DASH_DOT,
    //背景颜色 和填充方式
    fillForegroundColor =17 , fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND)
@AllArgsConstructor
public class Teacher {
    //value映射到excel中的表头名称   index:写入到excel中的索引从0开始
    @ExcelProperty(value = "编号",index = 3)
    private Integer id;
    @ExcelProperty(value = "姓名")
    private String name;
    @ExcelProperty(value = "年龄",index=10)
    private Integer age;
    @ExcelProperty(value = "月薪")
    //数值格式化
    @NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
    private Double salary;
    @ExcelProperty(value = "入职时间")
    //时间日期格式化
    @DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
    @ColumnWidth(value= 25) //指定当前列的宽度
//    @ContentStyle
    private Date joinDate;
    @ExcelProperty(value = "个人介绍")
    @ContentStyle(fillForegroundColor = 40 , fillPatternType =FillPatternTypeEnum.SOLID_FOREGROUND )
    @ContentFontStyle(fontName = "隶书", color = 51)
    private String link;//个人介绍网址
    @ExcelProperty(value = "个人注释")
    private String comment;//个人注释
}
@Data
@NoArgsConstructor
@HeadRowHeight(value= 20) //指定行高
//设置表头文本样式
@HeadFontStyle(fontName="黑体",color = 45,underline = Font.U_SINGLE)
//设置表头除了单元格文本外其他的样式
@HeadStyle(leftBorderColor = 10 ,borderLeft = BorderStyleEnum.THIN,
    rightBorderColor = 13 , borderRight = BorderStyleEnum.MEDIUM_DASH_DOT,
    //背景颜色 和填充方式
    fillForegroundColor =17 , fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND)
@AllArgsConstructor
public class Teacher2 {
    //value映射到excel中的表头名称   index:写入到excel中的索引从0开始
    @ExcelProperty(value = "编号",index = 3)
    private Integer id;
    @ExcelProperty(value = "姓名")
    private String name;
    @ExcelProperty(value = "年龄",index=10)
    private Integer age;
    @ExcelProperty(value = "月薪")
    //数值格式化
    @NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
    private Double salary;
    @ExcelProperty(value = "入职时间")
    //时间日期格式化
    @DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
    @ColumnWidth(value= 25) //指定当前列的宽度
//    @ContentStyle
    private Date joinDate;
    @ExcelProperty(value = "个人介绍")
    //背景颜色+全部填充
    //配置复杂的内容:链接、注释、样式
    private WriteCellData<String> link;//个人介绍网址
//    @ContentStyle(fillForegroundColor = 40 , fillPatternType =FillPatternTypeEnum.SOLID_FOREGROUND )
    @ContentFontStyle(fontName = "隶书", color = 60)
    @ExcelProperty(value = "个人注释")
    private WriteCellData<String> comment;//个人注释
}

3. 监听

//监听器:泛型 AnalysisEventListener读取一行数据后会自动转为该类型的对象
public class TeacherVoReadListener extends AnalysisEventListener<TeacherVo> {
    private List<TeacherVo> list = new ArrayList<>();
    private int limit = 100;
    //每读取一行数据回调一次
    @Override
    public void invoke(TeacherVo data, AnalysisContext context) {
        //处理读取到数据的业务代码
//        System.out.println(data);
        //保存数据到数据库: 单个保存性能较差,可以使用批量保存
        //为了节省内存占用,批量保存的数据行数需要设置阈值

        //1、保存数据到集合中
        list.add(data);
        //2、判断集合数据条数到达阈值批量保存
        if(list.size()==limit){
            System.out.println("批量保存。。。。。。。");
            //3、清空保存过的集合数据
            list.clear();
        }
    }
    //整个文档解析完毕后回调
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //如果集合中仍有数据 保存到数据库
        if(list.size()>0){
            System.out.println("文档解析完成:保存数据到数据库,"+list);
            list.clear();
        }
    }
}

4. vo类

@Data
public class TeacherVo {
    //value映射到excel中的表头名称   index:写入到excel中的索引从0开始
    @ExcelProperty(value = "编号",index = 3)
    private Integer id;
    @ExcelProperty(value = "姓名")
    private String name;
    @ExcelProperty(value = "年龄",index=10)
    private Integer age;
    @ExcelProperty(value = "月薪")
    //数值格式化
    @NumberFormat(value = "#.##")//小数点后的#个数表示精确到小数点后的位数
    private Double salary;
    @ExcelProperty(value = "入职时间")
    //时间日期格式化
    @DateTimeFormat(value = "yyyy年MM月dd日 HH:mm:ss")
    @ColumnWidth(value= 25) //指定当前列的宽度
//    @ContentStyle
    private Date joinDate;
    @ExcelProperty(value = "个人介绍")
    private String link;//个人介绍网址
    @ExcelProperty(value = "个人注释")
    private String comment;//个人注释
}

5. 测试写

public class TestWrite {
    //测试创建新的工作簿
    @Test
    void test4(){
        //设置样式:
        //字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
        List<Teacher2> data = new ArrayList<>();
        Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
                RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
                new Date(), null, null );
        //需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
        WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
        //设置链接内容:
        HyperlinkData hyperLinkData = new HyperlinkData();
        hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
        hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
        link.setHyperlinkData(hyperLinkData);
        //设置单元格样式
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
        writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //link.setRichTextStringDataValue();  设置渐变色
        link.setWriteCellStyle(writeCellStyle);
        teacher.setLink(link);
        //需求:给文本添加备注信息
        WriteCellData<String> comment = new WriteCellData<>("评价");
        //批注内容:
        CommentData commentData = new CommentData();
        commentData.setAuthor("庞局");
        commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
        comment.setCommentData(commentData);
        teacher.setComment(comment);
        data.add(teacher);

        //需求:追加写入
        //1、判断如果要写入数据的文件不存在,直接写入
        //覆盖写入
        String path = "F:/excel/teacher1" + ExcelTypeEnum.XLSX.getValue();//目标写入的文件
        String tmpPath = "F:/excel/tmp_"+System.currentTimeMillis()+ ExcelTypeEnum.XLSX.getValue();//临时文件
        File file = new File(path);
        File tmpFile = new File(tmpPath);
        if(!file.exists()){
            EasyExcel.write(file)
                    .head(Teacher2.class)
                    .sheet("1")
                    .doWrite(data);
        }else{
            //2、如果写入数据的文件已存在,使用已存在的文件当做模板和本次要写入的数据 一起写入到一个临时文件中
            EasyExcel.write(tmpFile) //需要指定写入到临时文件中
                    .withTemplate(file) //使用原来的文件当做模板复制过来继续写
                    .file(tmpFile)  //最终写入到的文件
                    .inMemory(true) //在内存中操作
                    .sheet("2") //如果和源文件的工作簿不一样 就会新创建工作簿,一样则合并
                    .needHead(true) //不需要再生成表头
                    .head(Teacher2.class)
                    .doWrite(data);
        }
        //3、删除原来的数据文件,修改临时文件名为原来文件的名称
        //如何判断是第一次创建原来文件 还是 第N次创建临时文件
        if(tmpFile.exists()){
            //删除原来的文件
            file.delete();
            //重命名临时文件
            tmpFile.renameTo(file);
        }
    }

    //测试追加写入
    @Test
    void test3(){
        //设置样式:
        //字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
        List<Teacher2> data = new ArrayList<>();
        Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
                RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
                new Date(), null, null );
        //需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
        WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
        //设置链接内容:
        HyperlinkData hyperLinkData = new HyperlinkData();
        hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
        hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
        link.setHyperlinkData(hyperLinkData);
        //设置单元格样式
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
        writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //link.setRichTextStringDataValue();  设置渐变色
        link.setWriteCellStyle(writeCellStyle);
        teacher.setLink(link);
        //需求:给文本添加备注信息
        WriteCellData<String> comment = new WriteCellData<>("评价");
        //批注内容:
        CommentData commentData = new CommentData();
        commentData.setAuthor("庞局");
        commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
        comment.setCommentData(commentData);
        teacher.setComment(comment);
        data.add(teacher);

        //需求:追加写入
        //1、判断如果要写入数据的文件不存在,直接写入
        //覆盖写入
        String path = "F:/excel/teacher1" + ExcelTypeEnum.XLSX.getValue();//目标写入的文件
        String tmpPath = "F:/excel/tmp_"+System.currentTimeMillis()+ ExcelTypeEnum.XLSX.getValue();//临时文件
        File file = new File(path);
        File tmpFile = new File(tmpPath);
        if(!file.exists()){
            EasyExcel.write(file)
                    .head(Teacher2.class)
                    .sheet("1")
                    .doWrite(data);
        }else{
            //2、如果写入数据的文件已存在,使用已存在的文件当做模板和本次要写入的数据 一起写入到一个临时文件中
            EasyExcel.write(tmpFile) //需要指定写入到临时文件中
                    .withTemplate(file) //使用原来的文件当做模板复制过来继续写
                    .file(tmpFile)  //最终写入到的文件
                    .inMemory(true) //在内存中操作
                    .sheet("1") //需要和原来文件的sheet一样
                    .needHead(false) //不需要再生成表头
                    .doWrite(data);
        }
        //3、删除原来的数据文件,修改临时文件名为原来文件的名称
        //如何判断是第一次创建原来文件 还是 第N次创建临时文件
        if(tmpFile.exists()){
            //删除原来的文件
            file.delete();
            //重命名临时文件
            tmpFile.renameTo(file);
        }
    }
    
    //测试写数据到excel文件中:
    @Test
    void test2(){
        //设置样式:
        //字体颜色、背景颜色、字体、边框颜色、文本添加链接地址、文本添加注释
        List<Teacher2> data = new ArrayList<>();
        Teacher2 teacher = new Teacher2(100000 , "桃桃2" ,
                RandomUtils.nextInt(45, 60), RandomUtils.nextDouble(30000D, 60000D),
                new Date(), null, null );
        //需求:给一个文本设置一个超链接,点击excel中的文本时可以跳转到链接地址
        WriteCellData<String> link = new WriteCellData<>("个人首页地址");//文本内容
        //设置链接内容:
        HyperlinkData hyperLinkData = new HyperlinkData();
        hyperLinkData.setAddress("http://www.atguigu.com/teacher/new/zhangyitao.jpg");//链接地址
        hyperLinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);//链接类型
        link.setHyperlinkData(hyperLinkData);
        //设置单元格样式
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        writeCellStyle.setFillForegroundColor(IndexedColors.DARK_YELLOW.getIndex());
        writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //link.setRichTextStringDataValue();  设置渐变色
        link.setWriteCellStyle(writeCellStyle);
        teacher.setLink(link);
        //需求:给文本添加备注信息
        WriteCellData<String> comment = new WriteCellData<>("评价");
        //批注内容:
        CommentData commentData = new CommentData();
        commentData.setAuthor("庞局");
        commentData.setRichTextStringData(new RichTextStringData("张老师是个男老师...今年50了."));
        comment.setCommentData(commentData);
        teacher.setComment(comment);
        data.add(teacher);
        //需求:追加写入
        //覆盖写入
        EasyExcel.write("F:/excel/teacher1"+ExcelTypeEnum.XLSX.getValue())
                    .head(Teacher2.class)
                    .sheet("1")
                    .doWrite(data);
    }

    @Test
    void test1(){
        //xls: 老版本的excel文件一次性最多可以写入65535行数据
        //xlsx: 新版本的excel文件 写入数据一般没有限制  去掉了默认的样式 文件比老版本小
        EasyExcel.write("F:/excel/t7"+ ExcelTypeEnum.XLSX.getValue()) //目标文件
                .head(Teacher.class) // excel中的头:以后通过excel映射的bean的属性名解析
                .sheet("teachers") // excel中的一个工作簿
                .doWrite(data()); //写入到excel中的数据集合
    }

    private List<Teacher> data(){
        List<Teacher> data = new ArrayList<>();
        for (int i = 0; i <= 165535; i++) {
            Teacher teacher = new Teacher(100000 + i, "pangju" + i,
                    RandomUtils.nextInt(35, 50), RandomUtils.nextDouble(20000D, 50000D),
                    new Date(), "http://asdasdasd/pangju.html", "hehe" + i);
            data.add(teacher);
        }
        return data;
    }
}

6. 测试读

public class TestRead {
    @Test
    void test1(){

        EasyExcel.read("F:/excel/teacher1.xlsx")
                .sheet("2")
                .head(TeacherVo.class)
                //需要配置监听器:接收easyexcel读取的每行数据
                //  easyexcel基于回调的方式每读取一行数据调用一次 监听器的回调方法传入
                .registerReadListener(new TeacherVoReadListener())
                .doRead();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45037155/article/details/129804039
今日推荐