最近遇到一個新需求,關於使用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,如果你真的用到了,可以仔細閱讀文檔