JAVA使用POI操作Excel

        几个月以前找工作时我收到了人生中第一份为了竞争工作的笔试题。打开的时候还是很期待的,但是打开后我发现,里面竟然只有一道题。让我用程序来将他发给我的一个数据量很大的excel表格读取并按照他要求的几列来进行分类,同一类的数据保存到同一个文件中。说实话我当时并没有学过POI,甚至根本还不知道这个东西。去问了身边一些认识的人,他们说你直接放弃吧,公司那么多,谁会这个啊。但由于有些不甘心,去问了我的老师。老师说:“你去学吧,这个叫POI。”于是,我就去现学现卖了......最终成功通过了笔试和两轮面试,获得了这家公司的offer~

        这段时间我又做到了涉及到java中POI的需求,所以决定把这个整理一下。其实这个api和操作过程很简单,难得往往是我们在开发中如何合理的运用,以及我们自己的逻辑思维。

Apache POI 是基于Office Open XML 标准(OOXML)和 Microsoft 的OLE 2 复合文档格式(OLE2)处理各种文件格式的开源项目。简而言之,您可以使用Java读写MS Excel文件,可以使用Java读写MS Word 和 MS PowerPoint 文件。

目录

模块

Maven依赖

Excel写操作

SXSSF

Excel读操作


模块

  • HSSF - 提供读写 Microsoft Excel XLS 格式 (Microsoft Excel 97 (-2003)) 档案的功能。

  • XSSF - 提供读写 Microsoft Excel OOXML XLSX 格式 (Microsoft Excel XML (2007+)) 档案的功能。

  • SXSSF - 提供低内存占用量读写 Microsoft Excel OOXML XLSX 格式档案的功能。

  • HWPF - 提供读写 Microsoft Word DOC97 格式 (Microsoft Word 97 (-2003)) 档案的功能。

  • XWPF - 提供读写 Microsoft Word DOC2003 格式 (WordprocessingML (2007+)) 档案的功能。

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

  • HDGF/XDGF - 提供读 Microsoft Visio 格式档案的功能。

  • HPBF - 提供读 Microsoft Publisher 格式档案的功能。

  • HSMF - 提供读 Microsoft Outlook 格式档案的功能。

Maven依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>

文件类型有很多种,不同的文件类型我们需要使用不同的类来进行操作,如Excel格式我们就要用到HSSFWorkboo。其实学会一个其他的自然就会了,下面我就用Excel为例子:

Excel写操作

先给大家介绍一下我们Excel文件的结构:

public static void excelWrite() throws Exception{
        String path = "/Users/admin/Desktop/list/";
        //创建一个工作簿
        Workbook workbook = new HSSFWorkbook();
        //创建一个工作表
        Sheet sheet = workbook.createSheet("页面访问统计表");
        //创建一个行 第i行的下标为i-1
        Row row1 = sheet.createRow(0);
        //创建一个单元格 第i列的单元格的下标i-1 (1,1)
        Cell cell11 = row1.createCell(0);
        cell11.setCellValue("今日访客量");
        //(1,2)
        Cell cell12 = row1.createCell(1);
        cell12.setCellValue(666);

        Row row2 = sheet.createRow(1);
        //(2,1)
        Cell cell21 = row2.createCell(0);
        cell21.setCellValue("页面类型");
        //(2,2)
        Cell cell22 = row2.createCell(1);
        cell22.setCellValue("购物");

        FileOutputStream fileOutputStream = new FileOutputStream(path + "页面访问统计表.xls");

        workbook.write(fileOutputStream);

        //关闭流
        fileOutputStream.close();

        workbook.close();
        System.out.println("生成完成");
    }

在main函数中调用一下

public static void main(String[] args) throws Exception{
    ExampleUtil.excelWrite();
}

就可以生成一个excel文件存储在我们指定的路径:

SXSSF

HSSF用来对Microsoft Excel XLS 格式进行读写操作,仅能保存65536行数据,而对Microsoft Excel OOXML XLSX 格式 (Microsoft Excel XML (2007+))进行读写的话需要用XSSF,虽然XSSF没有限制,但是它的速度很慢,所以我们可以用速度快且占用内存少的SXSSF。

SXSSF会产生临时文件。它默认在内存中保存的记录条数为100,如果超过这个数量,则行号(rownum)最小的数据将被写入临时文件中,可以通过使用它的有参构造SXSSFWorkbook(int windowSize)来对整个工作簿存放在内存中的记录条数进行修改,还可以通过setRandomAccessWindowSize(int windowSize)对单个表在内存中的记录条数进行修改。需要注意的是你必须通过调用dispose方法来清理定时文件。

有关于SXSSF的工作原理可以查看官网:

The New Halloween Document

public static void SXSSFWrite() throws Exception{
        String path = "/Users/admin/Desktop/list/";
        //创建一个工作簿 为他设定windowSize
        Workbook workbook = new SXSSFWorkbook(100);
        //创建一个工作表
        Sheet sheet = workbook.createSheet("页面访问数据表");
        //为单个表设置windowSize
        ((SXSSFSheet)sheet).setRandomAccessWindowSize(110);
        //写入数据
        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);
            }
        }
        FileOutputStream fileOutputStream = new FileOutputStream(path + "页面访问数据表.xlsx");

        workbook.write(fileOutputStream);

        // 关闭流
        fileOutputStream.close();

        // 清除临时文件
        ((SXSSFWorkbook) workbook).dispose();
        workbook.close();
    }

Excel读操作

有这样一张表,我们来读取它并按照不同的类型进行处理和输出

public static void excelRead() throws Exception{
        String path = "/Users/admin/Desktop/list/";
        FileInputStream fileInputStream = new FileInputStream(path + "页面访问统计表.xls");

        Workbook workbook = new HSSFWorkbook(fileInputStream);
        Sheet sheet = workbook.getSheetAt(0);
        //拿到表头行
        Row row0 = sheet.getRow(0);
        if(row0 != null) {
            int cellCount = row0.getPhysicalNumberOfCells();
            for (int cellNum = 0;cellNum < cellCount; cellNum++){
                Cell cell = row0.getCell(cellNum);
                if (cell != null){
                    String cellValue = cell.getStringCellValue();
                    System.out.print(cellValue + " | ");
                }
            }
            System.out.println();
        }

        int rowCount = sheet.getPhysicalNumberOfRows();
        for (int rowNum = 1;rowNum < rowCount;rowNum ++){
            Row row = sheet.getRow(rowNum);
            if (row != null){
                int cellCount = row.getPhysicalNumberOfCells();
                for (int cellNum = 0;cellNum < cellCount;cellNum ++){
                    Cell cell = row.getCell(cellNum);
                    if (cell != null){
                        CellType cellType = cell.getCellTypeEnum();
                        String cellValue = "";

                        switch (cellType){
                            case STRING:
                                System.out.print("【STRING】");
                                cellValue = cell.getStringCellValue();
                                break;
                            case BOOLEAN:
                                System.out.print("【BOOLEAN】");
                                cellValue = String.valueOf(cell.getBooleanCellValue());
                                break;
                            case BLANK:
                                System.out.print("【BLANK】");
                                cellValue = cell.getStringCellValue();
                                break;
                            case NUMERIC:
                                //要判断是普通的数字还是日期
                                System.out.print("【NUMERIC】");
                                if (DateUtil.isCellDateFormatted(cell)){
                                    //是日期
                                    System.out.print("【DATE】");
                                    Date date = cell.getDateCellValue();
                                }else {
                                    //不是日期
                                    cellValue = new BigDecimal(cell.getNumericCellValue()).toPlainString();
                                }
                                break;
                            case FORMULA:
                                //是公式
                                System.out.print("【FORMULA】");
                                cellValue = cell.getCellFormula();
                            case ERROR:
                                cellValue = "ERROR";
                                break;
                            default:
                                cellValue = "UNKNOW";
                                break;
                        }
                        System.out.print(cellValue);
                        if(cellNum != cellCount-1){
                            System.out.print(" | ");
                        }
                    }
                }
                System.out.println();
            }
        }
        fileInputStream.close();
        workbook.close();
    }

输出结果是这样的:

  • 32
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值