需求:讀excel中的數據,去掉空行,入庫
常用的讀取數據方法當然是用poi了,循環sheet頁,每一行row,每一個單元格cell。獲得的數據再通過反射封裝到對象中。
遇到的坑有:
(1)空行問題:具體情況具體處理吧,如果某一個的每個單元格如果都為空就認為是空行,也有某個單元格為空,就忽略該行的情況。
(2)性能問題:100條左右的數據,從讀取數據到封裝入庫,總共花了20多秒,結果當然是poi速度太慢,雖然是小系統,但是這種速度也是不可忍受的。于是找到eventUserModel方式讀取,見下一節
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.io.FileUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.picc.ermss.controller.UploadController;
import com.picc.ermss.model.Require;
import com.picc.ermss.model.UserSheet;
public class ExcelUtil {
private final static Logger logger = LoggerFactory.getLogger(UploadController.class);
public static Map<String, List<String>> readSheetTitle(File file) {
Map<String, List<String>> sheetTitleMap = new HashMap<String, List<String>>();
Workbook workbook = null;
try {
// 獲取 workbook
workbook = WorkbookFactory.create(FileUtils.openInputStream(file));
// 遍歷 workbook
for (int i=0; i<workbook.getNumberOfSheets(); i++) {
// 獲取某個sheet
Sheet sheet = workbook.getSheetAt(i);
List<String> titleList = new ArrayList<String>();
// 獲取 sheet的第一行 表頭
Row firstRow = sheet.getRow(0);
if(firstRow == null) {
continue;
}
// 遍歷第一行的每個cell
for (int j=0; j<firstRow.getLastCellNum(); j++) {
Cell cell = firstRow.getCell(j);
String title = cell.getStringCellValue().trim();
if (!"".equals(title)) {
// 標題不為空,才添加到 titleList
titleList.add(title);
}
}
sheetTitleMap.put(sheet.getSheetName(), titleList);
}
} catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
logger.info(e.getMessage());
} finally {
try {
if(workbook != null) {
workbook.close();
}
} catch (IOException e) {
logger.error(e.getMessage());
}
}
return sheetTitleMap;
}
private static Sheet sheet = null;
private static Row rowFirst = null;
private static Row row = null;
private static Map<String, String> objectMap = new HashMap<String, String>();
private static String title = "";
private static String value = "";
// 解析excel,返回List<Map<String, String>>格式的對象
public static List<Map<String, String>> parseExcelData(List<UserSheet> userSheetListChanged, File file) {
logger.info("開始方法-----解析excel成List<Map<String, String>>對象");
logger.info("獲取workbook");
List<Map<String, String>> resultList = new LinkedList<Map<String, String>>();
Workbook workbook = null;
// 獲取 workbook
try {
workbook = WorkbookFactory.create(FileUtils.openInputStream(file));
} catch (EncryptedDocumentException | InvalidFormatException | IOException e) {
e.printStackTrace();
}
logger.info("開始解析數據,并添加到list中");
for (UserSheet userSheet : userSheetListChanged) {
// 根據名字獲取sheet
logger.info("要解析的sheetname:" + userSheet.getSheetname());
sheet = workbook.getSheet(userSheet.getSheetname());
// 獲取第一行
rowFirst = sheet.getRow(0);
// 遍歷每一行sheet.getPhysicalNumberOfRows()
for(int rowIndex = 1; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
logger.info("遍歷第" + rowIndex + "行");
row = sheet.getRow(rowIndex);
// 每一行 對應一個 ObjectMap
objectMap.clear();
// 遍歷數據行里的每一個單元格,遍歷長度以第一行為準
for(int cellIndex=0;cellIndex < rowFirst.getPhysicalNumberOfCells();cellIndex++){ //cell
title = rowFirst.getCell(cellIndex).getStringCellValue();
// 給sheetid賦值
if("sheetid".equals(title)) {
value = userSheet.getSheetid();
}
// 給serialno賦值
if("serialno".equals(title)) {
value = String.valueOf(rowIndex);
}
Cell cell = row.getCell(cellIndex);
if(cell != null) {
cell.setCellType(Cell.CELL_TYPE_STRING);
value = cell.getStringCellValue();
}
// 把每個單元格里的值都放到map里
objectMap.put(title, value);
}
// 過濾空行
Set<Entry<String,String>> entrySet = objectMap.entrySet();
int sum = 0;
int actualSum = entrySet.size();
for(Entry<String,String> entry : entrySet) {
String value = entry.getValue();
if("".equals(value) || value == null) {
sum += 1;
}
}
if(actualSum - sum == 2) {
//resultList.add(objectMap);
break;
} else {
resultList.add(objectMap);
}
}
}
logger.info("結束方法-----解析excel成List<Map<String, String>>對象");
return resultList;
}
/**
* 利用反射將 List<Map<String,String>>結構 生成相應的List<T>數據
*
* */
public static <T> List<T> toObjectList(List<Map<String, String>> list, Class<T> clazz) {
List<T> returnList = new LinkedList<T>();
for(int i=0; i<list.size(); i++){
Set<Map.Entry<String, String>> set = list.get(i).entrySet();
Iterator<Entry<String, String>> iterator = set.iterator();
// 生成一個對象實例
T obj = null;
try {
obj = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Method[] methods = clazz.getDeclaredMethods();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
for(Method m : methods){
if(m.getName().startsWith("set")) {
String methodName = entry.getKey().toString();
StringBuffer sb = new StringBuffer(methodName);
sb.replace(0, 1, (methodName.charAt(0)+"").toUpperCase());
// 獲取set方法
methodName = "set" + sb.toString();
if(methodName.equals(m.getName())) {
try {
// 調用set方法,給對象賦值
m.invoke(obj, entry.getValue());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
break;
}
}
}
}
returnList.add(obj);
}
System.out.println("size=" + returnList.size());
return returnList;
}
public static void main(String[] args) {
// System.out.println(ExcelUtil.class.getResource("/").getPath().substring(1));
// File file = new File("C:/Users/Administrator/Desktop/說明文檔2/xxxx.xlsx");
// System.out.println(readSheetTitle_HSSF(file));
List<UserSheet> usersheetList = new ArrayList<UserSheet>();
UserSheet sheet = new UserSheet();
sheet.setSheetid("024e1efd-0c2b-4484-b807-e12ce9f0263a");
sheet.setSheetname("需求提驗升級時間");
usersheetList.add(sheet);
File file = new File("D:/profiles/sts-bundle/workspace20170628/ermss/target/classes/aaa.xlsx");
List<Map<String, String>> list = parseExcelData(usersheetList, file);
System.out.println(list);
try {
System.out.println(toObjectList(list, Require.class));
} catch (Exception e) {
e.printStackTrace();
}
}
}