POI 按照自定義的單元格名稱解析對應單元格內容的方法,按行或列的名稱解析對應行列的方法

最近遇到一個新需求,關於使用POI解析excel的,正常的遍歷解析經常會用到,但是這次要求按照單元格自定義的名字去解析

首先定義好單元格名稱 右鍵定義
在這裏插入圖片描述在這裏插入圖片描述
這個叫單元格ID 也叫單元格地址,不過管理這個的地方叫名稱管理器
這個地方按照你需要去定義範圍,我得都是全局唯一的,所以我直接整個工作簿搜索
在這裏插入圖片描述你要把全部都定義好
接着先讀取一下試試
http://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/Workbook.html
這個是官方文檔,你們可以自己點進去看依一下
在這裏插入圖片描述

public static void main(String[] args) throws Exception {

        try {
            FileInputStream is = new FileInputStream("D:\\測試工作表.xls");
            // 讀取文件進來
            HSSFWorkbook workbook = new HSSFWorkbook(is);
            List<HSSFName> allNames = workbook.getAllNames();
            System.out.println("allNames = " + allNames);   
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

這裏你就能得到你定義所有的單元格的自定義名稱
在這裏插入圖片描述
你也可以按照名稱單獨讀取
在這裏插入圖片描述

那麼怎麼得到他的位置信息呢,下邊這樣就可以了
在這裏插入圖片描述關鍵代碼是這樣的

// 所有的別名
        List<HSSFName> allNames = workbook.getAllNames();
        for (int i = 0; i < allNames.size(); i++) {
            AreaReference[] arefs = AreaReference.generateContiguous(null, allNames.get(i).getRefersToFormula());
            for (int j = 0; j < arefs.length; j++) {
                CellReference[] crefs = arefs[j].getAllReferencedCells();
                for (int k = 0; k < crefs.length; k++) {
                    Sheet sheet = workbook.getSheet(crefs[k].getSheetName());
                    row = sheet.getRow(crefs[k].getRow());
                    cell = row.getCell(crefs[k].getCol());
                    // 命名分析 這裏因爲要存key-value所以需要根據單元格命名去定義key值,方便以後存取
                    // 自定義的名字
                    String refName = allNames.get(i).getNameName();
                    String key = checkTaskTemplate(refName);
                    // 類型分析
                    String value = FormatCell(cell);
                    map.put(key, value);
                }
            }
        }
 /**
     * 格式化Cell  根據你的要求去自己修改
     *
     * @param cell
     * @return
     */
    private static String FormatCell(Cell cell) {
        String value = "";
        switch (cell.getCellType()) {
            // 數字
            case NUMERIC:
                //如果爲時間格式的內容
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    //注:format格式 yyyy-MM-dd hh:mm:ss 中小時爲12小時制,若要24小時制,則把小h變爲H即可,yyyy-MM-dd HH:mm:ss
                    DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    Instant instant = HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toInstant();
                    ZoneId zoneId = ZoneId.systemDefault();
                    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
                    value = sdf.format(localDateTime);
                    break;
                } else {
                    DecimalFormat df = new DecimalFormat("0");// 避免科學記數法
                    value = String.valueOf(df.format(cell.getNumericCellValue()));
                    // value = String.valueOf(cell.getNumericCellValue());
                    // String[] split = value.split("\\.");
                    // //整型不保留小數部分
                    // if (split[1].length() == 1 && split[1].equals("0")) {
                    //     value = split[0];
                    //     break;
                    // }
                    break;
                }
                // 字符串
            case STRING:
                value = cell.getStringCellValue();
                break;
            // Boolean
            case BOOLEAN:
                value = cell.getBooleanCellValue() + "";
                break;
            // 公式
            case FORMULA:
                value = cell.getCellFormula() + "";
                break;
            // 空值
            case BLANK:
                value = "空";
                break;
            // 故障
            case ERROR:
                value = "非法字符";
                break;
            default:
                value = "未知類型";
                break;
        }
        return String.valueOf(value).trim().replaceAll("[\b\r\n\t]*", "");
    }

還有一種情況是 按照列或者行去讀取
老規矩 先定義好"表頭"
在這裏插入圖片描述上代碼 直接看吧

HSSFName name = workbook.getName("部門");
            CellReference cellReference = new CellReference(name.getRefersToFormula());
            String[] cellRefParts = cellReference.getCellRefParts();
            for (int i = 0; i < cellRefParts.length; i++) {
                System.out.println("cellRefParts = " + cellRefParts[i]);
            }
            HSSFSheet sheet = workbook.getSheet(cellRefParts[0]);
            // 行
            int startRow = Integer.parseInt(cellRefParts[1]);
            System.out.println("startRow = " + startRow);
            // 列
            int column = CellReference.convertColStringToIndex(cellRefParts[2]);
            System.out.println("column = " + column);

            HashSet<String> columnSet = getColumnSet(sheet, startRow, column);
            System.out.println("columnSet = " + columnSet);

這是執行結果,是不是很6
在這裏插入圖片描述關鍵代碼

   /**
     * @param sheet    需要讀取的sheet
     * @param column   指定需要獲取的列數,例如第一列 1
     * @param startRow 指定從第幾行開始讀取數據
     * @return 返回讀取列數據的set
     */
    public static HashSet<String> getColumnSet(HSSFSheet sheet, int startRow , int column ) {
        HashSet<String> hashSet = new HashSet<>();
        for (int rowIndex = startRow; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
            Row row = sheet.getRow(rowIndex);
            Cell content = row.getCell(column);
            String s = FormatCell(content);
            //對於內容進行操作
            hashSet.add(s);
        }
        return hashSet;
    }

這個暫時寫了一半,因爲寫一半的時候…需求取消了,我????!!!!!!!

所以爛尾,但是主要方法都在裏邊了,官方文檔真的寫的很清楚 還有很多操作屬性的,比如去創建一個excel的時候去設置一些系統信息都可以

因爲沒有用到所以代碼被我刪了

workbook.createInformationProperties();//創建文檔信息

只剩下這一行,但是根據API,如果你真的用到了,可以仔細閱讀文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章