1.POI使用

1.1 什么是POI

POI简介(Apache POI),Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

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

1.2 官网

http://poi.apache.org/

官网可以找到文档和每个版本的下载地址

2.xls写-03和07

2.1、创建项目

1、创建一个普通的maven项目

项目名:excel_poi

2、pom中引入xml相关依赖

<dependencies>
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency> <!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency> <!--日期格式化工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency> <!--test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

2.2、xls写-03和07的区别

区别1.格式不一样,03是xls,07是xlsx。

区别2:别的没啥区别。

1、03

public class ExcelWriteTest {

    @Test
public void testWrite03() throws IOException { // 创建新的Excel 工作簿
Workbook workbook = new HSSFWorkbook(); // 在Excel工作簿中建一工作表,其名为缺省值 Sheet0
//Sheet sheet = workbook.createSheet(); // 如要新建一名为"会员登录统计"的工作表,其语句为:
Sheet sheet = workbook.createSheet("会员登录统计"); // 创建行(row 1)
Row row1 = sheet.createRow(0); // 创建单元格(col 1-1)
Cell cell11 = row1.createCell(0);
cell11.setCellValue("今日人数"); // 创建单元格(col 1-2)
Cell cell12 = row1.createCell(1);
cell12.setCellValue(666); // 创建行(row 2)
Row row2 = sheet.createRow(1); // 创建单元格(col 2-1)
Cell cell21 = row2.createCell(0);
cell21.setCellValue("统计时间"); //创建单元格(第三列)
Cell cell22 = row2.createCell(1);
String dateTime = new DateTime().toString("yyyy-MM-dd HH:mm:ss");
cell22.setCellValue(dateTime); // 新建一输出文件流(注意:要先创建文件夹)
FileOutputStream out = new FileOutputStream("d:/excel-poi/test-write03.xls");
// 把相应的Excel 工作簿存盘
workbook.write(out);
// 操作结束,关闭文件
out.close(); System.out.println("文件生成成功");
}
}

2 、07

@Test
public void testWrite07() throws IOException { // 创建新的Excel 工作簿
Workbook workbook = new XSSFWorkbook(); ...... // 新建一输出文件流(注意:要先创建文件夹)
FileOutputStream out = new FileOutputStream("d:/excel-poi/test-write07.xlsx"); ......
}

2.3、大文件写-HSSF、XSSF和SXSSF

1、使用HSSF

缺点:最多只能处理65536行,否则会抛出异常

java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)

优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快

@Test
public void testWrite03BigData() throws IOException {
//记录开始时间
long begin = System.currentTimeMillis(); //创建一个SXSSFWorkbook
Workbook workbook = new HSSFWorkbook(); //创建一个sheet
Sheet sheet = workbook.createSheet(); //xls文件最大支持65536行
for (int rowNum = 0; rowNum < 65536; rowNum++) {
//创建一个行
Row row = sheet.createRow(rowNum);
for (int cellNum = 0; cellNum < 10; cellNum++) {//创建单元格
Cell cell = row.createCell(cellNum);
cell.setCellValue(cellNum);
}
} System.out.println("done");
FileOutputStream out = new FileOutputStream("d:/excel-poi/test-write03-bigdata.xls");
workbook.write(out);
// 操作结束,关闭文件
out.close(); //记录结束时间
long end = System.currentTimeMillis();
System.out.println((double)(end - begin)/1000);
}

2、使用XSSF

缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条

优点:可以写较大的数据量,如20万条

@Test
public void testWrite07BigData() throws IOException {
//记录开始时间
long begin = System.currentTimeMillis(); //创建一个XSSFWorkbook
Workbook workbook = new XSSFWorkbook(); ...... FileOutputStream out = new FileOutputStream("d:/excel-poi/test-write07-bigdata.xlsx"); ......
}

3、使用SXSSF

优点:可以写非常大的数据量,如100万条甚至更多条,写数据速度快,占用更少的内存

注意:

过程中会产生临时文件,需要清理临时文件

默认由100条记录被保存在内存中,如果查过这数量,则最前面的数据被写入临时文件

如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook(数量)

@Test
public void testWrite07BigDataFast() throws IOException {
//记录开始时间
long begin = System.currentTimeMillis(); //创建一个SXSSFWorkbook
Workbook workbook = new SXSSFWorkbook(); ...... FileOutputStream out = new FileOutputStream("d:/excel-poi/test-write07-bigdata-fast.xlsx");
workbook.write(out);
// 操作结束,关闭文件
out.close(); //清除临时文件
((SXSSFWorkbook)workbook).dispose(); //记录结束时间
long end = System.currentTimeMillis();
System.out.println((double)(end - begin)/1000);
}

SXSSFWorkbook-来至官方的解释:实现“BigGridDemo”策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。

请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注释......仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。

3、xls读-03和07

1、03

package com.atguigu.excelpoi;

public class ExcelReadTest {

    @Test
public void testRead03() throws Exception{ InputStream is = new FileInputStream("d:/excel-poi/商品表-03.xls"); Workbook workbook = new HSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0); // 读取第一行第一列
Row row = sheet.getRow(0);
Cell cell = row.getCell(0); // 输出单元内容
System.out.println(cell.getStringCellValue()); // 操作结束,关闭文件
is.close();
}
}

2、07

@Test
public void testRead07() throws Exception{ InputStream is = new FileInputStream("d:/excel-poi/商品表-07.xlsx"); Workbook workbook = new XSSFWorkbook(is); ......
}

3、读取不同类型的数据

1、读取不同的数据类型

@Test
public void testCellType() throws Exception { InputStream is = new FileInputStream("d:/excel-poi/会员消费商品明细表.xls");
Workbook workbook = new HSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0); // 读取标题所有内容
Row rowTitle = sheet.getRow(0);
if (rowTitle != null) {// 行不为空
// 读取cell
int cellCount = rowTitle.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cellCount; cellNum++) {
Cell cell = rowTitle.getCell(cellNum);
if (cell != null) { int cellType = cell.getCellType();
String cellValue = cell.getStringCellValue();
System.out.print(cellValue + "|");
}
}
System.out.println();
} // 读取商品列表数据
int rowCount = sheet.getPhysicalNumberOfRows();
for (int rowNum = 1; rowNum < rowCount; rowNum++) { Row rowData = sheet.getRow(rowNum);
if (rowData != null) {// 行不为空 // 读取cell
int cellCount = rowTitle.getPhysicalNumberOfCells();
for (int cellNum = 0; cellNum < cellCount; cellNum++) { System.out.print("【" + (rowNum + 1) + "-" + (cellNum + 1) + "】"); Cell cell = rowData.getCell(cellNum);
if (cell != null) { int cellType = cell.getCellType(); //判断单元格数据类型
String cellValue = "";
switch (cellType) {
case HSSFCell.CELL_TYPE_STRING://字符串
System.out.print("【STRING】");
cellValue = cell.getStringCellValue();
break; case HSSFCell.CELL_TYPE_BOOLEAN://布尔
System.out.print("【BOOLEAN】");
cellValue = String.valueOf(cell.getBooleanCellValue());
break; case HSSFCell.CELL_TYPE_BLANK://空
System.out.print("【BLANK】");
break; case HSSFCell.CELL_TYPE_NUMERIC:
System.out.print("【NUMERIC】");
//cellValue = String.valueOf(cell.getNumericCellValue()); if (HSSFDateUtil.isCellDateFormatted(cell)) {//日期
System.out.print("【日期】");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
} else {
// 不是日期格式,则防止当数字过长时以科学计数法显示
System.out.print("【转换成字符串】");
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cellValue = cell.toString();
}
break; case Cell.CELL_TYPE_ERROR:
System.out.print("【数据类型错误】");
break;
} System.out.println(cellValue);
}
}
}
} is.close();
}

2、计算公式

@Test
public void testFormula() throws Exception{ InputStream is = new FileInputStream("d:/excel-poi/计算公式.xls"); Workbook workbook = new HSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0); // 读取第五行第一列
Row row = sheet.getRow(4);
Cell cell = row.getCell(0); //公式计算器
FormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook); // 输出单元内容
int cellType = cell.getCellType();
switch (cellType) {
case Cell.CELL_TYPE_FORMULA://2 //得到公式
String formula = cell.getCellFormula();
System.out.print(formula); CellValue evaluate = formulaEvaluator.evaluate(cell);
//String cellValue = String.valueOf(evaluate.getNumberValue());
String cellValue = evaluate.formatAsString();
System.out.println(cellValue); break;
}
}

4.EasyExcel使用

4.1、Excel导入导出的应用场景

1、数据导入:减轻录入工作量

2、数据导出:统计信息归档

3、数据传输:异构系统之间数据传输

4.2、EasyExcel简介

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

5.EasyExcel写入

5.1 创建项目,实现EasyExcel对Excel写操作

1、创建一个普通的maven项目

项目名:excel-easydemo

2、pom中引入xml相关依赖

<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>

3、创建实体类

设置表头和添加的数据字段

import com.alibaba.excel.annotation.ExcelProperty;

//设置表头和添加的数据字段
public class DemoData {
//设置表头名称
@ExcelProperty("学生编号")
private int sno; //设置表头名称
@ExcelProperty("学生姓名")
private String sname; public int getSno() {
return sno;
} public void setSno(int sno) {
this.sno = sno;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} @Override
public String toString() {
return "DemoData{" +
"sno=" + sno +
", sname='" + sname + '\'' +
'}';
}
}

4、实现写操作

(1)创建方法循环设置要添加到Excel的数据

//循环设置要添加的数据,最终封装到list集合中
private static List<DemoData> data() {
List<DemoData> list = new ArrayList<DemoData>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setSno(i);
data.setSname("张三"+i);
list.add(data);
}
return list;
}

(2)实现最终的添加操作(写法一)

public static void main(String[] args) throws Exception {
// 写法1
String fileName = "F:\\11.xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, DemoData.class).sheet("写入方法一").doWrite(data());
}

(3)实现最终的添加操作(写法二)

public static void main(String[] args) throws Exception {
// 写法2,方法二需要手动关闭流
String fileName = "F:\\112.xlsx";
// 这里 需要指定写用哪个class去写
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("写入方法二").build();
excelWriter.write(data(), writeSheet);
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
}

6.EasyExcel读取

6.1、实现EasyExcel对Excel读操作

1、创建实体类

import com.alibaba.excel.annotation.ExcelProperty;
public class ReadData {
//设置列对应的属性
@ExcelProperty(index = 0)
private int sid; //设置列对应的属性
@ExcelProperty(index = 1)
private String sname; public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
@Override
public String toString() {
return "ReadData{" +
"sid=" + sid +
", sname='" + sname + '\'' +
'}';
}
}

2、创建读取操作的监听器

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; //创建读取excel监听器
public class ExcelListener extends AnalysisEventListener<ReadData> { //创建list集合封装最终的数据
List<ReadData> list = new ArrayList<ReadData>(); //一行一行去读取excle内容
@Override
public void invoke(ReadData user, AnalysisContext analysisContext) {
System.out.println("***"+user);
list.add(user);
} //读取excel表头信息
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("表头信息:"+headMap);
} //读取完成后执行
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}

3、调用实现最终的读取

   public static void main(String[] args) throws Exception {

        // 写法1:
String fileName = "F:\\01.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(fileName, ReadData.class, new ExcelListener()).sheet().doRead(); // 写法2:
InputStream in = new BufferedInputStream(new FileInputStream("F:\\01.xlsx"));
ExcelReader excelReader = EasyExcel.read(in, ReadData.class, new ExcelListener()).build();
ReadSheet readSheet = EasyExcel.readSheet(0).build();
excelReader.read(readSheet);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
}

POI和EasyExcel的使用的更多相关文章

  1. POI和easyExcel

    POI与easyExcel 这个东西一般用来做什么? 将用户信息导出为Excel表格(导出数据) 将Excel表中的信息录入到网站数据库(比如一些习题上传) 在开发过程中会遇到对Excel的处理,比如 ...

  2. Java实现导入导出Excel:POI和EasyExcel

    文章与CSDN同步,欢迎访问:https://blog.csdn.net/qq_40280582/article/details/107300081 代码地址:https://gitee.com/il ...

  3. EasyExcel的基本使用方法

    在Java语言领域,说到Excel处理工具,大家首先想到的可能是阿帕奇的poi,poi在处理数据量不大的excel文件上确实非常强大,但是随着后来excel从03(一个excel文件中最多有65536 ...

  4. EasyExcel完成excel文件的导入导出

    简介 常见的Excel分析框架有Apache poi 和EasyExcel, poi在另一篇已经介绍过了,详情可以看[https://www.cnblogs.com/jasmine-e/p/16064 ...

  5. SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  6. 搭建SSM基础环境>基于idea

    目录 搭建SSM基础环境 创建一个Web项目 导入所需要的jar包 在项目目录下创建一个Resources文件夹并设置为类路径 在src目录下创建项目的初始文件夹目录 在resources文件夹下创建 ...

  7. easyExcel+poi导出Excel出现乱码

    这种问题肯定是浏览器编码问题,修改官方给的util就好了

  8. 阿里巴巴excel工具easyexcel 助你快速简单避免OOM

    Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有 ...

  9. easyExcel导出excel的简单使用

    easyExcel导出excel的简单使用 Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定 ...

随机推荐

  1. PythonCrashCourse 第四章习题

    Python 从入门到实践第四章习题 4.1想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for 循环将每种比萨的名称都打印出来 修改这个for 循环,使其打印包含比萨名称的句子,而不仅仅 ...

  2. linux root用户下没有.ssh目录

    .ssh 是记录密码信息的文件夹,如果没有登录过root的话,就没有 .ssh 文件夹,因此登录 localhost ,并输入密码就会生成了 ssh localhost

  3. Training spiking neural networks for reinforcement learning

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 原文链接:https://arxiv.org/pdf/2005.05941.pdf Contents: Abstract Introduc ...

  4. linux计算命令

    1.在lammps中通过car文件导出data文件 (进入工作目录xxx cd xxx/ msi2lmp.exe xxx -class I -frc clayff -i -ignore > ou ...

  5. in文件注意事项及详细解释(转载)

    转载自:https://www.cnblogs.com/sysu/p/10817315.html  和   https://www.cnblogs.com/panscience/p/4953940.h ...

  6. elementUI的隐藏组件el-scroll--滚动条

    由于原生的滚动条存在兼容性问题并且样式不是太美观,在项目中经常使用的是elementui,发现elementui中有个隐藏的组件,就是element官网使用的滚动条,可以优化滚动条样式.鼠标经过的时候 ...

  7. 23种设计模式 - 接口隔离(Facade - Proxy - Mediator - Adapter)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 接口隔离 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接( ...

  8. PostgreSQL在不同的表空间移动数据文件

    一.背景 在工作中,可能会遇到将表从一个表空间移动另一个表空间.例如 * 对数据进行冷处理 * 表空间所在的磁盘空间不足 * 建表时分配错了表空间 以上等等,可能需要你将一个表移动表空间. 二.表空间 ...

  9. 记录laravelchina中的微信小程序教程的npm install安装报错

    npm安装报错时 npm ERR! code EIOnpm ERR! syscall symlinknpm ERR! path ../@babel/parser/bin/babel-parser.js ...

  10. Android开发之java代码中获取当前系统的时间工具类

    /** * 获取当前时间 * * @return */ public String getTime() { Date date = new Date();// 创建一个时间对象,获取到当前的时间 Si ...