封裝poi讀取excel的超強工具類,支援一行程式碼獲取excel內容
阿新 • • 發佈:2019-01-12
時隔多年,再次更新下部落格。特貢獻一份poi讀取excel的超強工具類,一行程式碼讀取excel的封裝。包括讀、寫等操作。具體還是跟著程式碼看吧。
- ExcelReadDealUtils:excel讀取處理工具類
package all.file.excel.util;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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;
/**
*
* Excel檔案讀取封裝 使用說明:<br>
* 1、使用loadExcelFile(String excelFilePath)方法載入Excel檔案,即可使用workbook靜態物件;<br>
* 2、使用closeDestory()方法銷燬檔案流,即呼叫該方法後,類資源不可用;<br>
* 3、使用Map<Object, Object> getRowDataToMap(Row row, boolean isValueKey), 需瞭解引數isValueKey的意義,獲取Excel檔案一行的內容,以Map儲存,該方法常用於Excel表格頭列的獲取;<br>
* 4、使用List<String> getRowDataToList(Row row)方法 獲取Excel檔案一行的內容,以List儲存,List可包含重複值,常用於正文內容的獲取;<br>
* 5、使用Map<Object, List<String>> getBatchRowDataToList(Sheet sheet, int startRowIndex, int endRowIndex) 批量查詢,獲取Excel檔案中指定開始下標索引與結束下標索引號之間的內容;<br>
* 6、使用Object getCellValue(Cell cell)方法獲取指定單元格的內容;<br>
* 7、使用getGivenSheetDatas(String excelFilePath, String[] sheetNames, int headIndex, String[] attributes, boolean isMerge, String[] mergeAttributes)<br>
* 獲取指定Excel檔案、指定Sheet集、指定表格列集、指定需要合併列的內容 ,適用於較大資料,使用該方法不需要loadExcelFile()以及closeDestory()方法; 整個的載入Excel檔案與關閉、銷燬檔案流自動在方法體完成;
* 8、使用getByGivenAttributeAndRowValue(Map<Object, Object> headDataMap, Row row, String[] attributes) 獲取一行指定列的資料集;<br>
* 9、使用getMergeCellRowsData(Sheet sheet, Map<Object, Object> headRowData, int rowIndex, String[] attributes, String mergeAttribute, boolean isMerge, String[] mergeAttributes) 根據指定Sheet表及開始行進行獲取一個合併單元集;<br>
* 10、使用getCellToDate(Object cellDateValue)將讀取到的Cell單元格為日期型別時,通過表示5位數的Double型別,轉換成Java的Date <br>
* 11、使用deleteRows(Sheet sheet, int startRow, int endRow)方法刪除指定開始至結束行,並儲存至原路徑中;<br>
* 12、使用getExcelWorkbook()方法獲取載入Excel檔案後的Workbook物件<br>
*
* 注意:deleteRows方法未完善,由於此方法不用於查詢的功能範圍內
* @author qiqitrue
* @version 1.0
* @since 2015-1-5
*/
public class ExcelReadDealUtils extends ExcelCommon {
/**
* excel工作物件
*/
public static Workbook workbook;
/**
* excel檔案流,用於closeDestory銷燬一次開啟會話
*/
private static FileInputStream fis;
/**
* 使用示例
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// 載入excel檔案物件
loadExcelFile("D:/新建 Microsoft Excel 工作表.xlsx");
// 獲取指定sheet名稱的excel Sheet物件
Sheet sheet = workbook.getSheet("Sheet1");
// 驗證是否存在,有些時候沒有必要驗證
if (isExistSheet(sheet)) {
// 獲取Sheet最後行號
int lastRowNum = sheet.getLastRowNum();
// 獲取表頭轉換成Map形式儲存
Map<Object, Object> headMap = getRowDataToMap(sheet.getRow(0), true);
// 定義要獲取Excel中的表頭列
String[] attributes = new String[] { "關聯ID", "英文名", "中文名", "時間",
"颱風編號", "強度等級", "緯度", "經度", "風速", "陣風", "氣壓", "風向", "移速",
"6級風圈", "7級風圈", "8級風圈", "10級風圈" };
// 從索引為2開始,需注意根據實際情況來定
for (int i = 2; i <= lastRowNum; i++) {
// 獲取行物件
Row row = sheet.getRow(i);
// 驗證是否存在行
if (isExistRow(row)) {
// 獲取一行指定列的資訊
List<Object> byGivenAttributeAndRowValue = getByGivenAttributeAndRowValue(headMap, row, attributes);
for (int j = 0; j < byGivenAttributeAndRowValue.size(); j++) {
// 特殊的單元格,日期處理
if (j == 3) {
System.out.print(getCellToDate(byGivenAttributeAndRowValue.get(j)) + "\t");
}
// 普通的單元格,轉換成字串輸出
else {
System.out.print(String.valueOf(byGivenAttributeAndRowValue.get(j)) + "\t");
}
}
System.out.println();
}
}
}
// 銷燬開啟會話的檔案
closeDestory();
}
/**
*
* 載入Excel檔案,建立Workbook物件
*
* @param excelFilePath
* Excel檔案路徑
*/
public static void loadExcelFile(String excelFilePath) {
try {
fis = new FileInputStream(excelFilePath);
if (excelFilePath.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(fis);
} else if (excelFilePath.endsWith(".xls")) {
workbook = new HSSFWorkbook(fis);
} else {
throw new RuntimeException("錯誤提示: 您設定的Excel檔名不合法!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 獲取Excel檔案的Workbook物件
* @return
*/
public static Workbook getExcelWorkbook(){
if(!isExist(workbook)){
throw new RuntimeException("錯誤提示:請先進行Excel載入,初始化Workbook物件!");
}
return workbook;
}
/**
*
* 關閉Excel檔案流
* @throws IOException
*/
public static void closeDestory() throws IOException {
if(fis == null){
throw new RuntimeException("錯誤提示:Excel檔案未載入或未初始化檔案!");
}
fis.close();
}
/********************************************row行操作********************************************/
/**
*
* 獲取一行的內容,Map儲存,儲存方式由引數定義
*
* @param row
* 行物件
* @param isValueKey
* 是否以單元格內容作為Key?key為單元格內容, value為下標索引:key為下標索引, value為單元格內容
* @return 一行的內容,Map儲存
*/
public static Map<Object, Object> getRowDataToMap(Row row, boolean isValueKey) {
Map<Object, Object> headDatas = new HashMap<Object, Object>();
short countCellNum = row.getLastCellNum();
// 在外面判斷isValueKey是為了提高效率,放在迴圈體中降低效率
if (isValueKey) {
for (int j = 0; j < countCellNum; j++) {
Cell cell = row.getCell(j);
if (isExistCell(cell)) {
// Key=單元格內容, Value=下標索引
headDatas.put(getCellValue(cell), j);
}
}
} else {
for (int j = 0; j < countCellNum; j++) {
Cell cell = row.getCell(j);
if (isExistCell(cell)) {
// Key=下標索引, Value=單元格內容
headDatas.put(j, getCellValue(cell));
}
}
}
return headDatas;
}
/**
*
* 獲取一行的內容,List儲存
*
* @param row
* 行物件
* @return 一行的內容
*/
public static List<Object> getRowDataToList(Row row) {
List<Object> rowData = new ArrayList<Object>();
if (isExistRow(row)) {
short countCellNum = row.getLastCellNum();
for (int i = 0; i < countCellNum; i++) {
Cell cell = row.getCell(i);
if (isExistCell(cell)) {
rowData.add(getCellValue(cell));
}
}
}
return rowData;
}
/**
*
* 獲取sheet批量行內容,以List儲存
*
* @param sheet
* Sheet表物件
* @param startRowIndex
* 開始行下標索引號
* @param endRowIndex
* 結束行下標索引號
* @return 批量內容行內容
*/
public static List<List<Object>> getBatchRowDataToList(Sheet sheet, int startRowIndex, int endRowIndex) {
List<List<Object>> batchDatas = new ArrayList<List<Object>>();
if(startRowIndex > endRowIndex){
throw new RuntimeException("錯誤提示:開始行不能大於結束行!");
}
// 獲取sheet總行數
int lastRowNum = sheet.getLastRowNum();
if(startRowIndex > lastRowNum || endRowIndex > lastRowNum){
throw new RuntimeException("錯誤提示:開始行或結束行不能超過sheet最大行數!");
}
for (int i = startRowIndex; i <= endRowIndex; i++) {
Row row = sheet.getRow(i);
batchDatas.add(getRowDataToList(row));// 此處不需要驗證row是否為空,在底層getRowData已驗證
}
return batchDatas;
}
/**
*
* 獲取指定Excel檔案、指定Sheet集、指定表格列集、指定需要合併列的資料
*
* @param excelFilePath
* Excel檔案路徑,包括Excel檔名
* @param sheetNames
* 要解析的Sheet名稱集,null表示全部獲取
* @param headIndex
* Sheet表頭下標,從0開始
* @param attributes
* 需要獲取Excel列
* @param isMerge
* 是否需要合併的列,若為false,mergeAttributes可設定為null
* @param mergeAttributes
* 需要合併的列(在需要獲取Excel列中)
* @return 整個Excel處理後的資料
* @throws IOException
*/
public static List<List<Object>> getGivenSheetDatas(String excelFilePath, String[] sheetNames, int headIndex, String[] attributes, boolean isMerge, String[] mergeAttributes) throws IOException {
// 定義儲存Excel內容集合,List<Object>表示一行的內容
List<List<Object>> excelDatas = new ArrayList<List<Object>>();
// 列表頭,key=單元格內容,value=列下標索引號
Map<Object, Object> headDatasMap = new HashMap<Object, Object>();
// 載入檔案
loadExcelFile(excelFilePath);
// 定義需進行解析的Sheet集
List<Sheet> sheets = new ArrayList<Sheet>();
// 按指定的Sheet進行解析
if (sheetNames != null) {
for (int i = 0; i < sheetNames.length; i++) {
// 獲取第i個Sheet表物件
Sheet sheet = workbook.getSheet(sheetNames[i]);
if (!isExistSheet(sheet)) {
throw new RuntimeException("錯誤提示: 您指定的Sheet集中的【" + sheetNames[i] + "】不存在,請檢查原Excel檔案!");
}
// 新增至解析的Sheet集中
else {
sheets.add(sheet);
}
}
}
// 沒有指定Sheet,則全部
else {
int length = workbook.getNumberOfSheets();
for (int i = 0; i < length; i++) {
Sheet sheet = workbook.getSheet(workbook.getSheetName(i));
sheets.add(sheet);
}
}
// 以上是獲取需要讀取的Sheet表
for (Sheet sheet : sheets) {
// 獲取表頭列行是否存在
Row headRow = sheet.getRow(headIndex);
if (headRow == null) {
System.out.println("錯誤提示: 您指定的表格列頭行【" + headIndex + "】不存在!");
}
// 存在著指定的表頭列行
else {
// 轉換成Map,Key=表頭列名稱,Value=列名稱下標索引
headDatasMap = getRowDataToMap(headRow, true);
int eqCount = 0;// 實際存在的列個數
// 定義需要獲取到的列在實際中不存在的列集合
List<String> noEqAttributes = new ArrayList<String>();
for (String attribute : attributes) {
if (headDatasMap.get(attribute) != null) {
eqCount++;
}
// 不存在的列數
else {
noEqAttributes.add(attribute);
}
}
System.out.println("提示:Sheet表名稱為[" + sheet.getSheetName() + "]中需匯入的列數與存在的列數之比:" + attributes.length + ":" + eqCount);
if (attributes.length != eqCount) {
System.out.println("錯誤提示: 實際不存在的屬性集(程式中需要獲取的列在Sheet中不存在的列):");
for (int j = 0; j < noEqAttributes.size(); j++) {
System.out.print(noEqAttributes.get(j) + "\t");
}
System.out.println();
}
// 全部等於進行解析該Sheet頁的所有內容
else {
// 獲取當前Sheet表總行數
int rowCount = sheet.getLastRowNum();
// 從索引號為列頭行號索引+1開始進行讀取
for (int k = (headIndex + 1); k <= rowCount; k++) {
Row row = sheet.getRow(k);
if (!isExistRow(row)) {
System.out.println("錯誤提示: 在第" + k + "行出現空行。");
continue;
}
// 一行資料
List<Object> rowDatas = getByGivenAttributeAndRowValue(headDatasMap, row, attributes);
excelDatas.add(rowDatas);// 新增一行資料
}
}
}
}
// 需要合併
if (isMerge) {
// 記錄需要合併的列Index
List<Integer> mergerIndex = new ArrayList<Integer>();
for (String mergerAttribute : mergeAttributes) {
Integer integerIndex = (Integer) headDatasMap.get(mergerAttribute);
if (integerIndex != null) {
mergerIndex.add(integerIndex);
}
}
for (int i = 0; i < excelDatas.size(); i++) {
List<Object> rowDatas = excelDatas.get(i);
for (int j = 0; j < mergerIndex.size(); j++) {
if (rowDatas.get(mergerIndex.get(j)).equals("")) {
// 在第一行不為空的情況下
if (i != 0) {
Object value = excelDatas.get(i - 1).get(mergerIndex.get(j));
rowDatas.set(mergerIndex.get(j), value);
}
}
}
}
}
closeDestory();
return excelDatas;
}
/**
*
* 獲取一行指定列的資料集
*
* @param headDataMap
* 表列頭Map資料,key=單元格內容,value為下標索引號
* @param row
* 需獲取的指定行
* @param attributes
* 需獲取的指定單元格
* @return 一行指定列的資料集
*/
public static List<Object> getByGivenAttributeAndRowValue(Map<Object, Object> headDataMap, Row row, String[] attributes) {
List<Object> datas = new ArrayList<Object>();
for (int i = 0; i < attributes.length; i++) {
Integer index = (Integer) headDataMap.get(attributes[i]);
if(index == null){
System.out.println("查詢列:"+attributes[i]+"失敗!");
}
else{
Cell cell = row.getCell(index);
Object cellValue = getCellValue(cell);
if (cellValue == null) {
cellValue = "";
}
datas.add(cellValue);
}
}
return datas;
}
/**
*
* 根據指定Sheet表及開始行進行獲取一個合併單元集,若沒理解,好比是從資料庫中只取一個表,並把表的所有欄位返回
*
* @param sheet
* 指定Sheet表物件
* @param headRowData
* 表頭列,使用getRowDataToMap(Row, boolean)方法獲取
* @param rowIndex
* 開始行物件,即有內容的開始行
* @param attributes
* 需要獲取的單元格列物件
* @param mergeAttribute
* 根據那一個單元格進行合併
* @param isMerge
* 是否需要合併
* @param mergeAttributes
* 需要合併的單元格集
* @return 返回一個合併單元集
*/
public static List<List<Object>> getMergeCellRowsData(Sheet sheet,Map<Object, Object> headRowData, int rowIndex, String[] attributes, String mergeAttribute, boolean isMerge, String[] mergeAttributes) {
List<List<Object>> rowsData = null;
// 需要獲取的單元格列名稱在表格表頭行中完全存在
if (headRowData.keySet().containsAll(Arrays.asList(attributes))) {
Row row = sheet.getRow(rowIndex);
// 存在的列索引
Integer existCellIndex = (Integer) headRowData.get(mergeAttribute);
Cell cell = row.getCell(existCellIndex);
Object cellValue = getCellValue(cell);
if (String.valueOf(cellValue).isEmpty()) {// 值是空的
System.out.println("錯誤提示: 給定的行【" + rowIndex + "】的【"+ mergeAttribute + "】為空, 請檢查!");
} else {
rowsData = new ArrayList<List<Object>>();
rowsData.add(getByGivenAttributeAndRowValue(headRowData, row, attributes));// 第一行
while (true) {
Row row2 = sheet.getRow(++rowIndex);
Cell cell2 = row2.getCell(existCellIndex);
if (String.valueOf(getCellValue(cell2)).isEmpty()) {
rowsData.add(getByGivenAttributeAndRowValue(headRowData, row2, attributes));
} else {
// 需要合併
if (isMerge) {
// 記錄需要合併的列Index
List<Integer> mergerIndex = new ArrayList<Integer>();
for (String mergerAttribute : mergeAttributes) {
Integer integerIndex = (Integer) headRowData.get(mergerAttribute);
if (integerIndex != null) {
mergerIndex.add(integerIndex);
}
}
for (int i = 0; i < rowsData.size(); i++) {
List<Object> rowDatas = rowsData.get(i);
for (int j = 0; j < mergerIndex.size(); j++) {
if (rowDatas.get(mergerIndex.get(j)).equals("")) {
// 在第一行不為空的情況下
if (i != 0) {
Object value = rowsData.get(i - 1).get(mergerIndex.get(j));
rowDatas.set(mergerIndex.get(j), value);
}
}
}
}
}
return rowsData;
}
}
}
} else {
System.out.println("錯誤提示: 要獲取表頭列在【" + sheet.getSheetName() + "】中的列頭不完全存在, 請檢查!");
}
return rowsData;// 此時這裡是返回Null
}
/**
*
* 將讀取到的Cell單元格為日期型別時,通過表示5位數的Double型別,轉換成Java的Date
*
* @param cellDateValue
* 單元格日期型別
* @return 返回Java Date型別
*/
public static Date getCellToDate(Object cellDateValue) {
if(cellDateValue == null || cellDateValue.equals("")){
return null;
}
double parseDouble = Double.parseDouble(cellDateValue.toString());
Date javaDate = HSSFDateUtil.getJavaDate(parseDouble);
return javaDate;
}
/**
*
* 指定Sheet表中進行刪除指定開始到結束行中間的行
*
* @param sheet
* 指定的Sheet表
* @param startRow
* 指定的開始行
* @param endRow
* 指定的結束行
*/
public static void deleteRows(Sheet sheet, int startRow, int endRow) {
int lastRowNum = sheet.getLastRowNum();
// 開始刪除行與結束刪除行的範圍在該Sheet裡
if (startRow < lastRowNum && endRow < lastRowNum) {
sheet.shiftRows(startRow, endRow, -1);// 刪除從startRow行到endRow行,然後使下方單元格上移
}
// 待新增儲存處理
}
/**
*
* 指定Sheet表中查詢關鍵字
*
* @param sheet
* 指定Sheet表
* @param keyWord
* 查詢的關鍵字
* @param isGoEnd
* 是否一找到底,如果找到一個了,就返回,還是繼續找
* @return 返回控制檯提示資訊
*/
public static String isExistKeyWord(Sheet sheet, String keyWord, boolean isGoEnd) {
if (isExistSheet(sheet)) {
StringBuffer sbf = new StringBuffer();
int findCount = 0;
int lastRowNum = sheet.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
if (isExistRow(row)) {
short lastCellNum = row.getLastCellNum();
for (int j = 0; j <= lastCellNum; j++) {
Cell cell = row.getCell(j);
if (isExistCell(cell)) {
Object cellValue = getCellValue(cell);
if (cellValue == null) {
continue;
} else {
if (String.valueOf(cellValue).contains(keyWord)) {
// 整個Sheet不停歇地找
if (isGoEnd) {
findCount++;
// 此處需加一個換行符
StringBuffer temp = new StringBuffer("提示:在Sheet表為【"+ sheet.getSheetName() + "】中的第【" + i + "】行【" + j + "】列查詢到關鍵字【" + keyWord + "】\n");
System.out.println(temp.toString());
sbf.append(temp);
} else {
return "提示:在Sheet表為【" + sheet.getSheetName() + "】中的第【" + i + "】行【" + j + "】列查詢到關鍵字【" + keyWord + "】";
}
}
}
}
}
}
}
System.out.println("查詢結束提示:在Sheet表為【" + sheet.getSheetName() + "】中總計找到關鍵字【" + keyWord + "】個數:" + findCount);
return sbf.toString();
}
return null;// 即表示不存在
}
}
- ExcelWriterDealUtils.java excel寫的處理工具類(水平不太好請勿介意)
package all.file.excel.util;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.RichTextString;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import all.file.util.FileComonDealUtils;
/**
*
* Excel檔案寫入封裝 使用說明:<br>
* 1、使用loadWorkbook(String excelFilePath)方法載入Workbook工作薄物件,即可使用靜態workbook物件;<br>
* 2、使用saveFile()方法儲存Workbook內容到檔案中,並關閉檔案流; <br>
* 3、使用setRowValue(Row row, List<Object> rowData)方法設定一行資料,並返回修改後的Row行物件; <br>
* 4、使用setCellValue(Cell cell, Object value)方法設定單元格值,並返回修改後的Cell單元格物件; <br>
* 5、使用createCellStyle(boolean isContentStyle)方法建立單元格樣式,isContentStyle設定是否為文字樣式,還有一種是表頭樣式;<br>
* 6、使用setSheetAndHead(String sheetName, String[] headCellContent)方法同時建立Sheet並設定一行列頭;起到簡化的作用,返回Sheet;<br>
* 7、使用setGivenRowDatas(Sheet sheet, int startRowIndex, List<List<Object>> rowsDatas方法設定從給定Sheet表、給定開始行批量新增、更新內容<br>
* 8、使用isExistRow(Row row)方法驗證一行物件是否存在,返回Boolean結果;<br>
* 9、使用isExistRow(Sheet sheet, int rowIndex)方法驗證指定Sheet表下的下標索引行是否存在,存在則返回原行物件,不存在則建立Row物件後返回 <br>
* 10、使用isExistCell(Cell cell)方法驗證一單元格是否存在 ,返回Boolean結果 <br>
* 11、使用isExistCell(Row row, int cellIndex)方法驗證指定Row行的單元格下標索引是否存在,存在則返回原單元格物件,不存在則建立單元格物件後返回 <br>
* 12、使用saveFile(Workbook workbook, String saveExcelPath)方法進行儲存,此方法是該類中的saveFile()方法的擴充套件,適用於外部,並適用於空內容的Exce檔案操作;
*
* @author 賴奇
* @version 1.0
* @since 2014-6-26
*/
public class ExcelWriterDealUtils extends ExcelCommon {
/**
* 工作薄物件
*/
protected static Workbook workbook;
/**
* 寫入Excel檔案路徑
*/
protected static String excelFilePath;
/**
* 檔案讀取流
*/
private static FileInputStream fis;
/**
*
* 載入Workbook工作薄物件,即可使用靜態workbook物件
*
* @param excelFilePath
* Excel檔案路徑
*/
public static void loadWorkbook(String excelFilePath) {
// try
// {
ExcelWriterDealUtils.excelFilePath = excelFilePath;
// saveFile(new XSSFWorkbook() , excelFilePath);
// fis = new FileInputStream(excelFilePath);
if (excelFilePath.endsWith(".xlsx")) {
workbook = new XSSFWorkbook();
} else if (excelFilePath.endsWith(".xls")) {
workbook = new HSSFWorkbook();
}
// }
// catch (IOException e)
// {
// e.printStackTrace();
// }
}
/**
*
* 儲存Workbook內容到檔案中
*/
public static void saveFile() {
FileOutputStream fos = null;
try {
if (fis != null) {
fis.close();// 先關閉
}
fos = new FileOutputStream(excelFilePath);
workbook.write(fos);
fos.flush();
System.out.println(excelFilePath + ":檔案寫入成功...");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();// 關閉讀取流
}
if (fos != null) {
fos.close();// 關閉檔案流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*
* 儲存一個為Excel的檔案
*
* @param workbook
* 工作薄物件
* @param saveExcelPath
* 儲存到Excel的檔案路徑
*/
public static void saveFile(Workbook workbook, String saveExcelPath) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(FileComonDealUtils
.createFile(saveExcelPath));
workbook.createSheet("Sheet1");
workbook.write(fos);
fos.flush();
// System.out.println(excelFilePath + ":檔案寫入成功...");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();// 關閉檔案流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*
* 設定一行的資料,返回設定後的行物件
*
* @param row
* 行物件
* @param rowData
* 行資料
* @return 設定後的行物件
*/
public static Row setRowValue(Row row, List<Object> rowData) {
for (int i = 0; i < rowData.size(); i++) {
Cell cell = isExistCell(row, i);
setCellValue(cell, rowData.get(i));
}
return row;
}
/**
*
* 設定單元格值
*
* @param cell
* 需要設定的單元格
* @param value
* 設定給單元格cell的值
* @return 設定好的單元格列物件
*/
public static Cell setCellValue(Cell cell, Object value) {
if (value instanceof String) {
cell.setCellValue((String) value);
cell.setCellType(Cell.CELL_TYPE_STRING);
} else if (value instanceof Date) {
cell.setCellValue((Date) value);
cell.setCellType(Cell.CELL_TYPE_STRING);
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
cell.setCellType(Cell.CELL_TYPE_BOOLEAN);
} else if (value instanceof Double) {
cell.setCellValue((Double) value);
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
} else if (value instanceof Calendar) {
cell.setCellValue((Calendar) value);
cell.setCellType(Cell.CELL_TYPE_STRING);
} else if (value instanceof RichTextString) {
cell.setCellValue((RichTextString) value);
cell.setCellType(Cell.CELL_TYPE_STRING);
} else {
cell.setCellValue(String.valueOf(value));
cell.setCellType(Cell.CELL_TYPE_STRING);
// System.out.println("錯誤提示: 您設定的單元格內容【"+value+"】不符合要求,不是常用型別!");
}
return cell;
}
/**
*
* 建立單元格樣式: 內容樣式、表格列頭樣式
*
* @param isContent
* 是否為內容樣式
* @return 單元格樣式
*/
public static CellStyle createCellStyle(boolean isContentStyle) {
CellStyle cellStyle = workbook.createCellStyle();
if (isContentStyle) {
} else {
}
return cellStyle;
}
/**
*
* 建立指定的Sheet表名稱及表頭,返回Sheet表物件
*
* @param sheetName
* Sheet表名稱
* @param headCellContent
* 表頭列屬性
* @return 返回建立好後的Sheet表物件
*/
public static Sheet setSheetAndHead(String sheetName,
String[] headCellContent) {
Sheet sheet = isExistSheet(sheetName);
Row headRow = isExistRow(sheet, 0);
List<Object> headRowDatas = new ArrayList<Object>();
for (String headCellValue : headCellContent) {
headRowDatas.add(headCellValue);
}
setRowValue(headRow, headRowDatas);
return sheet;
}
/**
*
* 設定從給定Sheet表、給定開始行批量新增、更新內容,返回結束行下標索引
*
* @param sheet
* 指定Sheet表
* @param startRowIndex
* 新增、更新開始行索引號
* @param rowsDatas
* 行內容資料
* @return 返回Sheet表更新、新增後的行號
*/
public static int setGivenRowDatas(Sheet sheet, int startRowIndex,
List<List<Object>> rowsDatas) {
int rowSize = rowsDatas.size();
int endIndex = startRowIndex + rowSize;
for (int i = 0; i < rowSize; i++) {
Row row = isExistRow(sheet, startRowIndex + i);
setRowValue(row, rowsDatas.get(i));
}
return endIndex;
}
/**
*
* 驗證指定Sheet表名稱是否存在,存在則返回原Sheet表物件,不存在則建立Sheet表物件後返回
*
* @param sheetName
* 需要驗證的Sheet表名稱
* @return Sheet表(存在就返回,不存在就新建)
*/
public static Sheet isExistSheet(String sheetName) {
Sheet sheet = workbook.getSheet(sheetName);
if (sheet == null) {
return workbook.createSheet(sheetName);
} else {
System.out.println("錯誤提示: 您設定的Sheet表名稱【" + sheetName
+ "】已存在,請重新設定!");
return sheet;
}
}
/**
*
* 驗證指定Sheet表下的下標索引行是否存在,存在則返回原行物件,不存在則建立Row物件後返回
*
* @param sheet
* 指定的Sheet物件
* @param rowIndex
* 指定的下標索引行號
* @return Row行(存在就返回,不存在就新建)
*/
public static Row isExistRow(Sheet sheet, int rowIndex) {
Row row = sheet.getRow(rowIndex);
if (row == null) {
return sheet.createRow(rowIndex);
} else {
// System.out.println("警告提示: 您設定的Sheet表名稱【"+sheet.getSheetName()+"】中的第【"+rowIndex+"】行已存在!");
return row;
}
}
/**
*
* 驗證指定Row行的單元格下標索引是否存在,存在則返回原單元格物件,不存在則建立單元格物件後返回
*
* @param row
* 指定的Row行物件
* @param cellIndex
* 指定的下標索引單元格列號
* @return Cell行(存在就返回,不存在就新建)
*/
public static Cell isExistCell(Row row, int cellIndex) {
Cell cell = row.getCell(cellIndex);
if (cell == null) {
return row.createCell(cellIndex);
} else {
System.out.println("指定的列已存在");
return cell;
}
}
/**
*
* 設定單元格合併
*
* @param sheet
* 指定合併的Sheet表
* @param firstRow
* 開始行
* @param lastRow
* 結束行
* @param firstCol
* 開始列
* @param lastCol
* 結束列
*/
public static void setCellMerge(Sheet sheet, int firstRow, int lastRow,
int firstCol, int lastCol) {
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol,
lastCol));
}
/**
*
* 設定指定列的單元格內如如果相同則進行單元格合併(需修改)
*
* @param sheet
* Sheet表
* @param headRowData
* 開始行資料
* @param mergeCells
* 合併的單元格列
* @param startRow
* 開始行
*/
public static void setCellMerge(Sheet sheet,
Map<Object, Object> headRowData, String[] mergeCells, int startRow) {
if (headRowData.keySet().containsAll(Arrays.asList(mergeCells))) {
int lastRowNum = sheet.getLastRowNum();
if (lastRowNum > 0) {
int temp = startRow;
for (String mergeCell : mergeCells) {
Integer cellIndex = (Integer) headRowData.get(mergeCell);
Row row = sheet.getRow(startRow);
if (row == null) {
continue;
}
Cell cell2 = row.getCell(cellIndex);
if (cell2 == null) {
continue;
}
Object cellValue = getCellValue(cell2);
int startMergerIndex = startRow;
while (startRow < (lastRowNum - 1)) {
Row eqRow = sheet.getRow(++startRow);
Cell cell = eqRow.getCell(cellIndex);
Object cellValue2 = getCellValue(cell);
System.out.println(cellValue + "\t" + cellValue2);
// 相同進行合併
if (!cellValue2.equals(cellValue)) {
System.out.println("裡:" + startMergerIndex + "\t"
+ lastRowNum + "\t" + cellIndex + "\t"
+ cellIndex);
setCellMerge(sheet, startMergerIndex, startRow - 1,
cellIndex, cellIndex);
startMergerIndex = startRow;
cellValue = cellValue2;
}
}
System.out.println(startMergerIndex + "\t" + lastRowNum
+ "\t" + cellIndex + "\t" + cellIndex);
setCellMerge(sheet, startMergerIndex, lastRowNum,
cellIndex, cellIndex);
startRow = temp;
}
}
} else {
System.out.println("錯誤提示: 你需要合併的列不存在!");
}
}
}
- ExcelCommon.java涉及到的公共封裝類
package all.file.excel.util;
import<