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日

相关文章

  • Scala小程序详解及实例代码

    Scala小程序详解及实例代码 简介 Scala是一种基于JVM的多范式编程语言,可以进行面向对象编程和函数式编程,具有简洁、优雅、高效的特性。 我们将在本文中介绍Scala小程序的基本概念以及实例代码。 程序结构 Scala小程序的程序结构如下: // 单行注释 /* * 多行注释 */ object HelloWorld { /* 这是我的第一个 Sca…

    Java 2023年5月23日
    00
  • 最全Java面试208题,涵盖大厂必考范围

    最全Java面试208题攻略 简介 Java作为一门广泛应用的编程语言,是许多公司招聘的必备技能,也是很多程序员的选择。针对Java面试,现有一份较全的面试题目列表,本攻略将结合这些问题提供完整的解答。 策略 首先,将Java面试题目逐一分析,深入理解问题本质及出题人意图,思考面试官可能会对于这些问题提出哪些追问,以及我们该如何回答。 其次,可通过企业面试官…

    Java 2023年5月24日
    00
  • javascript计算当月剩余天数(天数计算器)示例代码

    这里就为你详细讲解一下 “javascript计算当月剩余天数(天数计算器)示例代码”的完整攻略吧。 一、前置知识 在开始编写这个 JavaScript 计算当月剩余天数的样例代码之前,你需要了解以下几个前置知识: JavaScript 基础语法:了解 JavaScript 基本数据类型、运算符、条件语句、循环语句等基础语法。 Date 对象:了解 Java…

    Java 2023年6月15日
    00
  • Java实现二分搜索树的示例代码

    下面我将详细讲解“Java实现二分搜索树的示例代码”的完整攻略。 什么是二分搜索树? 首先,我们需要明确什么是二分搜索树(BST)。 二分搜索树是一种二叉树,其中每个节点都有一个键值,且每个节点的键值都大于左子树中任意一个节点的键值,小于右子树中任意一个节点的键值。这种性质使得查找、插入、删除节点的操作都可以在时间复杂度为O(logN)的时间内完成,非常适合…

    Java 2023年5月23日
    00
  • extJs 常用到的增,删,改,查操作代码

    下面我将为您详细讲解 ExtJS 常用到的增、删、改、查操作的完整攻略。这里主要针对 ExtJS 版本 6.2 进行讲解。 概述 在 ExtJS 中,我们常常需要进行数据的增、删、改、查操作。这些操作基本都是基于 Ext.data.Store 和 Ext.data.Model 进行的。 其中,Ext.data.Store 负责连接数据源(可以是远程 URL,…

    Java 2023年6月15日
    00
  • Json字符串与Object、List、Map的互转工具类

    介绍:在Java中,经常会使用Json格式的字符串来传输数据,但是在Java程序内部我们又需要把Json字符串转换为Java对象来方便的操作数据。本文将介绍如何使用Json相关的工具类将Json字符串转换为Java对象,并将Java对象转换为Json格式的字符串。 将Json字符串转换为Java对象 当我们有一个Json格式的字符串需要转换为Java对象时,…

    Java 2023年5月26日
    00
  • java 中的乱码问题汇总及解决方案

    Java 中的乱码问题汇总及解决方案 在 Java 中,由于字符集编码不统一或者操作过程中出现错误,会导致乱码问题的出现。以下是解决 Java 中乱码问题的一些方法总结。 字符集编码不正确 确定并设置编码方式 在 Java 的编码过程中,需要使用字符集编码,否则会出现乱码。在开发中,一般使用 UTF-8 编码,若使用其他编码方式,需要明确指定字符集编码。比如…

    Java 2023年5月19日
    00
  • Java编程接口详细

    Java编程接口详细攻略 什么是Java编程接口(API) Java编程接口(API)是Java中非常重要的概念。它是一组Java类、接口和方法的集合,使得Java程序员可以轻松地使用某些功能或模块。API文档包含了Java为程序员提供的应用编程接口的详细介绍、类的功能描述和方法使用说明等。 Java API文档 Java API文档通常由类和方法的文档组成…

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