今天我封裝了一下POI工具類
可以用這個工具類解析xls並生成List
可以通過list和標題來生成xls文件
首先是生成xls文件的部分
public static <T> void generateXls(OutputStream os,String title, Map<Integer,String> titleMap, List<T> list) throws IOException, IllegalAccessException {
//首先生成標題
HSSFWorkbook book=new HSSFWorkbook();
generateTitle(book,title,titleMap.size());
generateTableTitle(book,titleMap);
generateData(book,list);
book.write(os);
}
這裏先創建一個workbook
然後調用生成表頭,標題以及數據的方法
private static void generateTitle(HSSFWorkbook book, String title,int col) {
//準備樣式
HSSFCellStyle cellStyle = book.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setFillForegroundColor(IndexedColors.RED.index);
//創建字體,這裏還能設置字體呢,不光能設置大小
HSSFFont font = book.createFont();
font.setFontHeight((short) 440);
cellStyle.setFont(font);
book.createSheet();
HSSFSheet sheetAt = book.getSheetAt(0);
HSSFRow row = sheetAt.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue(title);
sheetAt.addMergedRegion(new CellRangeAddress(0,0,0,col));
cell.setCellStyle(cellStyle);
}
生成標題的話就先創建樣式,然後設置字體大小,以及創建單元格,然後設置文字
生成標題的部分代碼在這裏
private static void generateTableTitle(HSSFWorkbook book, Map<Integer, String> titleMap) {
HSSFRow row = sheet.createRow(1);
for(int i=0;i<titleMap.size();i++){
HSSFCell cell = row.createCell(i);
cell.setCellValue(titleMap.get(i));
}
}
先創建了一個工作簿,然後創建一行,接着就遍歷每個存放標題文字的map然後創建單元格,並設置進去文字
接下來是處理數據的部分
private static <T>void generateData(HSSFWorkbook book, List<T> list) throws IllegalAccessException {
HSSFSheet sheetAt = book.getSheetAt(0);
for(int i=0;i<list.size();i++){
HSSFRow row = sheetAt.createRow(i+2);
writeToRow(row,list.get(i));
}
}
獲得第一個工作簿,然後遍歷每一行,這裏從第三行開始(因爲第一行是標題,第二行是表頭)
然後寫入每一行數據
private static void writeToRow(HSSFRow row, Object o) throws IllegalAccessException {
Class<?> aClass = o.getClass();
int index=0;
for(Field f:aClass.getDeclaredFields()){
HSSFCell cell = row.createCell(index++);
f.setAccessible(true);
cell.setCellValue(f.get(o).toString());
}
}
我們來運行下
List<Student> objects = new ArrayList<>();
objects.add(new Student("zhangjun",18,"密碼"));
objects.add(new Student("lisi",88,"你懂得"));
Map<Integer,String> map=new HashMap<>();
map.put(0,"用戶名");
map.put(1,"年齡");
map.put(2,"密碼");
generateXls(new FileOutputStream("d:/xls/c.xls"),"我的信息",map,objects);
生成到了 d:/xls/c.xls
接下來是解析xls的代碼部分
public static <T> List<T> getData(File file, Map<Integer,String> map,Class c,int startIndex) throws IOException{
List<T> result=new ArrayList<T>();
Workbook book = WorkbookFactory.create(file);
Iterator<Sheet> sheetIterator = book.sheetIterator();
while(sheetIterator.hasNext()){
Sheet sheet = sheetIterator.next();
for(int i=0;i<=sheet.getLastRowNum();i++){
try {
System.out.println(i);
if(i<startIndex)
continue;
//這裏就是每一行,遍歷然後添加數據到list
handleRow(map, c, result, sheet.getRow(i));
}catch (Exception e){
e.printStackTrace();
}
}
}
return result;
}
從指定file創建workbook對象,然後遍歷每個sheet,然後再遍歷每個sheet,然後處理每一行數據
private static <T> void handleRow(Map<Integer, String> map, Class c, List<T> result, Row row) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
Object o = c.newInstance();
for(int i=0;i<row.getLastCellNum();i++){
//這裏獲得字段名
String fieldName = map.get(i);
setVal(o, fieldName, row.getCell(i));
}
result.add((T) o);
}
這裏對傳過來的class進行初始化,然後遍歷每一個單元格,把值通過反射注入到對象裏
private static void setVal(Object o, String fieldName, Cell cell) throws NoSuchFieldException, IllegalAccessException {
Class<?> aClass = o.getClass();
Field field = aClass.getDeclaredField(fieldName);
if(field==null)
return;
//這裏說明有那個字段,就下來就把單元格里面的值拿出來並做類型轉換並賦值進去
field.setAccessible(true);
field.set(o,getVal(field,cell));
}
有那個字段的話就從單元格獲得,並且進行類型轉換,然後再注入進去
private static Object getVal(Field field, Cell cell) {
cell.setCellType(CellType.STRING);
if(field.getType()==Integer.class||field.getType()==int.class){
return Integer.parseInt(cell.getStringCellValue());
}
if(field.getType()==Double.class||field.getType()==double.class){
return Double.parseDouble(cell.getStringCellValue());
}
if(field.getType()== Date.class){
return cell.getDateCellValue();
}
if(field.getType()==String.class){
return cell.getStringCellValue();
}
if(field.getType()==boolean.class||field.getType()==Boolean.class){
return cell.getBooleanCellValue();
}
return null;
}
這是一些簡單的判斷
有個很坑的地方,獲得單元格數據前需要把單元格的類型設置成String
我們來調用把
Map<Integer,String> mapp=new HashMap<>();
mapp.put(0,"name");
mapp.put(1,"age");
mapp.put(2,"password");
List<Student> data = getData(new File("d:/xls/c.xls"), mapp, Student.class,2);
for(Student s:data){
System.out.println(s.toString());
}
輸出結果