Java 中EasyExcel的使用方式

Java 中EasyExcel的使用方式

什么是EasyExcel

EasyExcel 是阿里巴巴开源的一个 Java 操作 Excel 的简单工具,具有自动识别 Excel 文件的类型(2003/2007/2010等)及生成 Excel 文件,读取数据和流式写入数据的功能。为我们处理 Excel 带来了很大的便利性。

EasyExcel 的使用方式

1. 添加依赖

在项目的 pom.xml 文件中,添加以下依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.1.6</version> 
</dependency>

2. 流式读取 Excel 文件

EasyExcel 支持流式读取 Excel 文件,这种方式适用于读取大批量数据时。

public class ExcelReaderDemo {
    /**
     * 读取普通的 sheet
     */
    public void readExcel(String fileName) throws IOException {
        // 直接传入文件流,通过回调函数读取excel中的每一行
        EasyExcel.read(fileName, new DemoDataListener()).sheet().doRead();
    }

    /**
     * 读取指定的 sheet
     */
    public void readSheet(String fileName, String sheetName) throws IOException {
        // 直接传入文件流,通过回调函数读取excel中的每一行,指定读取的sheet
        EasyExcel.read(fileName, new DemoDataListener()).sheet(sheetName).doRead();
    }

    /**
     * Excel 每一行的实体类,注意需要实现 EasyExcel 的接口
     */
    public static class DemoData {
        // Excel第一列数据
        private String firstCol;
        // Excel第二列数据
        private String secondCol;

        // setter 和 getter 方法省略略
        // ...
    }

    /**
     * 回调函数,通过 EasyExcel.read() 指定的示例
     */
    public static class DemoDataListener extends AnalysisEventListener<DemoData> {
        // 批处理阈值,每解析到这么多个数据就会回调一次 invoke 去处理
        private static final int BATCH_COUNT = 5;

        // 自定义的数据处理逻辑
        @Override
        public void invoke(DemoData data, AnalysisContext context) {
            // 接收到一条数据就处理一次
            System.out.println("接收到数据:" + data);
        }

        // 所有数据解析完成之后的回调
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            // 所有数据解析完成之后的回调
            System.out.println("所有数据解析完成");
        }
    }
}

3. 流式写入 Excel 文件

EasyExcel 支持流式写入 Excel 文件,这种方式适用于大批量写入数据时。

public class ExcelWriterDemo {
    /**
     * 写入 Excel 文件
     */
    public void writeExcel(String fileName) throws IOException {
        // 文件输出流,用来输出 Excel
        OutputStream out = new FileOutputStream(fileName);
        // ExcelWriter
        ExcelWriter excelWriter = EasyExcel.write(out).build();

        // sheet1
        writeSheet1(excelWriter);

        // sheet2
        writeSheet2(excelWriter);

        // 最后的操作
        excelWriter.finish();
    }

    /**
     * 写入 Sheet1
     */
    public void writeSheet1(ExcelWriter excelWriter) {
        // 设置sheet名字
        Sheet sheet = new Sheet(1, 0, DemoData.class);
        sheet.setSheetName("Sheet1");

        // 数据集合
        List<DemoData> data = getData();

        // 写入 Excel
        excelWriter.write(data, sheet);
    }

    /**
     * 写入 Sheet2
     */
    public void writeSheet2(ExcelWriter excelWriter) {
        // 设置sheet名字
        Sheet sheet = new Sheet(2, 0, DemoData.class);
        sheet.setSheetName("Sheet2");

        // 数据集合
        List<DemoData> data = getData();

        // 写入 Excel
        excelWriter.write(data, sheet);
    }

    /**
     * 获取数据
     */
    private List<DemoData> getData() {
        List<DemoData> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setFirstCol("第一列数据" + i);
            data.setSecondCol("第二列数据" + i);
            list.add(data);
        }
        return list;
    }

    /**
     * Excel 每一行的实体类,注意需要实现 EasyExcel 的接口
     */
    public static class DemoData {
        // Excel第一列数据
        private String firstCol;
        // Excel第二列数据
        private String secondCol;

        // setter 和 getter 方法省略略
        // ...
    }
}

EasyExcel 的常见问题

  1. 读取速度太慢,有没有更快的方法?
    答:默认读取是按行读取的,能读多少就要创建多少个对象,所以如果要读取大数据量时,需要用流式读取,这样就可以一行一行地读取,减少对象数量。
EasyExcel.read(file.getInputStream(), DemoData.class, new DemoDataListener()).sheet().doRead();
  1. 写入 Excel 文件时,如何设置字体?
    答:可以通过 HeadStyleHandlerContentStyleHandler 继承 AbstractCellStyleStrategy 然后覆盖 getHeadCellStylegetContentCellStyle 方法分别返回对应的 CellStyle 类型,例如:
public class ExcelCellStyleStrategy extends AbstractCellStyleStrategy {

    /**
     * 设置表头样式
     */
    @Override
    protected CellStyle getHeadCellStyle(Head head) {
        // 创建 CellStyle 对象
        CellStyle cellStyle = head.getHeadRowCellStyles().get(0);

        // 设置字体
        Font font = cellStyle.getFont();
        font.setFontName("宋体");//设置字体名称
        font.setFontHeightInPoints((short)12);//设置字号
        font.setBold(true);//是否加粗

        // 设置背景色
        cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        // 边框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        return cellStyle;
    }

    /**
     * 设置内容样式
     */
    @Override
    protected CellStyle getContentCellStyle(Head head, List<List<String>> datas, Integer rowIndex,
                                             Integer cellIndex) {
        if (rowIndex % 2 == 0) {
            return getEvenCellStyle();
        } else {
            return super.getContentCellStyle(head, datas, rowIndex, cellIndex);
        }
    }

    // 设置偶数行的样式
    private CellStyle getEvenCellStyle() {
        CellStyle cellStyle = super.getBaseCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return cellStyle;
    }

}

示例

下面是一个复杂的流程,读取 A 文件夹下的多个 Excel 文件,并将它们的内容合并到一个新的 Excel 文件中:

public class ExcelMergeDemo {
    /**
     * 读取 A 文件夹下所有 Excel 文件,并合并到一个 Excel 文件中
     */
    public void merge(String path, String outFile) throws IOException {
        // 所有 DataFrame
        List<DataFrame> dataFrames = new ArrayList<>();

        // 加载所有 Excel 文件
        File file = new File(path);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files) {
                if (f.getName().endsWith(".xlsx")) {
                    DataFrame dataFrame = Excel.read(f.getAbsolutePath())
                            .sheet(0)
                            .headerAlias(getHeaderAlias())
                            .read();
                    dataFrames.add(dataFrame);
                }
            }
        }

        // 合并成一个 Excel 文件
        Excel.write(outFile)
                .sheet("Sheet1")
                .headerAlias(getHeaderAlias())
                .write(dataFrames)
                .finish();
    }

    /**
     * 返回表头映射
     */
    private Map<String, String> getHeaderAlias() {
        Map<String, String> headerAlias = new HashMap<>();
        headerAlias.put("编号", "id");
        headerAlias.put("姓名", "name");
        headerAlias.put("年龄", "age");
        return headerAlias;
    }
}

以上就是 EasyExcel 的使用方式和示例,我们可以通过 EasyExcel 实现丰富的 Excel 文件交互体验。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 中EasyExcel的使用方式 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • IDEA 中 30 秒创建一个 Spring Cloud Alibaba 工程

    下面详细讲解如何在 IDEA 中快速创建一个 Spring Cloud Alibaba 工程的攻略: 准备工作 在开始创建项目前,我们需要为 IDEA 安装 Alibaba Cloud 插件。具体步骤如下: 打开 IDEA IDE 点击菜单栏的 “Plugins” 在搜索框中输入 “Alibaba Cloud Toolkit” 点击 “Install” 安装…

    Java 2023年5月23日
    00
  • Java String之contains方法的使用详解

    Java String 之 contains 方法使用详解 在 Java 中,String 类是最常用的类之一,而 String 类的 contains 方法则是其中常用的方法之一。本篇文章详细讲解了 Java String 类的 contains 方法使用的注意点以及示例演示。 contains 方法的作用 contains 方法的作用是判断某个字符串是否…

    Java 2023年5月26日
    00
  • Java输出链表倒数第k个节点

    下面是Java输出链表倒数第k个节点的完整攻略: 理解题意意义:输入一个链表,输出该链表中倒数第k个节点的值。 考虑边界条件:输入的链表为空或k不能大于链表长度。 定义两个指针,分别指向链表头部。让其中一个从0开始,先走k步,另一个开始走。然后两个指针同步走,直到其中一个到达链表尾部。另一个指针此时就是链表倒数第k个节点。 编写代码: public List…

    Java 2023年5月26日
    00
  • Java ArrayList 数组之间相互转换

    下面是Java ArrayList数组之间相互转换的完整攻略。 ArrayList 和数组之间的区别 在Java中,ArrayList和数组都可以用来存储多个相同类型的元素。但是,它们有以下的区别: 数组是静态数据类型,需要预先指定长度,而且只能存储同一种类型的元素; ArrayList则是动态数据类型,可以在不确定元素个数的情况下存储多个不同类型的元素,并…

    Java 2023年5月26日
    00
  • js验证身份证号有效性并提示对应信息

    为了讲解验证身份证号有效性的完整攻略,我将分以下几个步骤进行介绍: 了解身份证号的规则 身份证号是由18或15位数字和字母组成的标识符,其中最后一位可能是数字或字母X。身份证号是根据国家标准GB 11643-1999确定的,身份证号的前17位数字是根据ISO 7064:1983算法计算出来的,最后一位是校验码。 编写JavaScript代码实现身份证有效性的…

    Java 2023年6月16日
    00
  • Spring Boot + Jpa(Hibernate) 架构基本配置详解

    我将为您详细讲解“Spring Boot + Jpa(Hibernate) 架构基本配置详解”的完整攻略。 一、前置条件 在进行Spring Boot + Jpa(Hibernate) 架构的搭建之前,确保您已经安装好了Java和Maven,且熟悉了Spring Boot框架的基本概念和使用方法。 二、添加依赖 1.添加Spring Boot和Jpa(Hib…

    Java 2023年5月19日
    00
  • Spring AOP定义Before增加实战案例详解

    在Spring应用程序中,我们可以使用AOP(面向切面编程)来实现横切关注点的模块化。在本文中,我们将详细介绍如何使用Spring AOP定义Before增强,并提供两个示例说明。 1. Before增强 Before增强是AOP中的一种通知类型,它在目标方法执行之前执行。我们可以使用@Before注解将一个方法标记为Before增强。下面是一个示例代码: …

    Java 2023年5月18日
    00
  • 基于hibernate框架在eclipse下的配置方法(必看篇)

    下面我会详细讲解“基于hibernate框架在eclipse下的配置方法(必看篇)”的完整攻略,同时会提供两个示例。 1. 准备工作 首先,需要下载hibernate框架的jar包,并把它们添加到项目的classpath下。 其次,需要建立一个数据库,并在其中建立需要的表结构。 2. 在eclipse中创建一个java工程 打开eclipse,选择File …

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部