POI Excel解析

Posted 这个冬天有点冷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POI Excel解析相关的知识,希望对你有一定的参考价值。

Maven 引入POI

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.13</version>
        </dependency>

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

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.13</version>
        </dependency>

excel 工具类

package com.iris.controller.hello;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author
 * @date Created in 2018/5/2
 * @see
 */
public class PoiExcelUtil {

    private static DataFormatter formatter = new DataFormatter();

    /**
     * 合并单元格值
     *
     * @param sheet
     * @param cell
     * @param excelMap
     */
    public static void getMergedRegionValue(Sheet sheet, Cell cell, Map<String, Object> excelMap) {
        // 获得一个 sheet 中合并单元格的数量
        int sheetmergerCount = sheet.getNumMergedRegions();
        // 便利合并单元格
        for (int i = 0; i < sheetmergerCount; i++) {
            // 获得合并单元格
            CellRangeAddress ca = sheet.getMergedRegion(i);
            // 获得合并单元格的起始行, 结束行, 起始列, 结束列
            int firstC = ca.getFirstColumn();
            int firstR = ca.getFirstRow();

            if (cell.getColumnIndex() == firstC && cell.getRowIndex() == firstR) {
                System.out.println("第" + (cell.getRowIndex() + 1) + "行 第" + (cell.getColumnIndex() + 1) + "列 的内容是: "
                        + getCellValue(cell));
                excelMap.put((cell.getRowIndex() + 1) + "-" + (cell.getColumnIndex() + 1), getCellValue(cell));
            }

        }
    }

    /**
     * 判断是否在合并单元格
     *
     * @param sheet
     * @param cell
     * @return
     */
    public static boolean isMergedRegion(Sheet sheet, Cell cell) {
        // 得到一个sheet中有多少个合并单元格
        int sheetMergerCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergerCount; i++) {
            // 具体的合并单元格
            CellRangeAddress ca = sheet.getMergedRegion(i);
            // 合并单元格的起始列, 结束列;起始行, 结束行。
            int firstC = ca.getFirstColumn();
            int lastC = ca.getLastColumn();
            int firstR = ca.getFirstRow();
            int lastR = ca.getLastRow();
            // 判断该单元格是否在合并单元格范围之内, 如果是, 则返回 true
            if ((cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) && (cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param filePath      文件路径
     * @param sheetIndex    sheet
     * @param startRowIndex 开始行(不包含)
     * @return
     */
    private static Map<String, Object> getExcelValue(String filePath, int sheetIndex, int startRowIndex) {
        //保存解析的值 key: 行-列
        Map<String, Object> excelMap = new LinkedHashMap<>();
        try {
            // 创建对Excel工作簿文件
            Workbook book = null;
            try {
                //.xlsx 2007版本+
                book = new XSSFWorkbook(new FileInputStream(filePath));
            } catch (Exception ex) {
                //.xls 2003版本
                book = new HSSFWorkbook(new FileInputStream(filePath));
            }
            //读取sheet页
            Sheet sheet = book.getSheetAt(sheetIndex);
            // 获取到Excel文件中的所有行数
            int rows = sheet.getPhysicalNumberOfRows();
            for (int i = startRowIndex; i < rows; i++) {
                // 读取单元格
                Row row = sheet.getRow(i);
                if (row != null) {
                    // 获取到Excel文件中的所有的列
                    int cells = row.getPhysicalNumberOfCells();
                    for (int j = 0; j < cells; j++) {
                        // 获取到列的值
                        Cell cell = row.getCell(j);
                        if (cell != null) {
                            if (isMergedRegion(sheet, cell)) {
                                getMergedRegionValue(sheet, cell, excelMap);
                            } else {
                                System.out.println("第" + (i + 1) + "行 第" + (j + 1) + "列 的内容是: " + getCellValue(cell));
                                excelMap.put((i + 1) + "-" + (j + 1), getCellValue(cell));
                            }

                        }
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return excelMap;
    }

    /**
     * 获取 cell 值
     *
     * @param cell
     * @return
     */
    private static String getCellValue(Cell cell) {
        return formatter.formatCellValue(cell);
    }

    public static void main(String[] args) throws Exception {
        String file = "E://excel.xlsx";
        Map<String, Object> excelValue = getExcelValue(file, 0, 0);
        for (Map.Entry<String, Object> entry : excelValue.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

输出结果

第1行 第1列 的内容是: 品牌
第1行 第2列 的内容是: 车系
第1行 第3列 的内容是: 车型
第1行 第4列 的内容是: 车款
第1行 第5列 的内容是: 价格(万元)
第1行 第6列 的内容是: 首付比例
第2行 第1列 的内容是: 路虎
第2行 第2列 的内容是: 星脉
第2行 第3列 的内容是: L560 2.0P
第2行 第4列 的内容是: 2.0P AWD SWB S
第2行 第5列 的内容是: 399
第2行 第6列 的内容是: 20%
第3行 第1列 的内容是: 路虎
第3行 第2列 的内容是: 进EV
第3行 第3列 的内容是: Range Rover Evoque
第3行 第4列 的内容是: 敞篷版 2.0L P Convertible 4WD HSE Dynamic 2017款
第3行 第5列 的内容是: 599
第3行 第6列 的内容是: 25%
1-1:品牌
1-2:车系
1-3:车型
1-4:车款
1-5:价格(万元)
1-6:首付比例
2-1:路虎
2-2:星脉
2-3:L560 2.0P
2-4:2.0P AWD SWB S
2-5:399
2-6:20%
3-1:路虎
3-2:进EV
3-3:Range Rover Evoque
3-4:敞篷版 2.0L P Convertible 4WD HSE Dynamic 2017款
3-5:599
3-6:25%

以上是关于POI Excel解析的主要内容,如果未能解决你的问题,请参考以下文章

用POI解析Excel 出现的不能识别的编码问题

Java解析Excel之POI

基于POI导出Excel数据

java使用POI解析2007以上的Excel表格

poi 解析excel问题

java使用poi读取excel时,电话号码变成了科学计数法,整数变成double,怎么改过来