报表数据展现时,常见的原则都是所见即所得。
这里主要用到了POI及处理Excel需要jar包
完整代码请下载查看:链接https://pan.baidu.com/s/1shgo4d290lnIA-ucv6qowg 提取码:51q3
文章目录
- 代码相关
- 注解部分
- 实体部分
- 导出excel核心部分
- 完整代码请下载查看
- 结果
- 说明
- 都不是用反射,使用普通map记录
- 仅表头使用反射
- 表头以及内容都使用反射
- 结束
代码相关
注解部分
/**
* 注解类
*/
@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]
结束
以上仅为个人测试,不代表真实数据,仅供参考。
如有错误之处,望指导。谢谢