Excel POI(了解,推荐使用阿里开源 EasyExcel)

11 篇文章 0 订阅

一、POI概述

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。(相对比较麻烦,数据量大可能会报OOM(内存用完异常))

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

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

操作Excel文件区分版本:
2003版本(包含2003)以前的扩展名为.xls需要用HSSFWorkbook类操作
2007版本(包含2007)以后的扩展名为.xlsx需要用XSSFWorkbook类操作

excel 对应的对象:
工作簿
工作表

依赖

<dependencies>
        <!--导入依赖-->
        <!--旧版本支持,eg .xls Excel(03)-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <!--新版本支持,eg .xlsx Excel(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>
        <!--text-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>

        </dependency>

    </dependencies>

**

2003版本(包含2003)以前的扩展名为.xls需要用HSSFWorkbook类操作

**

public class ExcelWriteTest {
   private static final String PATH = "D:\\IDEA_Project\\Excel_POI_Easy\\excel-poi\\";
    private FileOutputStream fileOutputStream;
    //03版本
    @Test
    public void ExcelVersion03() throws IOException {
        //1.创建工作簿
        Workbook workbook = new HSSFWorkbook();
        //2.创建工作表
        Sheet sheet = workbook.createSheet("swj521");
        //3.创建单元格第一行
        Row row1 = sheet.createRow(0);
        //4.单元格第一行第一列
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("swj521521");
        //第一行第二列单元格
        Cell cell2 = row1.createCell(1);
        cell2.setCellValue("yzh521swj");
        //创建单元格第二行
        Row row2 = sheet.createRow(1);
        //第二行第一列
        Cell row2Cell = row2.createCell(0);
        row2Cell.setCellValue("swj521yzh");
        //第二行第二列
        Cell row2Cell2 = row2.createCell(1);
        row2Cell2.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
        //5.生成一张表(IO流),03版本的用xls结尾
        try {
        fileOutputStream = new FileOutputStream(PATH+"yzh521swj03表.xls");
            workbook.write(fileOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            fileOutputStream.close();
        }
        System.out.println("yzh521swj03表生成成功");

    }

}

2007版本(包含2007)以后的扩展名为.xlsx需要用XSSFWorkbook类操作

public class ExcelWriteTest2 {
    private static final String PATH = "D:\\IDEA_Project\\Excel_POI_Easy\\excel-poi\\";
    private FileOutputStream fileOutputStream;
    //03版本
    @Test
    public void ExcelVersion03() throws IOException {
        //1.创建工作簿
        Workbook workbook = new XSSFWorkbook();
        //2.创建工作表
        Sheet sheet = workbook.createSheet("swj521yzh");
        //3.创建单元格第一行
        Row row1 = sheet.createRow(0);
        //4.单元格第一行第一列
        Cell cell1 = row1.createCell(0);
        cell1.setCellValue("swj521521");
        //第一行第二列单元格
        Cell cell2 = row1.createCell(1);
        cell2.setCellValue("yzh521swj");
        //创建单元格第二行
        Row row2 = sheet.createRow(1);
        //第二行第一列
        Cell row2Cell = row2.createCell(0);
        row2Cell.setCellValue("swj521yzh");
        //第二行第二列
        Cell row2Cell2 = row2.createCell(1);
        row2Cell2.setCellValue(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
        //5.生成一张表(IO流),03版本的用xlsx结尾
        try {
            fileOutputStream = new FileOutputStream(PATH+"yzh521swj07表.xlsx");
            workbook.write(fileOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            fileOutputStream.close();
        }
        System.out.println("yzh521swj07表生成成功");

    }
}

1.大文件写HSSF

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

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

ava.lang.IllegalArgumentException: Invalid row number (65536) outsideallowable range (0..6553
      //03版本大量数据
    @Test
    public void ExcelVersion03BigData() throws IOException {
        FileOutputStream fileOutputStream1 = null;
        //1.创建工作簿
        Workbook hssfWorkbook = new HSSFWorkbook();
        //2.创建工作表
        Sheet sheet = hssfWorkbook.createSheet();
        //3.写入数据
        for (int rows = 0; rows < 65536; rows++) {
            Row row = sheet.createRow(rows);
            for (int cell = 0; cell < 10; cell++) {
                Cell cell1 = row.createCell(cell);
                cell1.setCellValue(cell);
            }
        }
        System.out.println("over");
        try {
            fileOutputStream1 = new FileOutputStream(PATH + "Excel03BigData.xls");
            hssfWorkbook.write(fileOutputStream1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            fileOutputStream1.close();
        }

    }

2.大文件写XSSF

缺点**😗* 写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条
优点**😗*可以写较大的数据量,如20万条

//07版本大量数据
    @Test
    public void ExcelVersion07BigData() throws IOException {
        FileOutputStream fileOutputStream1 = null;
        //1.创建工作簿
        Workbook Workbook = new XSSFWorkbook();
        //2.创建工作表
        Sheet sheet = Workbook.createSheet();
        //3.写入数据
        for (int rows = 0; rows < 100000; rows++) {
            Row row = sheet.createRow(rows);
            for (int cell = 0; cell < 10; cell++) {
                Cell cell1 = row.createCell(cell);
                cell1.setCellValue(cell);
            }
        }
        System.out.println("over");
        try {
            //4.创建表
            fileOutputStream1 = new FileOutputStream(PATH + "Excel07BigData.xlsx");
            //5.导出表
            Workbook.write(fileOutputStream1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            //6.关闭流
            fileOutputStream1.close();
        }

    }

2.大文件写SXSSF

优点**😗*可以写非常大的数据量,如100万条甚至更多条,写数据速度快,占用更少的内存注意:过程中会产生临时文件,需要清理临时文件默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件如果想自定义内存中数据的数量,可以使用new SXSSFWorkbook ( 数量 )

//07版本大量数据升级版解决速度慢
    @Test
    public void ExcelVersion07BigDataS() throws IOException {
        FileOutputStream fileOutputStream1 = null;
        //1.创建工作簿
        Workbook Workbook = new SXSSFWorkbook();
        //2.创建工作表
        Sheet sheet = Workbook.createSheet();
        //3.写入数据
        for (int rows = 0; rows < 100000; rows++) {
            Row row = sheet.createRow(rows);
            for (int cell = 0; cell < 10; cell++) {
                Cell cell1 = row.createCell(cell);
                cell1.setCellValue(cell);
            }
        }
        System.out.println("over");
        try {
            //4.创建表
            fileOutputStream1 = new FileOutputStream(PATH + "Excel07BigDataS.xlsx");
            //5.导出表
            Workbook.write(fileOutputStream1);
            //6.清除临时文件(多态)
            ((SXSSFWorkbook) Workbook).dispose();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            //6.关闭流
            fileOutputStream1.close();
        }

    }

4、POI-Excel读

03版本

public class ExcelReadTest {
    private static final String PATH = "D:\\IDEA_Project\\Excel_POI_Easy\\excel-poi\\";

    @Test
    public void testRead03() throws IOException {
        FileInputStream inputStream = new FileInputStream(PATH + "yzh521swj03表.xls");
        //1.创建一个工作簿,对excel的所有操作都可以
        Workbook workbook = new HSSFWorkbook(inputStream);
        //2.得到表
        Sheet sheet = workbook.getSheetAt(0);
        // 读取第一行第一列
        Row row = sheet.getRow(0);
        Cell cell = row.getCell(0);
        // 输出单元内容
        //读取值得时候注意数据类型
        //cell.getStringCellValue()字符串类型
        System.out.println(cell.getStringCellValue());//获取字符串
        // 操作结束,关闭文件
        inputStream.close();
    }
}

07版本

public class ExcelReadTest {
    private static final String PATH = "D:\\IDEA_Project\\Excel_POI_Easy\\excel-poi\\";

    @Test
    public void testRead07() throws IOException {
        FileInputStream inputStream = new FileInputStream(PATH + "yzh521swj07表.xlsx");
        //1.创建一个工作簿,对excel的所有操作都可以
        Workbook workbook = new XSSFWorkbook(inputStream);
        //2.得到表
        Sheet sheet = workbook.getSheetAt(0);
        // 读取第一行第一列
        Row row = sheet.getRow(0);
        Cell cell = row.getCell(0);
        // 输出单元内容
        //读取值得时候注意数据类型
        //cell.getStringCellValue()字符串类型
        System.out.println(cell.getStringCellValue());//获取字符串
        // 操作结束,关闭文件
        inputStream.close();
    }
}

读取不同的数据类型

public class ExcelReadTest {
    private static final String PATH = "D:\\IDEA_Project\\Excel_POI_Easy\\excel-poi\\";

    @Test
    public void testRead07() throws IOException {
        FileInputStream inputStream = new FileInputStream(PATH + "yzh521swj03表.xls");
        //1.创建一个工作簿,对excel的所有操作都可以
        Workbook workbook = new HSSFWorkbook(inputStream);
        //2.得到表
        Sheet sheet = workbook.getSheetAt(0);
        // 读取第一行(获取标题内容)
        Row rowTitle = sheet.getRow(0);
        if (rowTitle != null) {
            //读取这一行的所有内容(包括这一行有多少列有数据)
            int cellCount = rowTitle.getPhysicalNumberOfCells();
            //读取所有的列
            for (int cellNumber = 0; cellNumber < cellCount; cellNumber++) {
                Cell cell = rowTitle.getCell(cellNumber);
                if (cell != null) {
                    //获取类型
                    int cellType = cell.getCellType();
                    //读取内容(已知是string类型)
                    String stringCellValue = cell.getStringCellValue();
                    System.out.print(stringCellValue + "|");
                }
            }
            System.out.println();
        }
        //获取表多少行
        int rowCount = sheet.getPhysicalNumberOfRows();
        for (int rowNum = 1; rowNum < rowCount; rowNum++) {
            //读每一行
            Row rowData = sheet.getRow(rowNum);
            if (rowData != null) {
                //获取每一行多少列(单元格)
                int cells = rowTitle.getPhysicalNumberOfCells();
                //从第二行开始读
                for (int cellNum = 0; cellNum < cells; 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 Cell.CELL_TYPE_ERROR:
                                System.out.print("【数据类型错误】");
                                break;
                        }
                        System.out.println(cellValue);
                    }

                }
            }


        }
        inputStream.close();
    }
}

标题计算公式

 @Test
    public void excelTestFormula() throws Exception {
        FileInputStream fileInputStream = new FileInputStream(PATH + "计算公式.xls");
        Workbook workbook = new HSSFWorkbook(fileInputStream);
        Sheet sheet = workbook.getSheetAt(0);
        // 读取第2行第一列
        Row row = sheet.getRow(1);
        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;
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yzhSWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值