EasyExcel读模板生成excel文件&注解Bean生成文件

这篇具有很好参考价值的文章主要介绍了EasyExcel读模板生成excel文件&注解Bean生成文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、EasyExce依赖准备

  1. EasyExcel依赖
    <!-- easyexcel: excel快速导出-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>3.1.0</version>
    </dependency>
  1. apache poi依赖

        EasyExcel同时依赖Apache POI库,同时还需要注意下两个库的版本对应关系。EasyExcel可能升级对poi的依赖,导致功能不兼容。

    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>5.2.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>5.2.2</version>
    </dependency>

2、通过注解Bean的方式生成Excel

2.1、注解Bean准备

EasyExcel注解部分参考:EasyExcel注解大全_起一个让人印象深刻的名字的博客-CSDN博客

package com.dongzi.utils.excel.bean;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.*;
import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.alibaba.excel.enums.poi.VerticalAlignmentEnum;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.Date;

@Data // lombok提供getter\setter等
@Accessors(chain = true) // lombok提供链式操作
@ContentRowHeight(25) // 行高
public class FillData {

    @HeadStyle(fillBackgroundColor = 4) // 表头样式设置,背景颜色填充,颜色类型4
    @HeadFontStyle(fontName = "宋体", fontHeightInPoints = 25, color = 3) // 表头字体设置,宋体,颜色3
    @ExcelProperty(value = "姓名") // 列名
    @ColumnWidth(20) // 列宽
    @ContentFontStyle(fontName = "宋体", color = 4, bold = BooleanEnum.TRUE) // 数据部分单元格字体样式
    @ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
    // 数据部分单元格样式
    private String name; // 字段

    @HeadStyle(fillBackgroundColor = 4)
    @HeadFontStyle(fontName = "楷体", fontHeightInPoints = 25, color = 3)
    @ExcelProperty(value = "地址")
    @ColumnWidth(20)
    @ContentFontStyle(fontName = "楷体")
    @ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
    private String address;

    @HeadStyle(fillBackgroundColor = 4)
    @HeadFontStyle(fontName = "微软雅黑", fontHeightInPoints = 25, color = 3)
    @ExcelProperty(value = "时间")
    @ColumnWidth(50)
    @ContentFontStyle(fontName = "微软雅黑")
    @ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
    @DateTimeFormat(value = "yyyy-MM-dd") // 时间格式化
    private Date date;

    // 忽略生成的字段
    @ExcelIgnore
    private String welcome;

}

2.2、封装数据,生成Excel(只需要几行代码)

package com.dongzi.utils.excel;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.dongzi.utils.excel.bean.FillData;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class ReadeExcelTemplate {

    public static void main(String[] args) throws IOException {

        exportDataByAnnotation();
    }

    // 基于注解导出数据
    public static void exportDataByAnnotation() {
        // 文件输出位置
        File outPutFile = new File("D:/temp/Excel-基于注解导出数据.xlsx");
    	// 指定使用哪个注解Bean来生成Excel?
        ExcelWriter excelWriter = EasyExcel.write(outPutFile, FillData.class).excelType(ExcelTypeEnum.XLSX).build();
    	// 生成数据
        excelWriter.write(fillData(5), EasyExcelFactory.writerSheet(0).build());
        // 完成,写数据到本地
        excelWriter.finish();
    }

    public static List<FillData> fillData(int num) {
        List<FillData> mapList = new ArrayList<>();

        for (int i = 0; i < num; i++) {
            FillData fillData = new FillData();
            fillData.setName("姓名" + i)
                    .setAddress("住址" + i)
                    .setWelcome("你好" + i)
                    .setDate(new Date());
            mapList.add(fillData);
        }
        return mapList;
    }
}

2.3、生成结果展示

EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel

3、通过Excel模板生成数据

3.1、准备编写Excel模板

注意!

  1. 占位符的书写格式为{.字段名}(为什么占位符是这样的,详见附录)
  2. 一个单元格个可以写多个占位符
  3. 模板需要按照预定的格式/样式调整好,之后会按照相同格式输出单元格
  4. 数据输出视占位符所在位置依次向下输出

如图:Sheet1模板
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel
如图:Sheet2模板
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel
如图:Sheet3模板
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel

3.2、封装数据,生成excel

package com.dongzi.utils.excel;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.dongzi.utils.excel.bean.FillData;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class ReadeExcelTemplate {

    public static void main(String[] args) throws IOException {

       exportDataByTemplate();

    }

    // 基于excel模板导出数据
    public static void exportDataByTemplate() throws IOException {
        File outPutFile = new File("D:/temp/Excel-基于模板导出数据.xlsx");
        ClassPathResource pathResource = new ClassPathResource("template/info.xlsx");

        // 基于excel模板导出数据
        ExcelWriter excelWriter = EasyExcel.write(outPutFile).withTemplate(pathResource.getInputStream())
                .excelType(ExcelTypeEnum.XLSX).build();

//        excelWriter.write(fillData(5), EasyExcel.writerSheet(0).build());
//        excelWriter.write(fillData(10), EasyExcel.writerSheet(1).build());
//        excelWriter.write(fillData(15), EasyExcel.writerSheet(2).build());

        // {.name}-{.welcome}, {.address}, {.date} 占位符位置数据补充,一个单元格可以写多个{.字段名}
        // 数据的位置从当前sheet页的的占位符位置开始,无论title在什么位置
        // 注意这里必须使用excelWriter.fill()进行数据填充
        excelWriter.fill(fillData(5), EasyExcel.writerSheet(0).build());
        excelWriter.fill(fillData(10), EasyExcel.writerSheet(1).build());
        excelWriter.fill(fillData(15), EasyExcelFactory.writerSheet(2).build());

        // {.name}, {.address}, {.date} 占位符位置数据补充
//        excelWriter.fill(fillData2(5), EasyExcel.writerSheet(0).build());
//        excelWriter.fill(fillData2(10), EasyExcel.writerSheet(1).build());
//        excelWriter.fill(fillData2(15), EasyExcelFactory.writerSheet(2).build());

        excelWriter.finish();

    }

    public static List<Map<String, Object>> fillData2(int num) {
        List<Map<String, Object>> mapList = new ArrayList<>();

        for (int i = 0; i < num; i++) {
            Map<String, Object> beanMap = new HashMap<>();
            beanMap.put("name", "姓名" + i);
            beanMap.put("welcome", "你好" + i);
            beanMap.put("address", "地址" + i);
            beanMap.put("date", DateUtil.format(new Date(), "yyyy-MM-dd"));
            mapList.add(beanMap);
        }
        return mapList;
    }
}

3.3、模板导出数据结果展示

如图:Sheet1,中间框,加边框
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel
如图:Sheet2,第三列加边框
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel
如图:Sheet3,数据随着占位符的位置向下生成
EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel

附录

占位符为什么是{.字段名}?源码分析

excelWriter.fill()逐行调试,发现:在读excel模板的时候,会先进行占位符的解析。看源码:
包路径: package com.alibaba.excel.write.executor;

 private List<AnalysisCell> readTemplateData(Map<ExcelWriteFillExecutor.UniqueDataFlagKey, List<AnalysisCell>> analysisCache) {
        List<AnalysisCell> analysisCellList = (List)analysisCache.get(this.currentUniqueDataFlag);
        if (analysisCellList != null) {
            return analysisCellList;
        } else {
            Sheet sheet = this.writeContext.writeSheetHolder().getCachedSheet();
            Map<ExcelWriteFillExecutor.UniqueDataFlagKey, Set<Integer>> firstRowCache = MapUtils.newHashMapWithExpectedSize(8);

            for(int i = 0; i <= sheet.getLastRowNum(); ++i) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    for(int j = 0; j < row.getLastCellNum(); ++j) {
                        Cell cell = row.getCell(j);
                        if (cell != null) {
                            // 解析单元格占位符
                            String preparedData = this.prepareData(cell, i, j, firstRowCache);
                            if (preparedData != null) {
                                cell.setCellValue(preparedData);
                            }
                        }
                    }
                }
            }

            return (List)analysisCache.get(this.currentUniqueDataFlag);
        }
    }

    private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<ExcelWriteFillExecutor.UniqueDataFlagKey, Set<Integer>> firstRowCache) {
        if (!CellType.STRING.equals(cell.getCellType())) {
            return null;
        } else {
            String value = cell.getStringCellValue();
            if (StringUtils.isEmpty(value)) {
                return null;
            } else {
                StringBuilder preparedData = new StringBuilder();
                AnalysisCell analysisCell = null;
                int startIndex = 0;
                int length = value.length();
                int lastPrepareDataIndex = 0;

                label81:
                while(startIndex < length) {
                    // 对单元格占位符进行分割,取出字段名,之后按字段名去取值
                    // 有兴趣的可以逐行调试
                    int prefixIndex = value.indexOf("{", startIndex);
                    if (prefixIndex < 0) {
                        break;
                    }

                    if (prefixIndex != 0) {
                        char prefixPrefixChar = value.charAt(prefixIndex - 1);
                        if (prefixPrefixChar == '\\') {
                            startIndex = prefixIndex + 1;
                            continue;
                        }
                    }

                    int suffixIndex = -1;

                    while(suffixIndex == -1 && startIndex < length) {
                        suffixIndex = value.indexOf("}", startIndex + 1);
                        if (suffixIndex < 0) {
                            break label81;
                        }

                        startIndex = suffixIndex + 1;
                        char prefixSuffixChar = value.charAt(suffixIndex - 1);
                        if (prefixSuffixChar == '\\') {
                            suffixIndex = -1;
                        }
                    }

                    if (analysisCell == null) {
                        analysisCell = this.initAnalysisCell(rowIndex, columnIndex);
                    }

                    String variable = value.substring(prefixIndex + 1, suffixIndex);
                    if (!StringUtils.isEmpty(variable)) {
                        int collectPrefixIndex = variable.indexOf(".");
                        if (collectPrefixIndex > -1) {
                            if (collectPrefixIndex != 0) {
                                analysisCell.setPrefix(variable.substring(0, collectPrefixIndex));
                            }

                            variable = variable.substring(collectPrefixIndex + 1);
                            if (StringUtils.isEmpty(variable)) {
                                continue;
                            }

                            analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COLLECTION);
                        }

                        analysisCell.getVariableList().add(variable);
                        if (lastPrepareDataIndex == prefixIndex) {
                            analysisCell.getPrepareDataList().add("");
                            if (lastPrepareDataIndex != 0) {
                                analysisCell.setOnlyOneVariable(Boolean.FALSE);
                            }
                        } else {
                            String data = this.convertPrepareData(value.substring(lastPrepareDataIndex, prefixIndex));
                            preparedData.append(data);
                            analysisCell.getPrepareDataList().add(data);
                            analysisCell.setOnlyOneVariable(Boolean.FALSE);
                        }

                        lastPrepareDataIndex = suffixIndex + 1;
                    }
                }

                if (analysisCell != null && CollectionUtils.isNotEmpty(analysisCell.getVariableList())) {
                    cell.setBlank();
                }

                return this.dealAnalysisCell(analysisCell, value, rowIndex, lastPrepareDataIndex, length, firstRowCache, preparedData);
            }
        }
    }

补充

EasyExcel读模板生成excel文件&注解Bean生成文件,# java,java,easyexcel
在读excel文件时,如果文件过大可能会出现错误,需要在读文件前加上一行代码就可以解决。

 // 添加的ZipSecureFile.setMinInflateRatio代码
 ZipSecureFile.setMinInflateRatio(-1.0d);
 XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(new File(filepath));

参考链接

EasyExcel读取模板填充数据_easyexcel填充模板_hello_cmy的博客-CSDN博客
读取excel报错 Zip bomb detected! The file would exceed the max. ratio of compressed file size to the文章来源地址https://www.toymoban.com/news/detail-686289.html

到了这里,关于EasyExcel读模板生成excel文件&注解Bean生成文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • EasyExcel知识【Java程序进行读写生成Excel操作】

    💂 个人主页:  爱吃豆的土豆 🌈欢迎加入社区,福利多多哦!土豆社区 🤟数据库专栏更新完毕: 数据库知识 🤟JDBC专栏更新完毕: JDBC知识 🤟Mybatis专栏更新完毕: Mybatis知识 💬 如果文章对你有帮助、 欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 目录 1,Easy Excel入门

    2023年04月08日
    浏览(48)
  • Java 使用 easyexcel 读取 excel 文件

    easyexcel 官网:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 1. 引入依赖并给出示例 excel     2. 两种读取的方式         (1)确定表头:建立对象,和表头形成映射。(这里以此为例)         (2)不确定表头:每一行映射为 MapString, Object。 3. 先创建 excel 中表头对应

    2024年02月12日
    浏览(59)
  • Java EasyExcel高效读取保存excel文件

    阿里开源出一款易上手,且比较节省内存的Excel操作框架:EasyExcel。EasyExcel是一行一行进行读取,再大的excel也不会出现OOM。 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存

    2024年02月16日
    浏览(50)
  • 【JAVA】easyexcel 导出excel文件带多个图片

    最终效果  pom版本 实现代码  

    2024年02月16日
    浏览(36)
  • easyexcel poi根据模板导出Excel

    参考:https://blog.csdn.net/weixin_45742032/article/details/119593288?spm=1001.2101.3001.6650.1utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-119593288-blog-86538258.235%5Ev38%5Epc_relevant_anti_t3_basedepth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-11959328

    2024年02月10日
    浏览(45)
  • 使用easyexcel填充模板数据,并导出excel

    导出excel功能非常场景,本片文章记录如何使用模板填充数据后再导出。因直接导出excel数据样式不符合要求,所以做了模板填充然后再导出excel。 效果如下: 注意:列表数据变量名前面要写点{.id},如果单条数据可以不写。 使用表单提交: 实体代码: controller代码: 只对je

    2024年03月11日
    浏览(53)
  • EasyExcel导出带下拉选数据的Excel数据导入模板

    #因为项目中需要导入一些信息,但是这些信息比较不常见,且在项目字典数据中维护有这些数据,所以在导出模板的时候,把这些数据一并导出,可以减少用户的编写,避免在导入的时候因为数据错误,发生一些业务问题 直接开始 1、以岗位类型为例,展示数据的实现方式

    2024年02月03日
    浏览(50)
  • 30 使用easyExcel依赖生成Excel

            在类上加注解,@ExcelProperty,注解中value属性是列名,index属性是第几列。         首先,需要创建一个泛型为Student的集合,存放多个Student对象,一个对象相当于excel表格的其中一行。然后,调用EasyExcel的write方法,需要填写excel生成的路径(需要写到生成的excel文件

    2024年02月14日
    浏览(36)
  • EasyExcel+POI制作带有有效性校验及下拉联动的Excel模板

    最近在做一个CRM系统的人员销售目标导入的相关需求,需要将销售人员的目标导入到系统中,就要求在Excel导入模板中 填写销售人员Id 和销售人员姓名。在使用的时候,这是一个易错的点,因为这两个字段交给了使用者去自由填写的话,是很容易填错的。除了文字本身填多填

    2024年02月11日
    浏览(43)
  • Java多例Bean的应用场景-easyExcel导入

    有状态会话bean :每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。 无状态会话bean :bean一旦实例化就被加进会话池中,各个

    2023年04月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包