Java操作Excel文件解析与读写方法详解

目录
  • 一、概述
  • 二、Apache POI
  • 三、XSSF解析Excel文件
    • 1.Workbook(Excel文件)
    • 2.Sheet(工作簿)
    • 3.Row(数据行)
    • 4.Cell(单元格)
  • 四、超大Excel文件读写
    • 1.使用POI写入
    • 2.使用EasyExcel

一、概述

在应用程序的开发过程中,经常需要使用 Excel 文件来进行数据的导入或导出。所以,在通过Java语言实现此 类需求的时候,往往会面临着Excel文件的解析(导入)或生成(导出)。

在Java技术生态圈中,可以进行Excel文件处理的主流技术包括: Apache POI 、 JXL 、 Alibaba EasyExcel 等。

二、Apache POI

Apache POI 是用 Java 编写的免费开源的跨平台的 Java API , Apache POI 提供 给 Java 程序对 Microsoft Office 格式档案进行读写功能的 API 开源类库。

它分别提供对不同格式文件的解析:

  • HSSF - 提供读写Microsoft Excel格式档案的功能。
  • XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
  • HWPF - 提供读写Microsoft Word格式档案的功能。
  • HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
  • HDGF - 提供读写Microsoft Visio格式档案的功能。

三、XSSF解析Excel文件

HSSF 用于解析旧版本(*.xls)Excel文件,由于旧版本的Excel文件只能存在65535行数据,所以目前已经不常用。所以 目前主要采用 XSSF 进行新版本(*.xlsx)Exce文件的解析。

1.Workbook(Excel文件)

Workbook 接口代表一个 Excel 文件,用于创建或加载(解析) Excel 文件。常见实现类是 XSSFWorkbook 。

创建Excel文件

try (Workbook workbook = new XSSFWorkbook();
				FileOutputStream fos = new FileOutputStream("c:\\test\\temp.xlsx")) {
    workbook.write(fos);
} catch (IOException e) {
    e.printStackTrace();
}

解析Excel文件

// 输入流
FileInputStream fis = new FileInputStream("c:\\test\\1627356554991.xlsx");
// Excel文件对象
Workbook workbook = new XSSFWorkbook(fis);

2.Sheet(工作簿)

通过 Workbook 来进行工作簿 Sheet 对象的获取或创建

创建工作簿

// 按照默认名称创建工作簿
Sheet sheet1 = workbook.createSheet();
// 按照自定义名称创建工作簿
Sheet sheet2 = workbook.createSheet("自定义工作簿2");

获取工作簿

// 按照工作簿下标获取Sheet
Sheet sheet01 = workbook.getSheetAt(0);
// 按照工作簿名称获取Sheet
Sheet sheet02 = workbook.getSheet("Sheet0");

获取工作簿的数量

int n = workbook.getNumberOfSheets();

3.Row(数据行)

通过 Sheet 来进行数据行 Row 对象的获取或创建

创建数据行

Row row = sheet.createRow(0);

获取首行下标和尾行下标

int first = sheet.getFirstRowNum();
int last = sheet.getLastRowNum();

根据下标获取指定行

Row row = sheet.getRow(0);

遍历所有行

for(Row row : sheet) {
    System.out.println(row);
}

遍历指定区域行

for (int i = 1; i <= sheet.getLastRowNum(); i++) {
    Row row = sheet.getRow(i);
    System.out.println(row);
}

4.Cell(单元格)

通过 Row 来进行单元格 Cell 对象的获取或创建。

创建单元格

Cell cell0 = row.createCell(0);

设置单元格值

cell0.setCellValue(UUID.randomUUID().toString());

根据下标获取单元格

Cell cell = row.getCell(1);

遍历所有单元格

for(Cell cell : row) {}

获取单元格的类型

CellType type = cell.getCellType();

设置单元格样式

// 创建单元格样式
DataFormat dataFormat = workbook.createDataFormat();
Short formatCode = dataFormat.getFormat("yyyy-MM-dd HH:mm:ss");
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(formatCode);
// 为当前行创建单元格
Cell cell1 = row.createCell(1);
cell1.setCellStyle(cellStyle); // 设置单元格样式
cell1.setCellValue(new Date()); // 保存当前日期时间至本单元格

设置单元格对齐

// 创建单元格样式
CellStyle cellStyle = workbook.createCellStyle();
//设置单元格的水平对齐类型。 此时水平居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);
// 设置单元格的垂直对齐类型。 此时垂直靠底边
cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);

四、超大Excel文件读写

1.使用POI写入

使用 SXSSFWorkbook 进行写入,通过设置 SXXFWorkbook 的构造参数,可以设置每次在内存中保持的行 数,当达到这个值的时候,那么会把这些数据 flush 到磁盘上,这样就不会出现内存不够的情况。

try (Workbook workbook = new SXSSFWorkbook(100);
				FileOutputStream fos = new FileOutputStream("c:\\test\\temp.xlsx")) {
    Sheet sheet1 = workbook.createSheet();
    for (int i = 0; i <= 1000000; i++) {
        Row row = sheet1.createRow(i);
        Cell cell0 = row.createCell(0);
        cell0.setCellValue(UUID.randomUUID().toString());
        Cell cell1 = row.createCell(1);
        cell1.setCellValue(new Date());
    }
    workbook.write(fos);
} catch (IOException e) {
    e.printStackTrace();
}

但是读取超大Excel时POI会把文件的所有内容都加载到内存中,很容易占用大量内存;甚至发生out of memory异常。

2.使用EasyExcel

  • Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。
  • EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
  • EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理。

例:

//准备实体类
public class Order {
    @ExcelProperty("订单编号")
	private String orderId; // 订单编号
    @ExcelProperty("支付金额")
	@NumberFormat("¥#,###")
	private Double payment; // 支付金额
    @ExcelProperty(value = "创建日期",converter = LocalDateTimeConverter.class)
	private LocalDateTime creationTime; // 创建时间
	public Order() {
		this.orderId = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss"))
				+ UUID.randomUUID().toString().substring(0, 5);
		this.payment = Math.random() * 10000;
		this.creationTime = LocalDateTime.now();
	}
	public String getOrderId() {
		return orderId;
	}
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}
	public Double getPayment() {
		return payment;
	}
	public void setPayment(Double payment) {
		this.payment = payment;
	}
	public LocalDateTime getCreationTime() {
		return creationTime;
	}
	public void setCreationTime(LocalDateTime creationTime) {
		this.creationTime = creationTime;
	}
	@Override
	public String toString() {
		return "Order [orderId=" + orderId + ", payment=" + payment + ", creationTime=" + creationTime + "]";
	}
}
//准备Converter转换类
public class LocalDateTimeConverter implements Converter<LocalDateTime> {
	@Override
	public Class<LocalDateTime> supportJavaTypeKey() {
		return LocalDateTime.class;
	}
	@Override
	public CellDataTypeEnum supportExcelTypeKey() {
		return CellDataTypeEnum.STRING;
	}
	@Override
	public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
			GlobalConfiguration globalConfiguration) {
		return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
	}
	@Override
	public CellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
			GlobalConfiguration globalConfiguration) {
		return new CellData<>(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
	}
}

写入数据

import java.util.ArrayList;
import java.util.List;
import com.alibaba.excel.EasyExcel;
public class Demo01 {
	public static void main(String[] args) {
		long begin = System.currentTimeMillis();
		// 写入100w
        EasyExcel.write("D:\\java.workspace\\1000W.xlsx", Order.class)
                 .sheet("订单列表")
                 .doWrite(data());
        long end = System.currentTimeMillis();
		System.out.println("共耗时"+(end-begin)+"毫秒");
    }
    // 创建100w条订单数据
    private static List<Order> data() {
        List<Order> list = new ArrayList<Order>();
        for (int i = 0; i < 1000000; i++) {
            list.add(new Order());
        }
        return list;
    }
}

读取数据

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
public class Demo02 {
	public static void main(String[] args) {
		//用于保存读取到的结果
		List<Order> orderList = new ArrayList<Order>();
		//读取
		EasyExcel.read("D:\\java.workspace\\1000W.xlsx", Order.class,new AnalysisEventListener<Order>() {
		    @Override
		    public void invoke(Order order, AnalysisContext arg1) {
		        // 读取每条数据
		        orderList.add(order);
		    }
		    @Override
		    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
		        // 读取到列头
		        System.out.println(headMap);
		    }
		    @Override
		    public void doAfterAllAnalysed(AnalysisContext arg0) {
		        // 读取完毕
		        System.out.println("END");
		    }
		}).sheet().doRead();
		//遍历
		for(Order order : orderList) {
			System.out.println(order);
		}
	}
}

到此这篇关于Java操作Excel文件解析与读写方法详解的文章就介绍到这了,更多相关Java Excel文件解析内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java利用easyexcel实现导入与导出功能

    目录 前言 1先添加依赖 2批量插入数据 3创建需要导出数据实体类 4创建一个类ExcelListener 5实现下载excel 6控制器添加我们的导入操作代码 7导出效果如图 8导入直接调用 前言 poi的解析方式是dom解析,把结果一次都读入内存操作,这样的操作平时是不会有问题的,但是并发量上来的时候就会出现OOM,EasyExcel,底层对象其实还是使用poi包的那一套.它只是将poi包的一部分抽了出来,摒弃掉了大部分业务相关的属性.由于它关注的业务是导入导出这一块,所以在处理大数据量的导

  • Java使用easyExcel实现导入功能

    今天带来的是esayExcel的简单使用小结,一个高效的Excel的处理框架 临时接到领导要求需要做一个Excel导入功能,于是发挥我的特长——面向百度编程. 在百度搜索了一圈都是POi导入方式,找到一个看着还算靠谱的demo,这种方式在我看来相当的笨重,读取到Excel内容后逐个进行判断.折腾了一个上午,代码像是一个年迈的老人-岿然不动,为我的菜感到汗颜. 经过公司经验丰富的老人的指导,使用阿里巴巴开源的easyExcel导入方式使用很便捷,更重要的是快,十分钟就完成了整个导入过程的开发. 书

  • Java 将Excel转为UOS的操作方法

    目录 [导入jar包] [Excel转UOS] 以.uos为后缀的文件,表示Uniform Office Spreadsheet文件,是一种国产的办公文件格式,该格式以统一办公格式(UOF)创建,使用XML和压缩保存电子表格.既有的Excel表格文件,可以通过格式转换的方式转换为UOS格式,本文将对此作相关介绍. [导入jar包] 使用jar包:Spire.Xls.jar version: 12.7.4 导入方法1:手动下载 jar到本地,解压,然后找到lib文件夹下的Spire.Xls.jar

  • Java利用EasyExcel读取写入Excel详情

    目录 EasyExcel介绍 为什么使用EasyExcel? 封装使用 例子 EasyExcel介绍 EasyExcel是一个基于Java的.快速.简洁.解决大文件内存溢出的Excel处理工具.他能让你在不用考虑性能.内存的等因素的情况下,快速完成Excel的读.写等功能. 为什么使用EasyExcel? Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但PO

  • Java使用POI实现导出Excel的方法详解

    目录 一.前景 二.概念 2.1. 简介 2.2.Excel版本和相关对象 2.3.WorkBook 2.4.POI依赖 三.POI - 写 3.1.代码示例 3.2. 性能对比 3.3. 测试rowAccessWindowSize 3.4. 导出Excel样式设置 四.POI - 读 4.1.代码示例 4.2.读取不同的数据类型 4.3.读取公式 五.POI - 遇到的坑 一.前景 在项目开发中往往需要使用到Excel的导入和导出,导入就是从Excel中导入到DB中,而导出就是从DB中查询数据

  • Java实现自定义Excel数据排序的方法详解

    目录 1.引入jar包 2.自定义排序 通常,我们可以在Excel中对指定列数据执行升序或者降序排序,排序时可依据单元格中的数值.单元格颜色.字体颜色或图标等.在需要自定义排序情况下,我们也可以自行根据排序需要编辑数据排列顺序.本文,将通过Java应用程序来实现如何自定义排序. 1.引入jar包 使用jar包:Spire.Xls.jar version: 12.8.4 导入方法1:手动下载jar到本地,解压,然后找到lib文件夹下的Spire.Xls.jar文件.然后在IDEA中打开“Proje

  • Java操作Excel文件解析与读写方法详解

    目录 一.概述 二.Apache POI 三.XSSF解析Excel文件 1.Workbook(Excel文件) 2.Sheet(工作簿) 3.Row(数据行) 4.Cell(单元格) 四.超大Excel文件读写 1.使用POI写入 2.使用EasyExcel 一.概述 在应用程序的开发过程中,经常需要使用 Excel 文件来进行数据的导入或导出.所以,在通过Java语言实现此 类需求的时候,往往会面临着Excel文件的解析(导入)或生成(导出). 在Java技术生态圈中,可以进行Excel文件

  • Android平台基于Pull方式对XML文件解析与写入方法详解

    本文详细讲述了Android平台基于Pull方式对XML文件解析与写入方法.分享给大家供大家参考,具体如下: XML技术在跨平台的情况下的数据交互中得到了广泛的应用,假如我们需要开发一个Android应用程序,需要同服务器端进行数据交互,通过XML文件可以很方便的在Android平台和服务器之间进行数据传输,具体实现涉及到对XML文件进行解析及写入的技术.本文实现在Android平台上基于Pull方式对XML文件解析的技术. XmlPullParser是一个Java实现的开源API包(源码下载地

  • java 使用idea将工程打成jar并创建成exe文件类型执行的方法详解

    第一部分: 使用idea 打包工程jar 1.准备好一份 开发好的 可执行的 含有main方法的 工程. 例如:我随便写的main方法 public static void main(String[] args) throws IOException { Properties properties = System.getProperties(); String osName = properties.getProperty("os.name"); System.out.println

  • Java Spring MVC 上传下载文件配置及controller方法详解

    下载: 1.在spring-mvc中配置(用于100M以下的文件下载) <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <!--配置下载返回类型--> <bean class="or

  • python文件处理fileinput使用方法详解

    这篇文章主要介绍了python文件处理fileinput使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.介绍 fileinput模块可以对一个或多个文件中的内容进行迭代.遍历等操作,我们常用的open函数是对一个文件进行读写操作. fileinput模块的input()函数比open函数更高效和好用,体现在: input()函数生成一个迭代器,保证了在遇到大文件的读取时不会占用太大的内存. 用fileinput对文件进行循环遍历

  • java中压缩文件并下载的实例详解

    当我们对一些需要用到的资料进行整理时,会发现文件的内存占用很大,不过是下载或者存储,都不是很方便,这时候我们会想到把文件变成zip格式,即进行压缩.在正式开始压缩和下载文件之前,我们可以先对zip的格式进行一个了解,然后再就具体的方法给大家带来分享. 1.ZIP文件格式 [local file header + file data + data descriptor]{1,n} + central directory + end of central directory record 即 [文件

  • Java JWT实现跨域身份验证方法详解

    目录 1.JWT简介 2.JWT的结构 2.1 头部(header) 2.2 载荷(payload) 2.3 签证(signature) 3.JWT的原则 4.JWT的用法 5.JWT的问题和趋势 6.整合JWT令牌 6.1 在模块中添加jwt工具依赖 6.2 创建JWT工具类 1.JWT简介 JWT(JSON Web Token)是目前流行的跨域认证解决方案,是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信

  • SpringBoot整合MinIO实现文件上传的方法详解

    目录 前言 1. MinIO 简介 2. MinIO 安装 3. 整合 Spring Boot 4. 配置nginx 5. 小结 前言 现在 OSS 服务算是一个基础服务了,很多云服务厂商都有提供这样的服务,价格也不贵,松哥自己的网站用的就是类似的服务. 不过对于中小公司来说,除了购买 OSS 服务之外,也可以自己搭建专业的文件服务器,自己搭建专门的文件服务器的话,曾经比较专业的做法是 FastDFS,松哥之前也专门为之录过视频发在 B 站上,感兴趣的小伙伴可以自行查看.不过 FastDFS 搭

  • java 中Excel转shape file的实例详解

    java  中Excel转shape file的实例详解 概述: 本文讲述如何结合geotools和POI实现Excel到shp的转换,再结合前文shp到geojson数据的转换,即可实现用户上传excel数据并在web端的展示功能. 截图: 原始Excel文件 运行耗时 运行结果 代码: package com.lzugis.geotools; import com.lzugis.CommonMethod; import com.vividsolutions.jts.geom.Coordina

  • Android中gson、jsonobject解析JSON的方法详解

    JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

随机推荐