Excel通用工具
最近專案中遇到要將SQL/">MySQL資料庫中的某些資料匯出為Excel格式儲存,在以前也寫過這樣的功能,這次就準備用以前的程式碼,但是看了一下,這次卻不一樣,因為在以前用到的都是匯出一種或幾種資料,種類不多,但是這次匯出的種類比較多,相當於就是每一種型別的資料得單獨寫一些程式碼,而且重複的比較多;就想寫一個通用的,不管什麼種類,直接傳入資料就行了;
正文
想法
因為資料的種類是不同的,裡面的屬性也各不相同,如何用同一段程式碼去處理這些不同種類的屬性,讓我第一時間想到了Java的泛型和反射;因為之前的筆記中就寫到了反射,這時候剛好派上用場,就來實際操作一下;
程式碼部分
首先匯入poi相應的jar包:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency> 複製程式碼
- 實體類 有兩個實體類:pojoA 和pojoBB,主要是為了測試不同實體類的不同屬性是否有效; pojoA:
/** * @author gyc * @date 2018/10/2621:50 */ public class PojoA { private String name; private int num; private double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } } 複製程式碼
pojoB:
/** * @author gyc * @date 2018/10/2621:51 */ public class PojoB { private String userName; private int age; private Date birthday; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } 複製程式碼
- 核心程式碼部分 使用該類時,需要傳入每列得列名,為String陣列,以及資料的List集合物件;還有一個Excel的title名;其中每列自動適應寬度,這個屬性得將資料存入Excel之後才能呼叫,如果在資料存入之前呼叫,則不會取作用;
/** * @author gyc * @date 2018/10/2621:45 */ public class ExcelUtil<T> { public HSSFWorkbook setExcel(String title,String[] columnNames, List<T> tList) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, IOException { //1.建立Excel工作薄物件 HSSFWorkbook workbook=new HSSFWorkbook(); //2.建立Excel工作表物件 HSSFSheet sheet=workbook.createSheet(title); HSSFRow row=null; //3.建立Excel工作表的第一行,並填充列名 row=sheet.createRow(0); for(int i=0;i<columnNames.length;i++){ row.createCell(i).setCellValue(columnNames[i]); } Field[] declaredFields = tList.get(0).getClass().getDeclaredFields(); //4.將資料填充至表格中 for(int j=1;j<=tList.size();j++){ T t= tList.get(j-1); row=sheet.createRow(j); for(int i=0;i<declaredFields.length;i++){ // 通過反射獲取屬性值 String fieldName = declaredFields[i].getName(); String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); Method declaredMethod = t.getClass().getDeclaredMethod(getMethodName); //執行方法 Object fieldValue = declaredMethod.invoke(t); //判斷是否為空 if(fieldValue!=null &&!"".equals(fieldValue)){ //判斷屬性值型別 if(fieldValue instanceof Integer){ row.createCell(i).setCellValue(Integer.valueOf(fieldValue.toString())); }else if(fieldValue instanceof Double){ row.createCell(i).setCellValue(Double.valueOf(fieldValue.toString())); }else if(fieldValue instanceof Date){ row.createCell(i).setCellValue(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(fieldValue)); }else { row.createCell(i).setCellValue(fieldValue.toString()); } }else { row.createCell(i).setCellValue(""); } } } //自動設定列寬,要在在資料讀入之後設定; for (int i = 0; i < columnNames.length; i++) { sheet.autoSizeColumn(i); //在自動適應的基礎上增加寬度 //sheet.setColumnWidth(i,sheet.getColumnWidth(i)*17/10); } return workbook; } } 複製程式碼
測試
測試程式碼
/** * @author gyc * @date 2018/10/2621:52 */ public class Test { public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, IOException { PojoA pojoA=new PojoA(); pojoA.setName("a"); pojoA.setNum(1); pojoA.setPrice(1.1234); List<PojoA> lista=new ArrayList<>(); lista.add(pojoA); PojoB pojoB=new PojoB(); pojoB.setUserName("b"); pojoB.setAge(2); pojoB.setBirthday(new Date()); List<PojoB> listb=new ArrayList<>(); listb.add(pojoB); HSSFWorkbook workbooka = new ExcelUtil().setExcel("pojoA", new String[]{"名稱", "數量", "價格"}, lista); HSSFWorkbook workbookb = new ExcelUtil().setExcel("pojoB", new String[]{"名稱", "年齡", "時間"}, listb); workbooka.write(new FileOutputStream(new File("/Users/rose/IdeaProjects/java-study/smalltools/pojoA.xls"))); workbookb.write(new FileOutputStream(new File("/Users/rose/IdeaProjects/java-study/smalltools/pojoB.xls"))); } } 複製程式碼
總結
本篇筆記中使用了Java泛型和反射,但都是用得比較淺,只是最基礎的使用;主要解決了處理資料種類繁多的的問題,不用單獨處理; 其中也有很多不足之處,如下:
- 資料集合只支援List集合
- 用到了反射,速率可能比單獨處理的低
- 需要手動傳入列名,比較硬編碼