喝水不忘挖井人,感谢阿里巴巴项目组提供了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. Decorator装饰器模式个人理解

    对于装饰器模式,其主要是为了:在不改变本体特征的情况下,对其进行包装.装饰,目的是为了补充.扩展.增强其功能. 有三个原则: 不能改变本体的特征 要对本体的功能进行扩展 装饰器脱离了本体则没有任何含义 ...

  2. c++ class里面成员和分配内存问题

    慢慢开始学c++啦,记录学习的大体过程 class中神奇的内存(sizeof) 1.内存补齐 便于管理类(生成的对象)的内存,类总内存总是为最大成员字节大小的倍数,不足的会进行内存补齐 类的整体内存就 ...

  3. 获取HTML网页中option标签元素的值

    在进行表单元素的操作时,难免会遇到对option元素的挑选,下面的示例代码能够很好的获取到你option元素选择的值,如果要传递给后端,可通过ajax或者其他方式传递即可. 示例代码 <!doc ...

  4. Mac里存储空间不足,该怎么删垃圾数据?

    说明:在mac设备运行一段时间后,电脑空间很小了,对于开发者来说,清清Xcode缓存,腾出几十G的空间还是有可能的.在升级Xcode适配新系统.新手机也是得给电脑减减压. 一.Xcode缓存文件(co ...

  5. 阿里限流神器Sentinel夺命连环 17 问?

    1.前言 这是<spring Cloud 进阶>专栏的第五篇文章,这篇文章介绍一下阿里开源的流量防卫兵Sentinel,一款非常优秀的开源项目,经过近10年的双十一的考验,非常成熟的一款产 ...

  6. 在昨天夜黑风高的晚上,我偷了隔壁老王的Python入门课件,由浅入深堪称完美!

    隔壁老王是一个资深码农,就业教育事业的秃顶之才昨天我下楼打酱油,看他迎面走来,满目春光我好奇的问道:老王,有什么好事,隔壁小花叫你上门了吗?老王:秘密!!我心想:哎呦~不错啊半晚之时,连猫狗都睡着了, ...

  7. RPAaaS是什么?为何能够推进RPA人人可用?

    RPAaaS是什么?为何能够推进RPA人人可用? 助力中小企业快速实现自动化,RPAaaS加速"RPA人人可用"时代到来 相对传统RPA拥有更多优势,PRAaaS为RPA行业带来更 ...

  8. Java(31)泛型和可变参数

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228443.html 博客主页:https://www.cnblogs.com/testero ...

  9. 结对编程——带UI的小初高数学学习软件

    一.简介 本次项目要求: 1.所有功能通过图形化界面操作,可以是桌面应用,可以是网站(编程语言和技术不限): 2.用户注册功能.用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册: ...

  10. vue3.x新特性之setup函数,看完就会用了

    最近有小伙伴跟我聊起setup函数,因为习惯了vue2.x的写法导致了,setup用起来觉得奇奇怪怪的,在一些api混编的情况下,代码变得更加混乱了,个人觉得在工程化思想比较强的团队中使用setup确 ...