喝水不忘挖井人,感谢阿里巴巴项目组提供了easyexcel工具类,github地址:https://github.com/alibaba/easyexcel

环境搭建

  • easyexcel 依赖(必须)
  • springboot (不是必须)
  • lombok (不是必须)
 <dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beat1</version>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
</dependency>

读取excel文件

小于1000行数据

默认读取

读取Sheet1的全部数据

 String filePath = "/home/chenmingjian/Downloads/学生表.xlsx";
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath);

指定读取

下面是学生表.xlsx中Sheet1,Sheet2的数据


获取Sheet1表头以下的信息

String filePath = "/home/chenmingjian/Downloads/学生表.xlsx";
//第一个1代表sheet1, 第二个1代表从第几行开始读取数据,行号最小值为0
Sheet sheet = new Sheet(1, 1);
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath,sheet);

获取Sheet2的所有信息

 String filePath = "/home/chenmingjian/Downloads/学生表.xlsx";
Sheet sheet = new Sheet(2, 0);
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath,sheet);

大于1000行数据

默认读取

String filePath = "/home/chenmingjian/Downloads/学生表.xlsx";
List<Object> objects = ExcelUtil.readMoreThan1000Row(filePath);

指定读取

String filePath = "/home/chenmingjian/Downloads/学生表.xlsx";
Sheet sheet = new Sheet(1, 2);
List<Object> objects = ExcelUtil.readMoreThan1000Row(filePath,sheet);

导出excle

单个Sheet导出

无模型映射导出

String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
List<List<Object>> data = new ArrayList<>();
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
List<String> head = Arrays.asList("表头1", "表头2", "表头3");
ExcelUtil.writeBySimple(filePath,data,head);

结果

模型映射导出

1、定义好模型对象

package com.springboot.utils.excel.test;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;
import lombok.EqualsAndHashCode; /**
* @description:
* @author: chenmingjian
* @date: 19-4-3 14:44
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class TableHeaderExcelProperty extends BaseRowModel { /**
* value: 表头名称
* index: 列的号, 0表示第一列
*/
@ExcelProperty(value = "姓名", index = 0)
private String name; @ExcelProperty(value = "年龄",index = 1)
private int age; @ExcelProperty(value = "学校",index = 2)
private String school;
}

2、调用方法

String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
ArrayList<TableHeaderExcelProperty> data = new ArrayList<>();
for(int i = 0; i < 4; i++){
TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();
tableHeaderExcelProperty.setName("cmj" + i);
tableHeaderExcelProperty.setAge(22 + i);
tableHeaderExcelProperty.setSchool("清华大学" + i);
data.add(tableHeaderExcelProperty);
} ExcelUtil.writeWithTemplate(filePath,data);

多个Sheet导出

1、定义好模型对象

package com.springboot.utils.excel.test;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import lombok.Data;
import lombok.EqualsAndHashCode; /**
* @description:
* @author: chenmingjian
* @date: 19-4-3 14:44
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class TableHeaderExcelProperty extends BaseRowModel { /**
* value: 表头名称
* index: 列的号, 0表示第一列
*/
@ExcelProperty(value = "姓名", index = 0)
private String name; @ExcelProperty(value = "年龄",index = 1)
private int age; @ExcelProperty(value = "学校",index = 2)
private String school;
}

2、调用方法

 ArrayList<ExcelUtil.MultipleSheelPropety> list1 = new ArrayList<>();
for(int j = 1; j < 4; j++){
ArrayList<TableHeaderExcelProperty> list = new ArrayList<>();
for(int i = 0; i < 4; i++){
TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();
tableHeaderExcelProperty.setName("cmj" + i);
tableHeaderExcelProperty.setAge(22 + i);
tableHeaderExcelProperty.setSchool("清华大学" + i);
list.add(tableHeaderExcelProperty);
} Sheet sheet = new Sheet(j, 0);
sheet.setSheetName("sheet" + j); ExcelUtil.MultipleSheelPropety multipleSheelPropety = new ExcelUtil.MultipleSheelPropety();
multipleSheelPropety.setData(list);
multipleSheelPropety.setSheet(sheet); list1.add(multipleSheelPropety); } ExcelUtil.writeWithMultipleSheel("/home/chenmingjian/Downloads/aaa.xlsx",list1);

工具类

package com.springboot.utils.excel;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* @description:
* @author: chenmingjian
* @date: 19-3-18 16:16
*/
@Slf4j
public class ExcelUtil { private static Sheet initSheet; static {
initSheet = new Sheet(1, 0);
initSheet.setSheetName("sheet");
//设置自适应宽度
initSheet.setAutoWidth(Boolean.TRUE);
} /**
* 读取少于1000行数据
* @param filePath 文件绝对路径
* @return
*/
public static List<Object> readLessThan1000Row(String filePath){
return readLessThan1000RowBySheet(filePath,null);
} /**
* 读小于1000行数据, 带样式
* filePath 文件绝对路径
* initSheet :
* sheetNo: sheet页码,默认为1
* headLineMun: 从第几行开始读取数据,默认为0, 表示从第一行开始读取
* clazz: 返回数据List<Object> 中Object的类名
*/
public static List<Object> readLessThan1000RowBySheet(String filePath, Sheet sheet){
if(!StringUtils.hasText(filePath)){
return null;
} sheet = sheet != null ? sheet : initSheet; InputStream fileStream = null;
try {
fileStream = new FileInputStream(filePath);
return EasyExcelFactory.read(fileStream, sheet);
} catch (FileNotFoundException e) {
log.info("找不到文件或文件路径错误, 文件:{}", filePath);
}finally {
try {
if(fileStream != null){
fileStream.close();
}
} catch (IOException e) {
log.info("excel文件读取失败, 失败原因:{}", e);
}
}
return null;
} /**
* 读大于1000行数据
* @param filePath 文件觉得路径
* @return
*/
public static List<Object> readMoreThan1000Row(String filePath){
return readMoreThan1000RowBySheet(filePath,null);
} /**
* 读大于1000行数据, 带样式
* @param filePath 文件觉得路径
* @return
*/
public static List<Object> readMoreThan1000RowBySheet(String filePath, Sheet sheet){
if(!StringUtils.hasText(filePath)){
return null;
} sheet = sheet != null ? sheet : initSheet; InputStream fileStream = null;
try {
fileStream = new FileInputStream(filePath);
ExcelListener excelListener = new ExcelListener();
EasyExcelFactory.readBySax(fileStream, sheet, excelListener);
return excelListener.getDatas();
} catch (FileNotFoundException e) {
log.error("找不到文件或文件路径错误, 文件:{}", filePath);
}finally {
try {
if(fileStream != null){
fileStream.close();
}
} catch (IOException e) {
log.error("excel文件读取失败, 失败原因:{}", e);
}
}
return null;
} /**
* 生成excle
* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx
* @param data 数据源
* @param head 表头
*/
public static void writeBySimple(String filePath, List<List<Object>> data, List<String> head){
writeSimpleBySheet(filePath,data,head,null);
} /**
* 生成excle
* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx
* @param data 数据源
* @param sheet excle页面样式
* @param head 表头
*/
public static void writeSimpleBySheet(String filePath, List<List<Object>> data, List<String> head, Sheet sheet){
sheet = (sheet != null) ? sheet : initSheet; if(head != null){
List<List<String>> list = new ArrayList<>();
head.forEach(h -> list.add(Collections.singletonList(h)));
sheet.setHead(list);
} OutputStream outputStream = null;
ExcelWriter writer = null;
try {
outputStream = new FileOutputStream(filePath);
writer = EasyExcelFactory.getWriter(outputStream);
writer.write1(data,sheet);
} catch (FileNotFoundException e) {
log.error("找不到文件或文件路径错误, 文件:{}", filePath);
}finally {
try {
if(writer != null){
writer.finish();
} if(outputStream != null){
outputStream.close();
} } catch (IOException e) {
log.error("excel文件导出失败, 失败原因:{}", e);
}
} } /**
* 生成excle
* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx
* @param data 数据源
*/
public static void writeWithTemplate(String filePath, List<? extends BaseRowModel> data){
writeWithTemplateAndSheet(filePath,data,null);
} /**
* 生成excle
* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx
* @param data 数据源
* @param sheet excle页面样式
*/
public static void writeWithTemplateAndSheet(String filePath, List<? extends BaseRowModel> data, Sheet sheet){
if(CollectionUtils.isEmpty(data)){
return;
} sheet = (sheet != null) ? sheet : initSheet;
sheet.setClazz(data.get(0).getClass()); OutputStream outputStream = null;
ExcelWriter writer = null;
try {
outputStream = new FileOutputStream(filePath);
writer = EasyExcelFactory.getWriter(outputStream);
writer.write(data,sheet);
} catch (FileNotFoundException e) {
log.error("找不到文件或文件路径错误, 文件:{}", filePath);
}finally {
try {
if(writer != null){
writer.finish();
} if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
log.error("excel文件导出失败, 失败原因:{}", e);
}
} } /**
* 生成多Sheet的excle
* @param filePath 绝对路径, 如:/home/chenmingjian/Downloads/aaa.xlsx
* @param multipleSheelPropetys
*/
public static void writeWithMultipleSheel(String filePath,List<MultipleSheelPropety> multipleSheelPropetys){
if(CollectionUtils.isEmpty(multipleSheelPropetys)){
return;
} OutputStream outputStream = null;
ExcelWriter writer = null;
try {
outputStream = new FileOutputStream(filePath);
writer = EasyExcelFactory.getWriter(outputStream);
for (MultipleSheelPropety multipleSheelPropety : multipleSheelPropetys) {
Sheet sheet = multipleSheelPropety.getSheet() != null ? multipleSheelPropety.getSheet() : initSheet;
if(!CollectionUtils.isEmpty(multipleSheelPropety.getData())){
sheet.setClazz(multipleSheelPropety.getData().get(0).getClass());
}
writer.write(multipleSheelPropety.getData(), sheet);
} } catch (FileNotFoundException e) {
log.error("找不到文件或文件路径错误, 文件:{}", filePath);
}finally {
try {
if(writer != null){
writer.finish();
} if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
log.error("excel文件导出失败, 失败原因:{}", e);
}
} } /*********************匿名内部类开始,可以提取出去******************************/ @Data
public static class MultipleSheelPropety{ private List<? extends BaseRowModel> data; private Sheet sheet;
} /**
* 解析监听器,
* 每解析一行会回调invoke()方法。
* 整个excel解析结束会执行doAfterAllAnalysed()方法
*
* @author: chenmingjian
* @date: 19-4-3 14:11
*/
@Getter
@Setter
public static class ExcelListener extends AnalysisEventListener { private List<Object> datas = new ArrayList<>(); /**
* 逐行解析
* object : 当前行的数据
*/
@Override
public void invoke(Object object, AnalysisContext context) {
//当前行
// context.getCurrentRowNum()
if (object != null) {
datas.add(object);
}
} /**
* 解析完所有数据后会调用该方法
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
//解析结束销毁不用的资源
} } /************************匿名内部类结束,可以提取出去***************************/ }

测试类

package com.springboot.utils.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; /**
* @description: 测试类
* @author: chenmingjian
* @date: 19-4-4 15:24
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test { /**
* 读取少于1000行的excle
*/
@org.junit.Test
public void readLessThan1000Row(){
String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
List<Object> objects = ExcelUtil.readLessThan1000Row(filePath);
objects.forEach(System.out::println);
} /**
* 读取少于1000行的excle,可以指定sheet和从几行读起
*/
@org.junit.Test
public void readLessThan1000RowBySheet(){
String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
Sheet sheet = new Sheet(1, 1);
List<Object> objects = ExcelUtil.readLessThan1000RowBySheet(filePath,sheet);
objects.forEach(System.out::println);
} /**
* 读取大于1000行的excle
* 带sheet参数的方法可参照测试方法readLessThan1000RowBySheet()
*/
@org.junit.Test
public void readMoreThan1000Row(){
String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
List<Object> objects = ExcelUtil.readMoreThan1000Row(filePath);
objects.forEach(System.out::println);
} /**
* 生成excle
* 带sheet参数的方法可参照测试方法readLessThan1000RowBySheet()
*/
@org.junit.Test
public void writeBySimple(){
String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
List<List<Object>> data = new ArrayList<>();
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
data.add(Arrays.asList("111","222","333"));
List<String> head = Arrays.asList("表头1", "表头2", "表头3");
ExcelUtil.writeBySimple(filePath,data,head);
} /**
* 生成excle, 带用模型
* 带sheet参数的方法可参照测试方法readLessThan1000RowBySheet()
*/
@org.junit.Test
public void writeWithTemplate(){
String filePath = "/home/chenmingjian/Downloads/测试.xlsx";
ArrayList<TableHeaderExcelProperty> data = new ArrayList<>();
for(int i = 0; i < 4; i++){
TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();
tableHeaderExcelProperty.setName("cmj" + i);
tableHeaderExcelProperty.setAge(22 + i);
tableHeaderExcelProperty.setSchool("清华大学" + i);
data.add(tableHeaderExcelProperty);
}
ExcelUtil.writeWithTemplate(filePath,data);
} /**
* 生成excle, 带用模型,带多个sheet
*/
@org.junit.Test
public void writeWithMultipleSheel(){
ArrayList<ExcelUtil.MultipleSheelPropety> list1 = new ArrayList<>();
for(int j = 1; j < 4; j++){
ArrayList<TableHeaderExcelProperty> list = new ArrayList<>();
for(int i = 0; i < 4; i++){
TableHeaderExcelProperty tableHeaderExcelProperty = new TableHeaderExcelProperty();
tableHeaderExcelProperty.setName("cmj" + i);
tableHeaderExcelProperty.setAge(22 + i);
tableHeaderExcelProperty.setSchool("清华大学" + i);
list.add(tableHeaderExcelProperty);
} Sheet sheet = new Sheet(j, 0);
sheet.setSheetName("sheet" + j); ExcelUtil.MultipleSheelPropety multipleSheelPropety = new ExcelUtil.MultipleSheelPropety();
multipleSheelPropety.setData(list);
multipleSheelPropety.setSheet(sheet); list1.add(multipleSheelPropety); } ExcelUtil.writeWithMultipleSheel("/home/chenmingjian/Downloads/aaa.xlsx",list1); } /*******************匿名内部类,实际开发中该对象要提取出去**********************/ /**
* @description:
* @author: chenmingjian
* @date: 19-4-3 14:44
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class TableHeaderExcelProperty extends BaseRowModel { /**
* value: 表头名称
* index: 列的号, 0表示第一列
*/
@ExcelProperty(value = "姓名", index = 0)
private String name; @ExcelProperty(value = "年龄",index = 1)
private int age; @ExcelProperty(value = "学校",index = 2)
private String school;
} /*******************匿名内部类,实际开发中该对象要提取出去**********************/ }

史上最全的Excel导入导出之easyexcel的更多相关文章

  1. 史上最全的Excel数据编辑处理技巧(转)

    史上最全的数据编辑处理技巧,让你在日常数据分析处理的疯魔状态中解放出来. 一.隐藏行列 “不得了了,Excel出现灵异事件,部分区域消失不见了!”办公室里的一个MM跑过来大声喊叫着,着实吓了俺一跳.待 ...

  2. 史上最全的excel读写技术分享

    目录 简介 导出excel常用的几种方法 POI CSV jxl jxls easyexcel 快速入门 代码解读 总结 常用API 单元格样式 合并单元格 数据样式 多sheet设置 单元格添加超链 ...

  3. Excel导入导出的业务进化场景及组件化的设计方案(上)

    1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...

  4. ASP.NET 之 常用类、方法的超级总结,并包含动态的EXCEL导入导出功能,奉上类库源码

    实用类:UtilityClass 包含如下方法 判断对象是否为空或NULL,如果是空或NULL返回true,否则返回false 验证手机号是否正确 13,15,18 验证邮箱 验证网址 MD5加密,返 ...

  5. java jxl excel 导入导出的 总结(建立超链接,以及目录sheet的索引)

    最近项目要一个批量导出功能,而且要生成一个单独的sheet页,最后后面所有sheet的索引,并且可以点击进入连接.网上搜索了一下,找到一个方法,同时把相关的excel导入导出操作记录一下!以便以后使用 ...

  6. 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发

    [原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文  http: ...

  7. 关于Excel导入导出的用例设计

    目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel ...

  8. .Net魔法堂:史上最全的ActiveX开发教程——部署篇

    一.前言 接<.Net魔法堂:史上最全的ActiveX开发教程——发布篇>,后我们继续来部署吧! 二. 挽起衣袖来部署   ActiveX的部署其实就是客户端安装ActiveX组件,对未签 ...

  9. .Net魔法堂:史上最全的ActiveX开发教程——发布篇

    一. 前言 接着上一篇<.Net魔法堂:史上最全的ActiveX开发教程——开发篇>,本篇讲述如何发布我们的ActiveX. 二.废话少讲,马上看步骤! 1. 打包  C#开发的Activ ...

随机推荐

  1. 华为云计算IE面试笔记-华为云计算解决方案业务迁移支持哪些迁移?有哪些特点?请描述基本的业务交付流程、业务迁移流程和原则。

    1. 迁移场景:华为云计算解决方案按照源端环境来说,支持P2V.V2V(P2V:物理设备(操作系统及其上的应用软件和数据)迁移到华为虚拟化平台.V2V:其他厂商的虚拟化平台迁移到华为虚拟化平台.)以及 ...

  2. 📝 没 2 年 React Native 开发经验,你都遇不到这些坑

    如果你喜欢我的文章,希望点赞 收藏 评论 三连支持一下,谢谢你,这对我真的很重要! React Native 开发时,如果只是写些简单的页面,基本上按着官方文档 reactnative.dev就能写出 ...

  3. unittest基本原理及介绍

    unittest基本原理: unittest是python自带的测试框架,还有一个框架是:pytest,这里简单介绍下unittest模块的简单应用 unittest是python的标准测试库,相比于 ...

  4. Python+requests环境搭建和GET基本用法

    Python+requests环境搭建 首先你得安装Python,然后安装requests模块(第3方模块,安装方法:pip install requests)  基本用法 get 请求(不带参数的) ...

  5. Notepad++离线安装使用Markdown插件

    1.介绍 MarkdownViewerPlusPlus是Notepad++的Markdown插件, 这个Markdown插件可以在Notepad++中实时动态渲染, 可以同步查看使用Markdown的 ...

  6. 踩坑系列《七》解决VMware安装完成之后,不能联网的问题

    成功安装CentOS 6.5 好之后,它是默认并不能联网,这时候得需要对root用户进行网络设置 1.先登录root账户 2.命令行输入以下命令,修改配置文件 vim /etc/sysconfig/n ...

  7. Java实现四大基本排序算法和二分查找

    Java 基本排序算法 二分查找法 二分查找也称为折半查找,是指当每次查询时,将数据分为前后两部分,再用中值和待搜索的值进行比较,如果搜索的值大于中值,则使用同样的方式(二分法)向后搜索,反之则向前搜 ...

  8. 洛谷 P1862 输油管道问题

    题意 题目链接:P1862 输油管道问题 不难看出每个油井的 \(x\) 坐标是没用的,所以问题转化为如下. 代数意义:给出 \(n\) 个数 \(y_1,y_2,\ldots,y_n\),找一个数 ...

  9. jmx_prometheus_javaagent+prometheus+alertmanager+grafana完成容器化java监控告警(二)

    一.拓扑图 二.收集数据 2.1前期准备 创建共享目录,即为了各节点都创建该目录,有两个文件,做数据共享 /home/target/prom-jvm-demo 1.下载文件 jmx_prometheu ...

  10. SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean

    SpringBoot下使用AspectJ(CTW)下不能注入SpringIOC容器中的Bean 在SpringBoot中开发AspectJ时,使用CTW的方式来织入代码,由于采用这种形式,切面Bean ...