介绍一下本工具的功能: 对于给定的java对象(List)生成一个excell文件。
在这个list里面的每个子对象带有特定的列注释(此注释写在set方法上,思考了下其实这个注释最好能写在get方法上),开发时需要导入POI相关包,
然后对List的对象写一个特定注释的类,比如Student.java,即可调用工具完成excell文件的生成。
import java.util.Date; import Excel.annotation.Column; import XMLHandler.xmlopt.annotation.Node; import XMLHandler.xmlopt.annotation.Xml; import XMLHandler.xmlopt.annotation.Attr; @Xml(name="Student") public class Student { private String id; private String name; private String bir; private String age; public String getId() { return id; } @Column(name="学号") public void setId(String id) { this.id = id; } public String getName() { return name; } @Column(name="姓名") public void setName(String name) { this.name = name; } public String getBir() { return bir; } @Column(name="出生日期") public void setBir(String bir) { this.bir = bir; } public String getAge() { return age; } @Column(name="年龄") public void setAge(String age) { this.age = age; } }
用到的注释类Column.java,
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @desc: 描述excell文件的列头信息 * * @date-2011-1-10 * @author ziliang */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface Column { /** * 列名注释 */ public String name() default ""; }
下面看我们主要的工具类,
import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import Excel.annotation.Column; import XMLHandler.xmlopt.annotation.Ignore; import XMLHandler.xmlopt.annotation.Xml; /** * @desc: excel操作工具 * @date-2011-1-10 * @author-ziliang * */ public class ExcelUtil { /** * 待创建的excel文件名,你可以写定名字 * */ private static String filename=""; /** * @desc 根据list的数据生成excel文件 * @author ZILIANG * @throws IOException * */ public static void createExcelFile(List list) throws IOException{ FileOutputStream fileOut=null; if(list.size()==0)return; Object obj=list.get(0); HSSFWorkbook wb=(HSSFWorkbook) getWorkbook(obj); //构造excel头 getExcelHead(obj,0,wb); // 产生唯一文件名称, 并关联文件流 String file_name=System.currentTimeMillis()+filename+".xls"; fileOut = new FileOutputStream(file_name); //循环处理数据行:注意行序号 for(int i=1;i<=list.size();i++){ obj=list.get(i-1); getExcelBody(obj,i,wb); } wb.write(fileOut); fileOut.close(); } /** * 获取当前工作薄的每一行数据 * */ public static void getExcelBody(Object obj,int rowno,HSSFWorkbook wb ) throws IOException{ Class<?> targetClass = obj.getClass(); // 创建第一个工作表,命名filename HSSFSheet sheet = wb.getSheet(filename); Method methods[] = targetClass.getMethods(); int colno=0; HSSFRow row = sheet.createRow(rowno); for (Method method : methods) { if (!isSetMethod(method)) continue; if (method.getAnnotation(Ignore.class) != null) continue; //处理数据行 HSSFCell cell = row.createCell((short) colno); String defaultNodeName = method.getName().substring(3); Object value = invokeGet(obj, defaultNodeName); if(value==null) value=""; cell.setCellValue(value.toString()); colno++; } } /** * 获取当前工作薄的头 * */ public static void getExcelHead(Object obj,int rowno,HSSFWorkbook wb ) throws IOException{ Class<?> targetClass = obj.getClass(); // 创建第一个工作表,命名filename HSSFSheet sheet = wb.getSheet(filename); Method methods[] = targetClass.getMethods(); int colno=0; HSSFRow row = sheet.createRow(rowno); for (Method method : methods) { if (!isSetMethod(method)) continue; if (method.getAnnotation(Ignore.class) != null) continue; Column columnAnno = method.getAnnotation(Column.class); String column=columnAnno.name(); if(isNotEmpty(column)&&rowno==0){ //读取注释,处理头信息 HSSFCell cell = row.createCell((short) colno); cell.setCellValue(column); cell.setCellStyle(setCellStyle(wb)); colno++; } } } /** * @param 带有特定注释的javabean * @author ziliang * @return HSSFWorkbook,返回创建了一个名为filename的sheet页的工作薄 * */ public static HSSFWorkbook getWorkbook(Object obj) throws FileNotFoundException{ Class<?> targetClass = obj.getClass(); // 取类注解 Xml docAnno = targetClass.getAnnotation(Xml.class); if (docAnno == null) { throw new RuntimeException("被处理的类必须带有annotation的注解"); } //取类名字,如名字注释空则取默认类名为excel文件名 String file_name = docAnno.name(); if (file_name == null || file_name.length() == 0) file_name = obj.getClass().getSimpleName(); filename=file_name; HSSFWorkbook wb = new HSSFWorkbook(); // 创建一个工作表,命名filename HSSFSheet sheet = wb.createSheet(filename); return wb; } //设置单元样式 public static HSSFCellStyle setCellStyle(HSSFWorkbook wb){ HSSFFont font = wb.createFont(); font.setColor(HSSFFont.COLOR_NORMAL); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); HSSFCellStyle cellStyle = wb.createCellStyle(); cellStyle.setFont(font); return cellStyle; } /** * 是否为符合javaBean规范的set方法 * * @param methodName * @return */ public static boolean isSetMethod(Method method) { String methodName = method.getName(); if (!methodName.startsWith("set")) { return false; } Class<?>[] clazzes = method.getParameterTypes(); // 如果方法的参数>1 则不是设置属性的方法 if (clazzes.length != 1) { return false; } return true; } //工具函数: 判断字符串不空 public static boolean isNotEmpty(String s){ return s!=null && !s.trim().equalsIgnoreCase(""); } //取obj属性值 private static Object invokeGet(Object target, String name) { name = name.substring(0, 1).toUpperCase() + name.substring(1); String getMethodName = "get" + name; Object res = null; try { Method method = target.getClass().getMethod(getMethodName); res = method.invoke(target); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return res; } }
上面代码用到了另外2个特别注释类ignore.java和xml.java,参见我的另外文章:xml操作工具-实现篇
好了,有了上面完整的代码,下面来测试下student组成的List,生成的excell会是样子的?
import java.io.*; import java.util.*; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import Excel.excelutil.ExcelUtil; import XMLHandler.xmlopt.util.XmlUtil; import XMLHandler.xmlutil.test.School; public class TestExcel { @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } //@Ignore @Test public void testExcel2File() throws FileNotFoundException, IOException { List list=new ArrayList(); Student s1=new Student(); s1.setAge("22"); s1.setName("sname"); list.add(s1); Student s2=new Student(); s2.setAge("22"); s2.setBir("2010-1-1"); list.add(s2); Student s3=new Student(); s3.setAge("55"); s3.setId("001"); list.add(s3); ExcelUtil.createExcelFile(list); System.out.println(""); } }
测试上述代码,生成的excell文件放在工程路径下,文件名为时间戳加上Student构成,例如:1294967658921Student.xls
本文主要是用POI包实现的,另外介绍一篇-jxl模板导出excel
http://blog.csdn.net/ziliang871118/archive/2011/02/25/6207641.aspx