不知不觉工作已有大半年了,一直以来没有写东西的习惯,总以为只要记载自己的脑袋里面就行了,但是我似乎忘记了自己从事的是开发,从今天开始争取每天都把自己在工作中遇到问题,在工作中学到的东西记录下来,以方便日后在看。
对于框架,在工作之前觉得是多么的神奇,多么的牛逼,自从那次对我们项目的一个简单框架源码进行剖析后,感觉框架也就那么回事
1.规范 这是一个框架的核心
2.想要做的事 这是在制定一个框架前必须要有的一个大体概念
3.能做的事 这是一个框架的功能
4.扩展性
首先说说规范,规范就是要拿给使用这个框架的人的,我们要怎么才能让一个东西拿给所有人,让所有人用起来都感觉满意喃,当然这里的所有人说的是有正常思维的人,下面就以我自己写的一个小程序来说明,当然这个程序还是一个初级版本
需求:由于现在公司所使用的开发语言都是用的java,在各个项目中都需要导出一个excle文件(对于一般的公司经常需要导出这样的数据进行分析)
想要做的事:我直接把数据扔给你,你给我一个文件
要导出一个excel文件,我们首先要得到的就是一个文件名,然后就是数据,那么这些数据要是什么样格式的数据喃,这个就是规范,现在我想的就是你直接给我一个list集合,还有一个类的名字然后我就直接给你一个excel文件或者是文件的路径
那么我们需要做些什么喃,我是这样想的,我们可以通过注解来获得某一个属性的表头,还有就是顺序(这个暂时还没写进去),这样我们就可以生成一个简单的带有表头的excel文件了。下面是部份源代码,
AnnTitle.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface AnnTitle {
public String title();
}
这是一个注解类,我们主要通过这个来对一个字段导出时需要显示的表头进行指定。或许这个在后面需要加一个属性,来解决排序的问题,下面这个方法是通过反射来获得对类名为 className的类进行解析得到当前的配置信息
private Map<String,Object> parseObj(String className){
Map<String, String> map = new HashMap<String,String>();
List<String> fields = new ArrayList<String>();
try {
Class<?> c = Class.forName(className);
Object obj = c.newInstance();
Field[] fs = obj.getClass().getDeclaredFields();
for(Field f:fs){
AnnTitle ann = f.getAnnotation(AnnTitle.class);
if(ann!=null){
fields.add(f.getName());
map.put(f.getName(), ann.title());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Map<String,Object> result = new HashMap<String,Object>();
if(fields==null || map==null || fields.size()==0 || map.size()==0)
return null;
else{
result.put(LIST, fields);
result.put(MAP, map);
return result;
}
}
下面这个方法就是真正的开始创建文件了,这里创建的是一个excel2003的文件格式的excel文件,后面也会增加对2007也就是poi的导出,这段代码还存在一个问题,那就是如果数据量超过了65535,因为一个excel2003的文件单个sheet能够创建的最多行就是那么多,所以这里还有待改进,不过能够满足日常使用,在下面附上一个简单的例子
public void createExcelByObject(String fileName, List<Object> list,String className) throws IOException, RowsExceededException,
WriteException, IntrospectionException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Map<String,Object> resultMap = parseObj(className);
if(resultMap==null){
System.out.println("无法获得需要导出的属性,与表头信息!");
return;
}
@SuppressWarnings("unchecked")
Map<String, String> map = (Map<String, String>) resultMap.get(MAP);
@SuppressWarnings("unchecked")
List<String> fields = (List<String>) resultMap.get(LIST);
if (list == null || list.size() == 0 || fileName == null
|| fields == null || fields.size() == 0)
throw new RuntimeException("导出的数据不能为空");
WritableWorkbook book = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
File dir = new File(fileName.substring(0, fileName.lastIndexOf("/")));
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(fileName);
if (!file.exists())
file.createNewFile();
// 创建工作簿
FileOutputStream fos = new FileOutputStream(file);
book = Workbook.createWorkbook(fos);
// 创建sheet文件
WritableSheet sheet = book.createSheet("sheet1", 0);
// 用来存放对象拥有的属性
List<String> ownList = new ArrayList<String>();
// 先判断在fields中属性的是不是在Object中都有
Object obj = list.get(0);
@SuppressWarnings("rawtypes")
Class clazz = obj.getClass();
// 获得属性
Field[] ownFields = obj.getClass().getDeclaredFields();
for (Field field : ownFields) {
ownList.add(field.getName());
}
// 定义标志,如果fields中给出的属性在对象中不存在就不创建文件
boolean flag = false;
for (String str : fields) {
if (!ownList.contains(str)) {
flag = true;
System.out.println("需要导出的属性在对象上不存在!");
break;
}
}
if (!flag) {
System.out.println("数据检查完毕,开始创建文件。。。");
if (fields == null || fields.size() == 0) {
System.out.println("文件不能创建!");
} else {
if (map == null || map.size() == 0) {
System.out.println("创建的文件没有表头");
} else {
// 创建表头
for (int i = 0; i < fields.size(); i++) {
Label titl = new Label(i, 0, map.get(fields.get(i)));
sheet.addCell(titl);
}
}
// 创建内容
for (int j = 0; j < list.size(); j++) {
Object tempObj = list.get(j);
for (int k = 0; k < fields.size(); k++) {
PropertyDescriptor pd = new PropertyDescriptor(
fields.get(k), clazz);
Method getMethod = pd.getReadMethod();// 获得get方法
Object o = getMethod.invoke(tempObj);
if (o == null)
o = "";
Label contentLabel = null;
if (o instanceof Date) {
o = sdf.format(o);
contentLabel = new Label(k, j + 1, o.toString());
} else {
contentLabel = new Label(k, j + 1, o.toString());
}
sheet.addCell(contentLabel);
}
}
book.write();
fos.flush();
System.out.println("文件创建完成");
}
}
// }
try {
if (book != null)
book.close();
if (fos != null)
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
test.java
package com.pbd.test;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import com.pbd.util.GeneralExcelFile;
public class test {
public static void main(String[] args) throws RowsExceededException, WriteException, IllegalArgumentException, IOException, IntrospectionException, IllegalAccessException, InvocationTargetException {
GeneralExcelFile g = GeneralExcelFile.newInstance();
List<Object> list = new ArrayList<Object>();
for(int i = 0;i<20;i++){
TestBean b = new TestBean();
b.setAge(2);
b.setId(i);
b.setD(new Date());
b.setSex("男");
list.add(b);
}
g.createExcelByObject("c:/pdftest/1.xls", list, "com.pbd.test.TestBean");
}
}
testbean.java
package com.pbd.test;
import java.util.Date;
import com.pbd.util.AnnTitle;
public class TestBean {
@AnnTitle(title="编号")
private int id;
@AnnTitle(title="名称")
private String name;
@AnnTitle(title="性别")
private String sex;
@AnnTitle(title="年龄")
private int age;
@AnnTitle(title="时间")
private Date d;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getD() {
return d;
}
public void setD(Date d) {
this.d = d;
}
}