一峰说:POI技术和easyExcel如何快速使用操作excel

编程入门 行业动态 更新时间:2024-10-24 08:19:16

一峰说:POI技术和easyExcel如何<a href=https://www.elefans.com/category/jswz/34/1771431.html style=快速使用操作excel"/>

一峰说:POI技术和easyExcel如何快速使用操作excel

POI定义

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

HSSF - 提供读写Microsoft Excel格式档案的功能。

XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。

HWPF - 提供读写Microsoft Word格式档案的功能。

HSLF - 提供读写Microsoft PowerPoint格式档案的功能。

HDGF - 提供读写Microsoft Visio格式档案的功能。

这里有HSSF和XSSF

POI使用操作excel

路径要自己注意一下,点项目名然后选择绝对路径,这样也许比较好生成出来的文件
1.新建一个idea项目

2.导入依赖

<!--        xls03--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency>
<!--        xlsx07--><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><!--测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>

分为03版(xls)和07版(xlsx)
这里看方法名区分

//写的操作即是写入文件信息或者产出excel文件
//文件名ExcelWriteTest.java
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.Test;import java.io.FileOutputStream;
import java.io.IOException;public class ExcelWriteTest {String PATH = "G:\\大三\\下学期\\一峰说java\\yifeng-poi";//03版本@Testpublic void testWrite03() throws IOException {//1.创建一个工作簿Workbook workbook = new HSSFWorkbook();//2.创建一个工作表Sheet sheet = workbook.createSheet("一峰粉丝统计表");//3.创建一个行   (1,1)Row row1 = sheet.createRow(0);//4.创建一个单元格Cell cell11 = row1.createCell(0);cell11.setCellValue("今日新增粉丝");//(1,2)Cell cell12 = row1.createCell(1);cell12.setCellValue(666);//(2,1)Row row2 = sheet.createRow(1);Cell cell21 = row2.createCell(0);cell21.setCellValue("统计时间");//(2,2)Cell cell22 = row2.createCell(1);cell22.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));//生成一张表(IO 流)   03版本就是使用xls结尾FileOutputStream fileOutputStream = new FileOutputStream(PATH + "一峰粉丝统计表03.xls");workbook.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("一峰粉丝统计表03.xls生成完毕");}//07版本@Testpublic void testWrite07() throws IOException {//1.创建一个工作簿Workbook workbook = new XSSFWorkbook();//2.创建一个工作表Sheet sheet = workbook.createSheet("一峰粉丝统计表");//3.创建一个行   (1,1)Row row1 = sheet.createRow(0);//4.创建一个单元格Cell cell11 = row1.createCell(0);cell11.setCellValue("今日新增粉丝");//(1,2)Cell cell12 = row1.createCell(1);cell12.setCellValue(666);//(2,1)Row row2 = sheet.createRow(1);Cell cell21 = row2.createCell(0);cell21.setCellValue("统计时间");//(2,2)Cell cell22 = row2.createCell(1);cell22.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));//生成一张表(IO 流)   03版本就是使用xlsx结尾FileOutputStream fileOutputStream = new FileOutputStream(PATH + "一峰粉丝统计表07.xlsx");workbook.write(fileOutputStream);//关闭流fileOutputStream.close();System.out.println("一峰粉丝统计表07.xlsx生成完毕");}@Testpublic void testWrite03BigData() throws IOException {//时间long begin = System.currentTimeMillis();//创建一个簿Workbook workbook = new HSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据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("over");FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite03BigData.xls");workbook.write(outputStream);outputStream.close();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}//耗时较长@Testpublic void testWrite07BigData() throws IOException {//时间long begin = System.currentTimeMillis();//创建一个簿Workbook workbook = new XSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 65537; rowNum++){Row row =sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++){Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite07BigData.xlsx");workbook.write(outputStream);outputStream.close();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}@Testpublic void testWrite07BigDataS() throws IOException {//时间long begin = System.currentTimeMillis();//创建一个簿Workbook workbook = new SXSSFWorkbook();//创建表Sheet sheet = workbook.createSheet();//写入数据for (int rowNum = 0; rowNum < 100000; rowNum++){Row row =sheet.createRow(rowNum);for (int cellNum = 0; cellNum < 10; cellNum++){Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}System.out.println("over");FileOutputStream outputStream = new FileOutputStream(PATH + "testWrite07BigDataS.xlsx");workbook.write(outputStream);outputStream.close();//清除临时文件((SXSSFWorkbook)workbook).dispose();long end = System.currentTimeMillis();System.out.println((double)(end-begin)/1000);}
}
//这是读的操作,即是把excel文件读到控制台输出
//文件名ExcelReadTest.javaimport org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.Test;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;public class ExcelReadTest {String PATH = "G:\\大三\\下学期\\一峰说java\\";@Testpublic void testRead03() throws IOException {//获取文件流FileInputStream inputStream = new FileInputStream(PATH + "yifeng-poi一峰粉丝统计表03.xls");//1.创建一个工作簿,使用excel能操作的这边它都可以操作Workbook workbook = new HSSFWorkbook(inputStream);//2.得到表Sheet sheet = workbook.getSheetAt(0);//3.得到行Row row = sheet.getRow(0);//4.得到列Cell cell = row.getCell(1);//读取值的时候,一定需要注意类型!//getStringcellValue 字符串类型//System.out.println(cell.getStringCellValue());System.out.println(cell.getNumericCellValue());inputStream.close();}@Testpublic void testRead07() throws IOException {//获取文件流FileInputStream inputStream = new FileInputStream(PATH + "yifeng-poi一峰粉丝统计表07.xlsx");//1.创建一个工作簿,使用excel能操作的这边它都可以操作Workbook workbook = new XSSFWorkbook(inputStream);//2.得到表Sheet sheet = workbook.getSheetAt(0);//3.得到行Row row = sheet.getRow(0);//4.得到列Cell cell = row.getCell(1);//读取值的时候,一定需要注意类型!//getStringcellValue 字符串类型//System.out.println(cell.getStringCellValue());System.out.println(cell.getNumericCellValue());inputStream.close();}//测试数据类型@Testpublic void testCellType() throws IOException {//获取文件流FileInputStream inputStream = new FileInputStream(PATH + "明细表.xlsx");//1.创建一个工作簿,使用excel能操作的这边它都可以操作Workbook workbook = new XSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);//获取标题内容Row rowTitle = sheet.getRow(0);if (rowTitle!=null){//一定要掌握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){//读取列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]");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 HSSFCell.CELL_TYPE_ERROR: //错误System.out.print("[数据类型错误]");break;}System.out.println(cellValue);}}}}inputStream.close();}@Testpublic void testFormula() throws Exception{FileInputStream inputStream = new FileInputStream(PATH + "公式.xls");Workbook workbook = new HSSFWorkbook(inputStream);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://公式String formula = cell.getCellFormula();System.out.println(formula);//计算CellValue evaluate = FormulaEvaluator.evaluate(cell);String cellValue = evaluate.formatAsString();System.out.println(cellValue);break;}}
}

EasyExcel定义

Java领域解析,生成Excel比较有名的框架有Apache poi,jxl等,但他们都存在一个严重的问题就是非常的耗内存,如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc.

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。

快速使用easyExcel

1.导入依赖

 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.0-beta2</version></dependency><!--日期格式化工具--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10.1</version></dependency><!--测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version></dependency></dependencies>

2.建数据源

package com.yifeng.easy;import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;import java.util.Date;public class DemoData {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ExcelProperty("数字标题")private Double doubleData;@ExcelIgnoreprivate String ignore;public DemoData() {}public DemoData(String string, Date date, Double doubleData, String ignore) {this.string = string;this.date = date;this.doubleData = doubleData;this.ignore = ignore;}@Overridepublic String toString() {return "easy{" +"string='" + string + '\'' +", date=" + date +", doubleData=" + doubleData +", ignore='" + ignore + '\'' +'}';}public String getString() {return string;}public void setString(String string) {this.string = string;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public Double getDoubleData() {return doubleData;}public void setDoubleData(Double doubleData) {this.doubleData = doubleData;}public String getIgnore() {return ignore;}public void setIgnore(String ignore) {this.ignore = ignore;}
}

3.加个监听器,使用时会自动调用监听器

package com.yifeng.easy;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.ArrayList;
import java.util.List;// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class DemoDataListener extends AnalysisEventListener<DemoData> {private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);/*** 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 5;List<DemoData> list = new ArrayList<DemoData>();/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private DemoDAO demoDAO;public DemoDataListener() {// 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数demoDAO = new DemoDAO();}/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来** @param demoDAO*/public DemoDataListener(DemoDAO demoDAO) {this.demoDAO = demoDAO;}/*** 这个每一条数据解析都会来调用** @param data*            one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*///读取数据会执行invoke方法@Overridepublic void invoke(DemoData data, AnalysisContext context) {System.out.println("解析到一条数据:"+JSON.toJSONString(data));list.add(data);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (list.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listlist.clear();}}/*** 所有数据解析完成了 都会来调用** @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 这里也要保存数据,确保最后遗留的数据也存储到数据库saveData();LOGGER.info("所有数据解析完成!");}/*** 加上存储数据库*/private void saveData() {LOGGER.info("{}条数据,开始存储数据库!", list.size());demoDAO.save(list);LOGGER.info("存储数据库成功!");}
}

4.持久化类

package com.yifeng.easy;import java.util.List;/*** 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。**/
public class DemoDAO {public void save(List<DemoData> list) {// 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入}
}

5.开始测试

package com.yifeng.easy;import com.alibaba.excel.EasyExcel;
import org.junit.Test;import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class test {String PATH = "G:\\大三\\下学期\\一峰说java\\";private List<DemoData> data(){List<DemoData> list = new ArrayList<DemoData>();for (int i = 0; i < 10; i++ ){DemoData data = new DemoData();data.setString("字符串" + i);data.setDate(new Date());data.setDoubleData(0.56);list.add(data);}return list;}//根据list 写入excel@Testpublic void simpleWrite(){//写法1String fileName = PATH + "EasyTest.xlsx";//这里需要指定写用哪个class去写,然后写到第一个sheet, 名字为模板 然后文件流会自动关闭EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());}/*** 最简单的读* <p>1. 创建excel对应的实体对象 参照{@link DemoData}* <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}* <p>3. 直接读即可*/@Testpublic void simpleRead() {// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去// 写法1:String fileName = PATH + "EasyTest.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();}
}

更多推荐

一峰说:POI技术和easyExcel如何快速使用操作excel

本文发布于:2024-03-07 04:46:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1716879.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:快速   操作   技术   一峰说   POI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!