Java讀取批量Excel文件,並轉化為List >


1.首先基礎知識:
一 :簡介

開發中經常會設計到excel的處理,如導出Excel,導入Excel到數據庫中,操作Excel目前有兩個框架,一個是apache 的poi, 另一個是 Java Excel

Apache POI 簡介是用Java編寫的免費開源的跨平台的 Java API,Apache POI提供API給Java程式對Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式檔案讀和寫的功能。POI為“Poor Obfuscation Implementation”的首字母縮寫,意為“可憐的模糊實現”。

官方主頁: http://poi.apache.org/index.html

API文檔: http://poi.apache.org/apidocs/index.html

Java Excel是一開放源碼項目,通過它Java開發人員可以讀取Excel文件的內容、創建新的Excel文件、更新已經存在的Excel文件。jxl 由於其小巧 易用的特點, 逐漸已經取代了 POI-excel的地位, 成為了越來越多的java開發人員生成excel文件的首選。

由於apache poi 在項目中用的比較多,本篇博客只講解apache poi,不講jxl

二:Apache POI常用的類

HSSF - 提供讀寫Microsoft Excel XLS格式檔案的功能。

XSSF - 提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能。

HWPF - 提供讀寫Microsoft Word DOC97格式檔案的功能。

XWPF - 提供讀寫Microsoft Word DOC2003格式檔案的功能。

HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。

HDGF - 提供讀Microsoft Visio格式檔案的功能。

HPBF - 提供讀Microsoft Publisher格式檔案的功能。

HSMF - 提供讀Microsoft Outlook格式檔案的功能。

在開發中我們經常使用HSSF用來操作Excel處理表格數據,對於其它的不經常使用。

HSSF 是Horrible SpreadSheet Format的縮寫,通過HSSF,你可以用純Java代碼來讀取、寫入、修改Excel文件。HSSF 為讀取操作提供了兩類API:usermodel和eventusermodel,即“用戶模型”和“事件-用戶模型”。

常用的類和方法

HSSFWorkbook :工作簿,代表一個excel的整個文檔

HSSFWorkbook(); // 創建一個新的工作簿

HSSFWorkbook(InputStream inputStream); // 創建一個關聯輸入流的工作簿,可以將一個excel文件封裝成工作簿

HSSFSheet createSheet(String sheetname); 創建一個新的Sheet

HSSFSheet getSheet(String sheetName); 通過名稱獲取Sheet

HSSFSheet getSheetAt(int index); // 通過索引獲取Sheet,索引從0開始

HSSFCellStyle createCellStyle(); 創建單元格樣式

int getNumberOfSheets(); 獲取sheet的個數

setActiveSheet(int index); 設置默認選中的工作表

write();

write(File newFile);

write(OutputStream stream);

HSSFSheet:工作表

HSSFRow createRow(int rownum); 創建新行,需要指定行號,行號從0開始

HSSFRow getRow(int index); 根據索引獲取指定的行

int addMergedRegion(CellRangeAddress region); 合並單元格

CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol); 單元格范圍, 用於合並單元格,需要指定要合並的首行、最后一行、首列、最后一列。

autoSizeColumn(int column); 自動調整列的寬度來適應內容

getLastRowNum(); 獲取最后的行的索引,沒有行或者只有一行的時候返回0

setColumnWidth(int columnIndex, int width); 設置某一列的寬度,width=字符個數 * 256,例如20個字符的寬度就是20 * 256

HSSFRow :行

HSSFCell createCell(int column); 創建新的單元格

HSSFCell setCell(shot index);

HSSFCell getCell(shot index);

setRowStyle(HSSFCellStyle style); 設置行樣式

short getLastCellNum(); 獲取最后的單元格號,如果單元格有第一個開始算,lastCellNum就是列的個數

setHeightInPoints(float height); 設置行的高度

HSSFCell:單元格

setCellValue(String value); 設置單元格的值

setCellType(); 設置單元格類型,如 字符串、數字、布爾等

setCellStyle(); 設置單元格樣式

String getStringCellValue(); 獲取單元格中的字符串值

setCellStyle(HSSFCellStyle style); 設置單元格樣式,例如字體、加粗、格式化

setCellFormula(String formula); 設置計算公式,計算的結果作為單元格的值,也提供了異常常用的函數,如求和"sum(A1,C1)"、日期函數、字符串相關函數、CountIf和SumIf函數、隨機數函數等

HSSFCellStyle :單元格樣式

setFont(Font font); 為單元格設置字體樣式

setAlignment(HorizontalAlignment align); // 設置水平對齊方式

setVerticalAlignment(VerticalAlignment align); // 設置垂直對齊方式

setFillPattern(FillPatternType fp);

setFillForegroundColor(short bg); 設置前景色

setFillBackgroundColor(short bg); 設置背景顏色

HSSFFont:字體,

setColor(short color); // 設置字體顏色

setBold(boolean bold); // 設置是否粗體

setItalic(boolean italic); 設置傾斜

setUnderline(byte underline); 設置下划線

HSSFName:名稱

HSSFDataFormat :日期格式化

HSSFHeader : Sheet的頭部

HSSFFooter :Sheet的尾部

HSSFDateUtil :日期工具

HSSFPrintSetup :打印設置

HSSFErrorConstants:錯誤信息表

Excel中的工作簿、工作表、行、單元格中的關系:

一個Excel文件對應於一個workbook(HSSFWorkbook),

一個workbook可以有多個sheet(HSSFSheet)組成,

一個sheet是由多個row(HSSFRow)組成,

一個row是由多個cell(HSSFCell)組成

2. 簡單實現一個Excel工具類,可以修改引用
支持讀取文件夾,批量解析Excel文件;

也支持讀取單個文件,解析單個Excel文件。

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.util.*;



public class ExcelUtil {

private static final Logger logger = LoggerFactory.getLogger(ExcelUtil.class);

private static final String XLS = ".xls";
private static final String XLSX = ".xlsx";

/**
* 根據文件后綴獲取對應Workbook對象
* @param filePath
* @param fileType
* @return
*/
public static Workbook getWorkbook(String filePath,String fileType){
Workbook workbook = null;
FileInputStream fileInputStream = null;
try{
File excelFile = new File(filePath);
if(!excelFile.exists()){
logger.info(filePath+"文件不存在");
return null;
}
fileInputStream = new FileInputStream(excelFile);
if(fileType.equalsIgnoreCase(XLS)){
workbook = new HSSFWorkbook(fileInputStream);
}else if(fileType.equalsIgnoreCase(XLSX)){
workbook = new XSSFWorkbook(fileInputStream);
}
}catch (Exception e){
logger.error("獲取文件失敗",e);
}finally {
try {
if (null != fileInputStream) {
fileInputStream.close();
}
} catch (Exception e) {
logger.error("關閉數據流出錯!錯誤信息:" , e);
return null;
}
}
return workbook;
}

public static List<Object> readFolder(String filePath){
int fileNum = 0;
File file = new File(filePath);
List<Object> returnList = new ArrayList<>();
List<Map<String,String>> resultList = new ArrayList<>();
if (file.exists()) {
File[] files = file.listFiles();
for (File file2 : files) {
if (file2.isFile()) {
resultList = readExcel(file2.getAbsolutePath());
returnList.add(resultList);
fileNum++;
}
}
} else {
logger.info("文件夾不存在");
return null;
}
logger.info("共有文件:"+fileNum);
return returnList;
}

/**
* 批量讀取Excel文件,返回數據對象
* @param filePath
* @return
*/
public static List<Map<String,String>> readExcel(String filePath){
Workbook workbook = null;
List<Map<String,String>> resultList = new ArrayList<>();
try{
String fileType = filePath.substring(filePath.lastIndexOf("."));
workbook = getWorkbook(filePath,fileType);
if(workbook == null){
logger.info("獲取workbook對象失敗");
return null;
}
resultList = analysisExcel(workbook);
return resultList;
}catch (Exception e){
logger.error("讀取Excel文件失敗"+filePath+"錯誤信息",e);
return null;
}finally {
try {
if (null != workbook) {
workbook.close();
}
} catch (Exception e) {
logger.error("關閉數據流出錯!錯誤信息:" , e);
return null;
}

}
}

/**
* 解析Excel文件,返回數據對象
* @param workbook
* @return
*/
public static List<Map<String,String>> analysisExcel(Workbook workbook){
List<Map<String,String>> dataList = new ArrayList<>();
int sheetCount = workbook.getNumberOfSheets();//或取一個Excel中sheet數量
for(int i = 0 ; i < sheetCount ; i ++){
Sheet sheet = workbook.getSheetAt(i);

if(sheet == null){
continue;
}
int firstRowCount = sheet.getFirstRowNum();//獲取第一行的序號
Row firstRow = sheet.getRow(firstRowCount);
int cellCount = firstRow.getLastCellNum();//獲取列數

List<String> mapKey = new ArrayList<>();

//獲取表頭信息,放在List中備用
if(firstRow == null){
logger.info("解析Excel失敗,在第一行沒有讀取到任何數據!");
}else {
for (int i1 = 0; i1 < cellCount; i1++) {
mapKey.add(firstRow.getCell(i1).toString());
}
}

//解析每一行數據,構成數據對象
int rowStart = firstRowCount + 1;
int rowEnd = sheet.getPhysicalNumberOfRows();
for(int j = rowStart ; j < rowEnd ; j ++){
Row row = sheet.getRow(j);//獲取對應的row對象

if(row == null){
continue;
}

Map<String,String> dataMap = new HashMap<>();
//將每一行數據轉化為一個Map對象
dataMap = convertRowToData(row,cellCount,mapKey);
dataList.add(dataMap);
}
}
return dataList;
}

/**
* 將每一行數據轉化為一個Map對象
* @param row 行對象
* @param cellCount 列數
* @param mapKey 表頭Map
* @return
*/
public static Map<String,String> convertRowToData(Row row,int cellCount,List<String> mapKey){
if(mapKey == null){
logger.info("沒有表頭信息");
return null;
}
Map<String,String> resultMap = new HashMap<>();
Cell cell = null;
for(int i = 0 ; i < cellCount ; i ++){
cell = row.getCell(i);
if(cell == null){
resultMap.put(mapKey.get(i),"");
}else {
resultMap.put(mapKey.get(i),getCellVal(cell));
}
}
return resultMap;
}

/**
* 獲取單元格的值
* @param cel
* @return
*/
public static String getCellVal(Cell cel) {
if(cel.getCellType() == Cell.CELL_TYPE_STRING) {
return cel.getRichStringCellValue().getString();
}
if(cel.getCellType() == Cell.CELL_TYPE_NUMERIC) {
return cel.getNumericCellValue() + "";
}
if(cel.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return cel.getBooleanCellValue() + "";
}
if(cel.getCellType() == Cell.CELL_TYPE_FORMULA) {
return cel.getCellFormula() + "";
}
return cel.toString();
}


public static void main(String[] args) {
//讀取文件夾,批量解析Excel文件
System.out.println("--------------------讀取文件夾,批量解析Excel文件-----------------------");
List<Object> returnList = readFolder("C:\\Users\\Administrator\\Desktop\\ExcelTest");
for(int i = 0 ; i < returnList.size() ; i ++){
List<Map<String,String>> maps = (List<Map<String,String>>)returnList.get(i);
for(int j = 0 ; j < maps.size() ; j ++){
System.out.println(maps.get(j).toString());
}
System.out.println("--------------------手打List切割線-----------------------");
}

//讀取單個文件
System.out.println("--------------------讀取並解析單個文件-----------------------");
List<Map<String,String>> maps = readExcel("C:\\Users\\Administrator\\Desktop\\ExcelTest\\學生表.xlsx");
for(int j = 0 ; j < maps.size() ; j ++){
System.out.println(maps.get(j).toString());
}

}
運行結果
文件夾ExcelTest內容:

 

學生表內容:

 

 

用戶表內容:

 

最終運行結果:

 

主要參考博客網址:

https://blog.csdn.net/vbirdbest/article/details/72870714

https://www.cnblogs.com/Dreamer-1/p/10469430.html

https://blog.csdn.net/wangwenjie1997/article/details/90933223

 

https://blog.csdn.net/summerdirewof/article/details/83822710
————————————————
版權聲明:本文為CSDN博主「小白逆流而上」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/baidu_39298625/article/details/105842725


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM