報表數據展現時,常見的原則都是所見即所得。
這裏主要用到了POI及處理Excel需要jar包
完整代碼請下載查看:鏈接https://pan.baidu.com/s/1shgo4d290lnIA-ucv6qowg 提取碼:51q3
代碼相關
註解部分
/**
* 註解類
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface FileName {
public String defaulename() default "";//顯示錶頭默認名稱
public String languageid() default "";//顯示錶頭對應多語言id,支持多語言的情況下
}
實體部分
/**
* 用戶實體類
*/
class User {
@FileName(defaulename = "名稱", languageid = "")
public String username;
@FileName(defaulename = "電話", languageid = "")
public String mobilenumber;
@FileName(defaulename = "年齡", languageid = "")
public Integer age;
@FileName(defaulename = "郵箱", languageid = "")
public String em;
@FileName(defaulename = "其他測試", languageid = "")
public String othertest;
public static User getUser() {
User user = new User();
user.setUsername("百川" + (int) (Math.random() * 100));
user.setAge((int) (Math.random() * 100));
user.setMobilenumber("+86 173" + Math.random() * 100);
user.setEm((int) (Math.random() * 1000) + "@cc.com");
user.setOthertest("其他參數測試");
return user;
}
public User() { }
public String getOthertest() { return othertest; }
public void setOthertest(String othertest) { this.othertest = othertest; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getMobilenumber() { return mobilenumber; }
public void setMobilenumber(String mobilenumber) { this.mobilenumber = mobilenumber; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getEm() { return em; }
public void setEm(String em) { this.em = em; }
}
導出excel核心部分
public void writeExcel(String docname, List<User> users) {
if (users == null || users.isEmpty()) return;//無數據
long createtime = new Date().getTime();
int row = 0;
HSSFWorkbook wb = new HSSFWorkbook();//創建exe表格
HSSFSheet sheet = wb.createSheet(docname);//創建工作簿
try {
HSSFRow titlerow = sheet.createRow(row++);//創建首行
boolean hastable = setTableTitle(titlerow, users.get(0));
if (!hastable) return;//說明首行沒有,這個情況說明你的bean對象都不支持導出
//設置內容
for (User user : users) {
HSSFRow valuerow = sheet.createRow(row++);
setTableBody(valuerow, user);
if (row % EXECL_MAXNUM == 0) {//需要重新創建工作簿
row = 0;
sheet = wb.createSheet(docname + "-" + wb.getNumberOfSheets());//創建工作簿
titlerow = sheet.createRow(row++);//創建首行
setTableTitle(titlerow, users.get(0));
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
FileOutputStream os = new FileOutputStream("D:/mywebsit/" + docname + EXECL_TYPE);
wb.write(os);
os.flush();
os.close();
System.out.println("success");
} catch (Exception e) {
System.err.println(e);
}
long endtime = new Date().getTime();
System.out.println("user times " + (endtime - createtime) + "(ms)");
}
/**
* 這裏需要傳遞一個bean對象
*
* @param titlerow
* @param obj
*/
public boolean setTableTitle(HSSFRow titlerow, Object obj) {
int col = -1;
boolean hastitle = false;//用於判斷是否有表頭
Field[] fields = obj.getClass().getDeclaredFields();//前面已經保證了一定有數據
for (Field field : fields) {//用於遍歷創建表頭
if (canWriterFileName(field.getAnnotations())) {
titlerow.createCell(++col).setCellValue(field.getAnnotation(FileName.class).defaulename());//創建單元格
hastitle = true;
}
}
return hastitle;
}
/**
* 設置表格中的內容
*/
public void setTableBody(HSSFRow valuerow, Object obj) throws Exception {
int col = -1;
Class objClass = obj.getClass();
Field[] fields = objClass.getDeclaredFields();
for (Field field : fields) {//用於遍歷創建表頭
if (canWriterFileName(field.getAnnotations())) {
String fieldname = field.getName();
fieldname = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1);//注意這裏需要get方法名稱規範
valuerow.createCell(++col).setCellValue(objClass.getMethod(fieldname).invoke(obj).toString());//創建單元格
}
}
}
完整代碼請下載查看
鏈接:https://pan.baidu.com/s/1shgo4d290lnIA-ucv6qowg
提取碼:51q3
結果
說明
這裏通過註解以及使用反射的方式設置表頭,以及可設置顯示順序,同時預留多語言接口,可以根據自己的需求進行擴展。但是就目前使用反射或不使用反射導出數據,在導出時間上有明顯差異。
以50w條數據爲例,僅爲個人電腦測試
從下面的結果看來還是不使用反射的稍好,這裏用到反射的目的是,可以在實體中指明哪些是可以打印的數據。
都不是用反射,使用普通map記錄
平均用時11s[測試四次結果12337,10559,10578,11418]
僅表頭使用反射
平均用時約11s[測試四次結果11127,12896,11061,11584]
表頭以及內容都使用反射
平均用時約16s[測試四次結果17182,16328,17150,16891]
結束
以上僅爲個人測試,不代表真實數據,僅供參考。
如有錯誤之處,望指導。謝謝