iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >EasyExcel怎么引用
  • 594
分享到

EasyExcel怎么引用

2023-06-27 10:06:00 594人浏览 安东尼
摘要

今天小编给大家分享一下Easyexcel怎么引用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前提导出数据到Excel是非常

今天小编给大家分享一下Easyexcel怎么引用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

前提

导出数据到Excel是非常常见的后端需求之一,今天来推荐一款阿里出品的Excel操作神器:EasyExcelEasyExcel从其依赖树来看是对apache-poi的封装,笔者从开始接触Excel处理就选用了EasyExcel,避免了广泛流传的apache-poi导致的内存泄漏问题。

引入EasyExcel依赖

引入EasyExcelMaven如下:

com.alibaba    easyexcel    ${easyexcel.version}

当前(2020-09)的最新版本为2.2.6

api简介

Excel文件主要围绕读和写操作进行处理,EasyExcelAPI也是围绕这两个方面进行设计。先看读操作的相关API

// 新建一个ExcelReaderBuilder实例ExcelReaderBuilder readerBuilder = EasyExcel.read();// 读取的文件对象,可以是File、路径(字符串)或者InputStream实例readerBuilder.file("");// 文件的密码readerBuilder.password("");// 指定sheet,可以是数字序号sheetNo或者字符串sheetName,若不指定则会读取所有的sheetreaderBuilder.sheet("");// 是否自动关闭输入流readerBuilder.autoCloseStream(true);// Excel文件格式,包括ExcelTypeEnum.XLSX和ExcelTypeEnum.XLSreaderBuilder.excelType(ExcelTypeEnum.XLSX);// 指定文件的标题行,可以是Class对象(结合@ExcelProperty注解使用),或者List实例readerBuilder.head(Collections.singletonList(Collections.singletonList("head")));// 注册读取事件的监听器,默认的数据类型为Map,第一列的元素的下标从0开始readerBuilder.reGISterReadListener(new AnalysisEventListener() {    @Override    public void invokeHeadMap(Map headMap, AnalysisContext context) {        // 这里会回调标题行,文件内容的首行会认为是标题行    }    @Override    public void invoke(Object o, AnalysisContext analysisContext) {        // 这里会回调每行的数据    }    @Override    public void doAfterAllAnalysed(AnalysisContext analysisContext) {    }});// 构建读取器ExcelReader excelReader = readerBuilder.build();// 读取数据excelReader.readAll();excelReader.finish();

可以看到,读操作主要使用Builder模式和事件监听(或者可以理解为「观察者模式」)的设计。一般情况下,上面的代码可以简化如下:

Map head = new HashMap();List data = new LinkedList();EasyExcel.read("文件的绝对路径").sheet()        .registerReadListener(new AnalysisEventListener() {            @Override            public void invokeHeadMap(Map headMap, AnalysisContext context) {                head.putAll(headMap);            }            @Override            public void invoke(Map row, AnalysisContext analysisContext) {                data.add(row);            }            @Override            public void doAfterAllAnalysed(AnalysisContext analysisContext) {                    // 这里可以打印日志告知所有行读取完毕            }        }).doRead();

如果需要读取数据并且转换为对应的对象列表,则需要指定标题行的Class,结合注解@ExcelProperty使用:

文件内容:|订单编号|手机号||ORDER_ID_1|112222||ORDER_ID_2|334455|@Dataprivate static class OrderDTO {    @ExcelProperty(value = "订单编号")    private String orderId;    @ExcelProperty(value = "手机号")    private String phone;}Map head = new HashMap();List data = new LinkedList();EasyExcel.read("文件的绝对路径").head(OrderDTO.class).sheet()        .registerReadListener(new AnalysisEventListener() {            @Override            public void invokeHeadMap(Map headMap, AnalysisContext context) {                head.putAll(headMap);            }            @Override            public void invoke(OrderDTO row, AnalysisContext analysisContext) {                data.add(row);            }            @Override            public void doAfterAllAnalysed(AnalysisContext analysisContext) {                // 这里可以打印日志告知所有行读取完毕            }        }).doRead();

「如果数据量巨大,建议使用Map类型读取和操作数据对象,否则大量的反射操作会使读取数据的耗时大大增加,极端情况下,例如属性多的时候反射操作的耗时有可能比读取和遍历的时间长」

接着看写操作的API

// 新建一个ExcelWriterBuilder实例ExcelWriterBuilder writerBuilder = EasyExcel.write();// 输出的文件对象,可以是File、路径(字符串)或者OutputStream实例writerBuilder.file("");// 指定sheet,可以是数字序号sheetNo或者字符串sheetName,可以不设置,由下面提到的WriteSheet覆盖writerBuilder.sheet("");// 文件的密码writerBuilder.password("");// Excel文件格式,包括ExcelTypeEnum.XLSX和ExcelTypeEnum.XLSwriterBuilder.excelType(ExcelTypeEnum.XLSX);// 是否自动关闭输出流writerBuilder.autoCloseStream(true);// 指定文件的标题行,可以是Class对象(结合@ExcelProperty注解使用),或者List实例writerBuilder.head(Collections.singletonList(Collections.singletonList("head")));// 构建ExcelWriter实例ExcelWriter excelWriter = writerBuilder.build();List data = new ArrayList();// 构建输出的sheetWriteSheet writeSheet = new WriteSheet();writeSheet.setSheetName("target");excelWriter.write(data, writeSheet);// 这一步一定要调用,否则输出的文件有可能不完整excelWriter.finish();

ExcelWriterBuilder中还有很多样式、行处理器、转换器设置等方法,笔者觉得不常用,这里不做举例,内容的样式通常在输出文件之后再次加工会更加容易操作。写操作一般可以简化如下:

List head = new ArrayList();List data = new LinkedList();EasyExcel.write("输出文件绝对路径")        .head(head)        .excelType(ExcelTypeEnum.XLSX)        .sheet("target")        .doWrite(data);

实用技巧

下面简单介绍一下生产中用到的实用技巧。

多线程

使用EasyExcel线程读建议在限定的前提条件下使用:

  • 源文件已经被分割成多个小文件,并且每个小文件的标题行和列数一致。

  • 机器内存要充足,因为并发读取的结果最后需要合并成一个大的结果集,全部数据存放在内存中。

经常遇到外部反馈的多份文件需要紧急进行数据分析或者交叉校对,为了加快文件读取,笔者通常使用这种方式批量读取格式一致的Excel文件

一个简单的例子如下:

@Slf4jpublic class EasyExcelConcurrentRead {    static final int N_CPU = Runtime.getRuntime().availableProcessors();    public static void main(String[] args) throws Exception {        // 假设I盘的temp目录下有一堆同格式的Excel文件        String dir = "I:\\temp";        List mergeResult = Lists.newLinkedList();        ThreadPoolExecutor executor = new ThreadPoolExecutor(N_CPU, N_CPU * 2, 0, TimeUnit.SECONDS,                new LinkedBlockingQueue(), new ThreadFactory() {            private final AtomicInteger counter = new AtomicInteger();            @Override            public Thread newThread(@NotNull Runnable r) {                Thread thread = new Thread(r);                thread.setDaemon(true);                thread.setName("ExcelReadWorker-" + counter.getAndIncrement());                return thread;            }        });        Path dirPath = Paths.get(dir);        if (Files.isDirectory(dirPath)) {            List futures = Files.list(dirPath)                    .map(path -> path.toAbsolutePath().toString())                    .filter(absolutePath -> absolutePath.endsWith(".xls") || absolutePath.endsWith(".xlsx"))                    .map(absolutePath -> executor.submit(new ReadTask(absolutePath)))                    .collect(Collectors.toList());            for (Future future : futures) {                mergeResult.addAll(future.get());            }        }        log.info("读取[{}]目录下的文件成功,一共加载:{}行数据", dir, mergeResult.size());        // 其他业务逻辑.....    }    @RequiredArgsConstructor    private static class ReadTask implements Callable {        private final String location;        @Override        public List call() throws Exception {            List data = Lists.newLinkedList();            EasyExcel.read(location).sheet()                    .registerReadListener(new AnalysisEventListener() {                        @Override                        public void invoke(Map row, AnalysisContext analysisContext) {                            data.add(row);                        }                        @Override                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {                            log.info("读取路径[{}]文件成功,一共[{}]行", location, data.size());                        }                    }).doRead();            return data;        }    }}

这里采用ThreadPoolExecutor#submit()提交并发读的任务,然后使用Future#get()等待所有任务完成之后再合并最终的读取结果。

注意,一般文件的写操作不能并发执行,否则很大的概率会导致数据错乱

多Sheet写

Sheet写,其实就是使用同一个ExcelWriter实例,写入多个WriteSheet实例中,每个Sheet的标题行可以通过WriteSheet实例中的配置属性进行覆盖,代码如下:

public class EasyExcelMultiSheetWrite {    public static void main(String[] args) throws Exception {        ExcelWriterBuilder writerBuilder = EasyExcel.write();        writerBuilder.excelType(ExcelTypeEnum.XLSX);        writerBuilder.autoCloseStream(true);        writerBuilder.file("I:\\temp\\temp.xlsx");        ExcelWriter excelWriter = writerBuilder.build();        WriteSheet firstSheet = new WriteSheet();        firstSheet.setSheetName("first");        firstSheet.setHead(Collections.singletonList(Collections.singletonList("第一个Sheet的Head")));        // 写入第一个命名为first的Sheet        excelWriter.write(Collections.singletonList(Collections.singletonList("第一个Sheet的数据")), firstSheet);        WriteSheet secondSheet = new WriteSheet();        secondSheet.setSheetName("second");        secondSheet.setHead(Collections.singletonList(Collections.singletonList("第二个Sheet的Head")));        // 写入第二个命名为second的Sheet        excelWriter.write(Collections.singletonList(Collections.singletonList("第二个Sheet的数据")), secondSheet);        excelWriter.finish();    }}

分页查询和批量写

在一些数据量比较大的场景下,可以考虑分页查询和批量写,其实就是分页查询原始数据 -> 数据聚合或者转换 -> 写目标数据 -> 下一页查询....。其实数据量少的情况下,一次性全量查询和全量写也只是分页查询和批量写的一个特例,因此可以把查询、转换和写操作抽象成一个可复用的模板方法:

int batchSize = 定义每篇查询的条数;OutputStream outputStream = 定义写到何处;ExcelWriter writer = new ExcelWriterBuilder()        .autoCloseStream(true)        .file(outputStream)        .excelType(ExcelTypeEnum.XLSX)        .head(ExcelModel.class);for (;;){    List list = originModelRepository.分页查询();    if (list.isEmpty()){        writer.finish();        break;    }else {        list 转换-> List excelModelList;        writer.write(excelModelList);    }}

Excel上传与下载

下面的例子适用于Servlet容器,常见的如Tomcat,应用于spring-boot-starter-WEB

Excel文件上传跟普通文件上传的操作差不多,然后使用EasyExcelExcelReader读取请求对象MultiparthttpservletRequest中文件部分抽象的InputStream实例即可:

@PostMapping(path = "/upload")public ResponseEntity upload(MultipartHttpServletRequest request) throws Exception {    Map fileMap = request.getFileMap();    for (Map.Entry part : fileMap.entrySet()) {        InputStream inputStream = part.getValue().getInputStream();        Map head = new HashMap();        List data = new LinkedList();        EasyExcel.read(inputStream).sheet()                .registerReadListener(new AnalysisEventListener() {                    @Override                    public void invokeHeadMap(Map headMap, AnalysisContext context) {                        head.putAll(headMap);                    }                    @Override                    public void invoke(Map row, AnalysisContext analysisContext) {                        data.add(row);                    }                    @Override                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {                        log.info("读取文件[{}]成功,一共:{}行......", part.geTKEy(), data.size());                    }                }).doRead();        // 其他业务逻辑    }    return ResponseEntity.ok("success");}

使用Postman请求如下:

使用EasyExcel进行Excel文件导出也比较简单,只需要把响应对象HttpServletResponse中携带的OutputStream对象附着到EasyExcelExcelWriter实例即可:

@GetMapping(path = "/download")public void download(HttpServletResponse response) throws Exception {    // 这里文件名如果涉及中文一定要使用URL编码,否则会乱码    String fileName = URLEncoder.encode("文件名.xlsx", StandardCharsets.UTF_8.toString());    // 封装标题行    List head = new ArrayList();    // 封装数据    List data = new LinkedList();    response.setContentType("application/force-download");    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);    EasyExcel.write(response.getOutputStream())            .head(head)            .autoCloseStream(true)            .excelType(ExcelTypeEnum.XLSX)            .sheet("Sheet名字")            .doWrite(data);}

这里需要注意一下:

  • 文件名如果包含中文,需要进行URL编码,否则一定会乱码。

  • 无论导入或者导出,如果数据量大比较耗时,使用了Nginx的话记得调整Nginx中的连接、读写超时时间的上限配置。

  • 使用SpringBoot需要调整spring.servlet.multipart.max-request-sizespring.servlet.multipart.max-file-size的配置值,避免上传的文件过大出现异常。

以上就是“EasyExcel怎么引用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: EasyExcel怎么引用

本文链接: https://www.lsjlt.com/news/309712.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • EasyExcel怎么引用
    今天小编给大家分享一下EasyExcel怎么引用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前提导出数据到Excel是非常...
    99+
    2023-06-27
  • SpringBoot怎么整合EasyExcel
    这篇文章主要介绍“SpringBoot怎么整合EasyExcel”,在日常操作中,相信很多人在SpringBoot怎么整合EasyExcel问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot怎...
    99+
    2023-06-21
  • SpringBoot怎么集成EasyExcel应用
    这篇文章主要讲解了“SpringBoot怎么集成EasyExcel应用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么集成EasyExcel应用”吧!1、介绍特点:Ja...
    99+
    2023-06-08
  • Java怎么使用EasyExcel进行单元格合并
    本篇内容介绍了“Java怎么使用EasyExcel进行单元格合并”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.项目场景:简介:报销单导出...
    99+
    2023-07-02
  • 怎么在Java中使用EasyExcel来操作Excel表
    怎么在Java中使用EasyExcel来操作Excel表?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一.读ExcelExcel表格示例对象示例@Datapublic ...
    99+
    2023-06-14
  • EasyExcel 的基本使用
    EasyExcel EasyExcel 是一个基于 Java 的简单、省内存的读写 Excel 的开源项目。在尽可能节约内存的情况下支持读写百 M 的 Excel。 官网:https://easye...
    99+
    2023-09-12
    java excel spring boot
  • 怎么使用Java+EasyExcel实现文件上传功能
    这篇“怎么使用Java+EasyExcel实现文件上传功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Java+E...
    99+
    2023-07-05
  • 使用EasyExcel模版导出
    一、官方提供方法 easyexcel官方文档 填充Excel | Easy Excel 官方demo是利用本地模版文件填充并下载到本地 @Test public void complexFill() { ...
    99+
    2023-09-01
    excel java 后端
  • 【EasyExcel】的一些用法
    一、AnalysisEventListener监听类,可以用来解析Excel 用来进行监听,一方面,它可以处理空数据的检查,重复数据的检查等一些数据筛查工作。另一方面,也可以做数据的存储,如果在此做数...
    99+
    2023-09-05
    excel java
  • Java怎么用EasyExcel解析动态表头并导出
    本文小编为大家详细介绍“Java怎么用EasyExcel解析动态表头并导出”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java怎么用EasyExcel解析动态表头并导出”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知...
    99+
    2023-07-04
  • Java easyExcel的多级表头怎么导入
    这篇文章主要介绍了Java easyExcel的多级表头怎么导入的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java easyExcel的多级表头怎么导入文章都会有所收获,下面我们一起来看...
    99+
    2023-07-02
  • Java应用EasyExcel工具类
    目录一、前言二、导入三、导出一、前言 关于EasyExcel,它对poi做了进一步的封装,使得整个编写流程更加的面向对象。好处嘛,我认为流程上更加清晰即易懂、可读性更好,坏处的话,则...
    99+
    2024-04-02
  • Java中EasyExcel的使用方式
    目录背景项目构建及依赖创建实体类生成Excel解析Excel其他相关特殊用法自定义转换器保留两位小数排除指定Excel列小结背景 系统中经常要导出大量的数据,格式基本上都是Excel...
    99+
    2022-11-13
    Java 中EasyExcel的使用方式 Java EasyExcel
  • 怎么引用css
    本文小编为大家详细介绍“怎么引用css”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么引用css”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、内部样式表内部样式表是将CSS样式表嵌入到HTML文档中。使用...
    99+
    2023-07-06
  • TensorFlow怎么引用
    这篇“TensorFlow怎么引用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“TensorFlow怎么引用”文章吧。imp...
    99+
    2023-06-04
  • 怎么引用JavaScript
    这篇文章主要介绍“怎么引用JavaScript”,在日常操作中,相信很多人在怎么引用JavaScript问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么引用JavaScript”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-27
  • java使用EasyExcel导入导出excel
    目录一、准备工作 1、导包二、了解注解 1、常用注解2、@ExcelProperty注解 3、@ColumnWith注解 4、@ContentFontStyle注解 5、@Conte...
    99+
    2024-04-02
  • Java使用easyExcel实现导入功能
    今天带来的是esayExcel的简单使用小结,一个高效的Excel的处理框架 临时接到领导要求需要做一个Excel导入功能,于是发挥我的特长——面向百度编程。...
    99+
    2022-11-13
    Java easyExcel 导入Excel
  • Java easyexcel使用教程之导出篇
    目录EasyExcel简介1、导入Maven依赖2、新建Student.java类3、generateStudentUtil.java类,随机生成Student对象4、BaseTes...
    99+
    2024-04-02
  • 【java学习】EasyExcel的简单使用
    EasyExcel的简单使用 前言Excel读1.实体类2.读监听器与测试类3.输出结果 Excel写1.实体类2.写入Excel的测试类3.输出结果 填充Excel1.Excel模板...
    99+
    2023-10-03
    java 学习
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作