摘要:本文介紹了一個使用Java語言開發的Excel列數據提取工具,該工具借助Apache POI庫實現對Excel文件的讀取與特定列數據提取功能。通過用戶輸入文件路徑與列名,程序可從指定Excel文件中提取相應列的數據并展示,同時詳細闡述了關鍵代碼邏輯與實現步驟。
關鍵詞:Java;Excel數據提取;Apache POI
代碼和數據測試:我用夸克網盤分享了「基于Java的Excel列數據提取工具實現」。鏈接:https://pan.quark.cn/s/1a7cb199e0c5
一、引言
在數據處理任務中,常常需要從Excel文件中提取特定列的數據。本程序利用Java語言和Apache POI庫,實現根據用戶輸入的列名,從Excel文件中提取對應列數據的功能。
支持處理.xls 和.xlsx 兩種 Excel 格式文件
通過命令行交互獲取文件路徑和要提取的列名
可以同時提取多個列的數據
對列名進行了大小寫不敏感的匹配
包含了基本的錯誤處理機制
二、核心代碼實現
使用的依賴
<dependencies><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.3</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency>
</dependencies>
2.1 主函數邏輯
主函數main
負責與用戶交互并協調整個數據提取流程。
- 用戶輸入獲取:
使用Scanner
類獲取用戶輸入的Excel文件路徑和要提取的列名。用戶輸入的列名以逗號分隔,程序將其分割并處理為目標列名列表。
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入Excel文件路徑: ");
String filePath = scanner.nextLine();System.out.print("請輸入要提取的列名(多個列名用逗號分隔): ");
String columnNamesInput = scanner.nextLine();
String[] columnNames = columnNamesInput.split(",");List<String> targetColumnNames = new ArrayList<>();
for (String name : columnNames) {targetColumnNames.add(name.trim());
}
- Excel文件處理:
嘗試打開用戶指定路徑的Excel文件,并根據文件擴展名確定使用XSSFWorkbook
(.xlsx文件)或HSSFWorkbook
(.xls文件)創建Workbook
對象。
try {FileInputStream file = new FileInputStream(new File(filePath));Workbook workbook = getWorkbook(file, filePath);
- 工作表與表頭處理:
獲取Excel文件的第一個工作表和表頭行,用于后續查找目標列的索引。
Sheet sheet = workbook.getSheetAt(0); // 獲取第一個工作表
Row headerRow = sheet.getRow(0); // 獲取表頭行,0是第一行
- 目標列索引查找:
遍歷目標列名列表,通過findColumnIndex
方法查找每個列名在表頭中的索引位置,并記錄找到的索引。
// 查找目標列的索引
List<Integer> targetColumnIndices = new ArrayList<>();
for (String targetName : targetColumnNames) {int columnIndex = findColumnIndex(headerRow, targetName);if (columnIndex != -1) {targetColumnIndices.add(columnIndex);System.out.println("找到列: " + targetName + ", 索引: " + columnIndex);} else {System.out.println("未找到列: " + targetName);}
}
- 目標列數據提取與展示:
如果找到至少一個目標列,則從工作表的第二行開始遍歷每一行,提取目標列的數據并打印。
// 提取并打印目標列的數據
if (!targetColumnIndices.isEmpty()) {System.out.println("\n提取的數據:");for (int i = 1; i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);if (row == null) continue;StringBuilder rowData = new StringBuilder();for (int colIndex : targetColumnIndices) {Cell cell = row.getCell(colIndex);if (cell != null) {rowData.append(getCellValueAsString(cell)).append("\t");} else {rowData.append("null\t");}}System.out.println(rowData.toString().trim());}
}
- 資源關閉:
完成數據提取后,關閉Workbook
和FileInputStream
資源。
workbook.close();
file.close();
- 異常處理:
如果在處理Excel文件過程中發生IOException
,捕獲異常并打印錯誤信息。
} catch (IOException e) {System.err.println("處理Excel文件時出錯: " + e.getMessage());e.printStackTrace();
}
2.2 獲取Workbook對象
getWorkbook
方法根據文件路徑的擴展名,返回對應的Workbook
對象。如果文件擴展名不是.xlsx
或.xls
,則拋出IllegalArgumentException
異常。
private static Workbook getWorkbook(FileInputStream file, String filePath) throws IOException {if (filePath.endsWith(".xlsx")) {return new XSSFWorkbook(file);} else if (filePath.endsWith(".xls")) {return new HSSFWorkbook(file);} else {throw new IllegalArgumentException("不支持的文件格式: " + filePath);}
}
2.3 查找列索引
findColumnIndex
方法在給定的表頭行中查找指定列名的索引。它遍歷表頭行的每個單元格,比較單元格的字符串值(忽略大小寫)與目標列名,若匹配則返回該單元格的索引,否則返回 -1。
private static int findColumnIndex(Row headerRow, String columnName) {if (headerRow == null) return -1;for (int i = 0; i <= headerRow.getLastCellNum(); i++) {Cell cell = headerRow.getCell(i);if (cell != null && cell.getCellType() == CellType.STRING) {String cellValue = cell.getStringCellValue().trim();if (cellValue.equalsIgnoreCase(columnName)) {return i;}}}return -1;
}
2.4 獲取單元格值字符串
getCellValueAsString
方法根據單元格的類型,將單元格的值轉換為字符串形式返回。它支持處理字符串、數字、日期、布爾值、公式和空白等不同類型的單元格。
private static String getCellValueAsString(Cell cell) {CellType cellType = cell.getCellType();switch (cellType) {case STRING:return cell.getStringCellValue();case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {return cell.getDateCellValue().toString();} else {return String.valueOf(cell.getNumericCellValue());}case BOOLEAN:return String.valueOf(cell.getBooleanCellValue());case FORMULA:return cell.getCellFormula();case BLANK:return "";default:return cell.toString();}
}
結果輸出:
請輸入Excel文件路徑: D:\pyprogect\excellianxi\all.xlsx
請輸入要提取的列名(多個列名用逗號分隔): id,age,income
找到列: id, 索引: 0
找到列: age, 索引: 1
找到列: income, 索引: 4提取的數據:
ID12101 48.0 17546.0
ID12102 40.0 30085.1
ID12103 51.0 16575.4
ID12104 23.0 20375.4
ID12105 57.0 50576.3
ID12106 57.0 37869.6
ID12107 22.0 8877.07
ID12678 34.0 17546.0
ID12679 35.0 30085.1
ID12680 36.0 16575.4
ID12681 37.0 20375.4
ID12682 38.0 50576.3
ID12683 39.0 37869.6
ID12684 40.0 8877.07Process finished with exit code 0
完整代碼:
package org.example;import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class ExcelColumnSelector {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.print("請輸入Excel文件路徑: ");String filePath = scanner.nextLine();System.out.print("請輸入要提取的列名(多個列名用逗號分隔): ");String columnNamesInput = scanner.nextLine();String[] columnNames = columnNamesInput.split(",");List<String> targetColumnNames = new ArrayList<>();for (String name : columnNames) {targetColumnNames.add(name.trim());}try {FileInputStream file = new FileInputStream(new File(filePath));Workbook workbook = getWorkbook(file, filePath);Sheet sheet = workbook.getSheetAt(0); // 獲取第一個工作表Row headerRow = sheet.getRow(0); // 獲取表頭行// 查找目標列的索引List<Integer> targetColumnIndices = new ArrayList<>();for (String targetName : targetColumnNames) {int columnIndex = findColumnIndex(headerRow, targetName);if (columnIndex != -1) {targetColumnIndices.add(columnIndex);System.out.println("找到列: " + targetName + ", 索引: " + columnIndex);} else {System.out.println("未找到列: " + targetName);}}// 提取并打印目標列的數據if (!targetColumnIndices.isEmpty()) {System.out.println("\n提取的數據:");for (int i = 1; i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);if (row == null) continue;StringBuilder rowData = new StringBuilder();for (int colIndex : targetColumnIndices) {Cell cell = row.getCell(colIndex);if (cell != null) {rowData.append(getCellValueAsString(cell)).append("\t");} else {rowData.append("null\t");}}System.out.println(rowData.toString().trim());}}workbook.close();file.close();} catch (IOException e) {System.err.println("處理Excel文件時出錯: " + e.getMessage());e.printStackTrace();}}private static Workbook getWorkbook(FileInputStream file, String filePath) throws IOException {if (filePath.endsWith(".xlsx")) {return new XSSFWorkbook(file);} else if (filePath.endsWith(".xls")) {return new HSSFWorkbook(file);} else {throw new IllegalArgumentException("不支持的文件格式: " + filePath);}}private static int findColumnIndex(Row headerRow, String columnName) {if (headerRow == null) return -1;for (int i = 0; i <= headerRow.getLastCellNum(); i++) {Cell cell = headerRow.getCell(i);if (cell != null && cell.getCellType() == CellType.STRING) {String cellValue = cell.getStringCellValue().trim();if (cellValue.equalsIgnoreCase(columnName)) {return i;}}}return -1;}private static String getCellValueAsString(Cell cell) {CellType cellType = cell.getCellType();switch (cellType) {case STRING:return cell.getStringCellValue();case NUMERIC:if (DateUtil.isCellDateFormatted(cell)) {return cell.getDateCellValue().toString();} else {return String.valueOf(cell.getNumericCellValue());}case BOOLEAN:return String.valueOf(cell.getBooleanCellValue());case FORMULA:return cell.getCellFormula();case BLANK:return "";default:return cell.toString();}}
}