栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用Apache POI操作EXCEL03版本及EXCEL07以上版本表格

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Apache POI操作EXCEL03版本及EXCEL07以上版本表格

Apache POI 是什么

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。
Apache POI 解析链接:Apache POI .

使用 pom.xml


    
        excel
        com.jsxl
        0.0.1-SNAPSHOT
    
    4.0.0

    excel_poi

    
        
        
            org.apache.poi
            poi
            3.9
        

        
        
            org.apache.poi
            poi-ooxml
            3.9
        

        
        
            joda-time
            joda-time
            2.10.1
        

        
        
            junit
            junit
            4.12
        
    

excel表格解析

Workbook接口的几个实现类以及xls和区别

HSSF 可操作EXCEL03版本
SXSSF和XSSF可操作EXCEL07以上版本

POI-Excel写操作
package com.jsxl.excel;

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.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.Test;

import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWrite {

    private String PATH="D:\github\excel\excel_poi";

    @Test
    public void write03() throws IOException {
        // 1、创建工作薄
        Workbook workbook = new HSSFWorkbook();
        //2、创建工作表
        Sheet sheet = workbook.createSheet("test1");

        //3、创建行(0:第一行)
        Row row1 = sheet.createRow(0);
        //4、创建单元格(0:第一行的第一个格子)
        Cell cell00 = row1.createCell(0);
        cell00.setCellValue("测试数据");
        //第一行的第二个格子
        Cell cell01 = row1.createCell(1);
        cell01.setCellValue("testData");

        //第二行
        Row row2 = sheet.createRow(1);
        //第二行的第一个格子
        Cell cell10 = row2.createCell(0);
        cell10.setCellValue("时间");
        //第二行的第二个格子
        Cell cell11 = row2.createCell(1);
        cell11.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));

        //生成Excel(IO流)
        //03版本的Excel是使用 .xls 结尾!!!
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "POI03测试.xls");

        workbook.write(fileOutputStream);

        //关闭流
        fileOutputStream.close();

        System.out.println("03Excel输出完毕");
    }

    @Test
    public void write07() throws IOException {
        // 1、创建工作薄
        Workbook workbook = new XSSFWorkbook();
        //2、创建工作表
        Sheet sheet = workbook.createSheet("test1");

        //3、创建行(0:第一行)
        Row row1 = sheet.createRow(0);
        //4、创建单元格(0:第一行的第一个格子)
        Cell cell00 = row1.createCell(0);
        cell00.setCellValue("测试数据");
        //第一行的第二个格子
        Cell cell01 = row1.createCell(1);
        cell01.setCellValue("testData");

        //第二行
        Row row2 = sheet.createRow(1);
        //第二行的第一个格子
        Cell cell10 = row2.createCell(0);
        cell10.setCellValue("时间");
        //第二行的第二个格子
        Cell cell11 = row2.createCell(1);
        cell11.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));

        //生成Excel(IO流)
        //03版本的Excel是使用 .xlsx 结尾!!!
        FileOutputStream fileOutputStream = new FileOutputStream(PATH + "POI07测试.xlsx");

        workbook.write(fileOutputStream);

        //关闭流
        fileOutputStream.close();

        System.out.println("07Excel输出完毕");
    }
}
效率比较

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

  • 缺点:最多只能处理 65536 行,否则会抛出异常
  • 优点:过程中写入缓存,不操作磁盘,最后一次性写入磁盘,速度快
    @Test
    public void write03BigData() 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 fileOutputStream = new FileOutputStream(PATH + "TestWrite03BigData.xls");
        workbook.write(fileOutputStream);
        fileOutputStream.close();

        long end = System.currentTimeMillis();

        System.out.println((double) (end-begin)/1000);

耗时

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

  • 缺点:写数据时速度非常慢,非常耗内存,可能发生内存溢出OOM
  • 优点:可以写较大的数据量
 @Test
    public void write07BigData() throws IOException {
        long begin = System.currentTimeMillis();
        //创建簿
        Workbook workbook = new XSSFWorkbook();
        //创建表
        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 fileOutputStream = new FileOutputStream(PATH + "TestWrite07BigData.xlsx");
        workbook.write(fileOutputStream);
        fileOutputStream.close();

        long end = System.currentTimeMillis();

        System.out.println((double) (end-begin)/1000);
    }


SXSSF - 也是对Microsoft Excel OOXML XLSX操作,速度更快但是会产出临时文件
SXSSF - 通过一个滑动窗口来限制访问Row的数量从而达到低内存占用的目录,XSSF可以访问所有行。旧的行数据不再出现在滑动窗口中并变得无法访问,与此同时写到磁盘上。
在自动刷新的模式下,可以指定窗口中访问Row的数量,从而在内存中保持一定数量的Row。当达到这一数量时,在窗口中产生新的Row数据,并将低索引的数据从窗口中移动到磁盘中。
或者,滑动窗口的行数可以设定成自动增长的。它可以根据需要周期的根据一次明确的flushRow(int keepRows)调用来进行修改。

@Test
public void write07BigDataS() 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 fileOutputStream = new FileOutputStream(PATH + "TestWrite07BigDataS.xlsx");
    workbook.write(fileOutputStream);
    fileOutputStream.close();
    //清除临时文件
    ((SXSSFWorkbook) workbook).dispose();
 
    long end = System.currentTimeMillis();
    System.out.println((double) (end-begin)/1000);
}


SXSSFWorkbook 官方解释:实现“BigGridDemo”策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。
请注意,仍然可能会消耗大量内存,这些内存基于正在使用的功能,例如合并区域,注释…仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。

POI-Excel读操作

读操作时需要注意数据的类型,源码类型有如下几种

public interface Cell {

    
    public final static int CELL_TYPE_NUMERIC = 0;

    
    public final static int CELL_TYPE_STRING = 1;

    
    public final static int CELL_TYPE_FORMULA = 2;

    
    public final static int CELL_TYPE_BLANK = 3;

    
    public final static int CELL_TYPE_BOOLEAN = 4;

    
    public final static int CELL_TYPE_ERROR = 5;
}

HSSF

    @Test
    public void testRead03() throws IOException {
        //获取文件流
        FileInputStream fileInputStream = new FileInputStream(PATH + "POI03测试.xls");

        //1、获取工作簿
        Workbook workbook = new HSSFWorkbook(fileInputStream);
        //2、得到表
        Sheet sheet = workbook.getSheetAt(0);
        //3、得到行
        Row row = sheet.getRow(0);
        //4、得到列
        Cell cell = row.getCell(0);

        //读取值时一定要注意类型
        System.out.println(cell.getStringCellValue());

        fileInputStream.close();
    }

XSSF

@Test
public void testRead07() throws IOException {
    //获取文件流
    FileInputStream fileInputStream = new FileInputStream(PATH + "POI07测试.xlsx");
 
    //1、获取工作簿
    Workbook workbook = new XSSFWorkbook(fileInputStream);
    //2、得到表
    Sheet sheet = workbook.getSheetAt(0);
    //3、得到行
    Row row = sheet.getRow(0);
    //4、得到列
    Cell cell = row.getCell(0);
 
    //读取值时一定要注意类型
    System.out.println(cell.getStringCellValue());
 
    fileInputStream.close();
}
读取不同的数据类型

@Test
public void testCellType() throws Exception {
    //获取文件
    FileInputStream fileInputStream = new FileInputStream(PATH + "会员消费商品明细表.xls");
 
    //获取工作薄
    Workbook workbook = new HSSFWorkbook(fileInputStream);
    //得到表
    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 cellCout = rowTitle.getPhysicalNumberOfCells();
            for (int cellNum = 0; cellNum < cellCout; 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_NUMERIC://数字类型
                            System.out.print("【NUMERIC】");
 
                            if (HSSFDateUtil.isCellDateFormatted(cell)){//日期
                                System.out.print("【日期】");
                                Date date = cell.getDateCellValue();
                                cellValue = new DateTime().toString("yyyy-MM-dd");
                            }else{
                                // 不是日期格式,则防止当数字过长时以科学计数法显示
                                System.out.print("【转换成字符串】");
                                cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                                cellValue = cell.toString();
                            }
                            break;
                        case HSSFCell.CELL_TYPE_BLANK://空
                            System.out.print("【BLANK】");
                            break;
                        case Cell.CELL_TYPE_ERROR:
                            System.out.print("【数据类型错误】");
                            break;
                    }
                    System.out.println(cellValue);
                }
            }
        }
    }
    fileInputStream.close();
}


计算公式

    @Test
    public void testFormula() throws Exception {
        FileInputStream fileInputStream = new FileInputStream(PATH + "数据类型测试表.xls");
        Workbook workbook = new HSSFWorkbook(fileInputStream);
        Sheet sheetAt = workbook.getSheetAt(0);

        //获取计算公式所在的行
        Row row = sheetAt.getRow(1);
        //计算公式的第几个单元格
        Cell cell = row.getCell(5);

        //拿到计算公式
        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;
        }
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/693009.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号