本文介紹了解析EXCEL文件的通用方法的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我需要解析EXCEL文件并從中創建對象列表。為了做同樣的事情,我們正在使用There Aresorg.apache.poi
讀取EXCEL文件,我們能夠獲得所需的詳細信息,目前我們正在根據索引獲取單元格值,并將其設置為對象字段。但我們認為這不是基于索引獲取值的好方法,我們應該找到一種通用的方法來成功解析EXCEL文件,以防添加或刪除一些列,這樣我們就不必在代碼上做太多工作。我遇到了this article,它幾乎滿足了要求,但使用了我們不允許使用的反射方法。有沒有可能在不使用單元格索引的情況下解析EXCEL文件,這樣如果EXCEL文件的格式發生更改,我們就不需要花費太多精力?
public List<DTO> jsonConverter(Workbook workbook, Sheet sheet, String filename)
throws ParseException {
List<DTO> listOfDTOs = new ArrayList<>();
Row row;
for (int index = 1; index <= sheet.getLastRowNum(); index++) {
row = sheet.getRow(index);
if (row != null) {
DTO dto = new DTO();
dto.setFieldX(
getCellValueAsStringBasedOnCellType(
workbook, row.getCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK)));
dto.setFieldY(
getCellValueAsStringBasedOnCellType(
workbook, row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)));
listOfDTOs.add(dto);
}
}
return listOfDTOs;
}
public String getCellValueAsStringBasedOnCellType(Workbook workbook, Cell cell) {
DataFormatter formatter = new DataFormatter();
if (cell != null && cell.getCellType() == CellType.FORMULA) {
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
return formatter.formatCellValue(cell, evaluator);
}
return formatter.formatCellValue(cell);
}
推薦答案
當然。很簡單:
安裝
讀取Excel文件中的第一行,將其視為列,并將每個單元格視為字符串。
將這些存儲在數組中。
現在,您只需使用表達式headers[idx]
即可將任何索引轉換為列名。
因此,對于任何給定的單元格,您都知道標題名稱。現在,您需要將這些知識轉化為正確的預測。假設您在列E(i == 4
)中,頭文件的值是header[4]
,也就是Address
,然后您希望獲取字符串("Address"
)并將其轉換為正確的調用。您最終需要調用:
String cellValue = getCellValueAsStringBasedOnCellType(workbook, row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)));
dto.setFieldAddress(cellValue);
該代碼片段中的所有內容對于該字符串的任何值都是相同的,setFieldAddress
名稱除外。
因此,我們需要將字符串"Address"
轉換為調用setFieldAddress的操作。
解決方案
java.util.function
和用于救援的哈希圖!
這是一種將獲取dto實例并設置地址字段的概念存儲在變量中的方法:
BiConsumer<DTO, String> setAddress = (dto, value) -> dto.setFieldAddress(value);
甚至更簡單:
BiConsumer<DTO, String> setAddress = DTO::setFieldAddress;
這些代碼片段做的是相同的事情:它們不設置地址;它們是如何設置地址的秘訣,并且您將在DTO上設置地址的概念存儲在一個變量中,以便您可以在以后運行它,并且可以想運行多少次就運行多少次。這通常稱為”閉包”或”lambda”。
我們可以將這些內容存儲在地圖中:
Map<String, BiConsumer<DTO, String>> dtoSetters = new HashMap<>();
dtoSetters.put("Address", DTO::setFieldAddress);
然后我們就可以搞清楚了:
int colIdx = ...;
String headerName = header[colIdx];
var setter = dtoSetters.get(headerName);
if (setter == null) throw new IllegalStateException("Unexpected column header in excel sheet: " + headerName);
String cellValue = getCellValueAsStringBasedOnCellType(workbook, row.getCell(1, MissingCellPolicy.CREATE_NULL_AS_BLANK)));
setter.apply(dto, cellValue);
因此,創建該映射(一旦,在系統引導時,例如使用靜態初始值設定項),用上面的代碼替換您的dto.setFieldX
代碼,就可以了。
這篇關于解析EXCEL文件的通用方法的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,