浏览 6661 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-02
闲来无事,做了一个通用的excel导入导出类。 可以在数据库查询过滤的基础上导出数据(只需传入过滤后的List即可), 也可根据编辑的excel对数据库进行导入。引用了apache的poi,测试5000条数据的导入导出均在300毫秒左右 package com.love; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 作者:王云权;QQ:1371392495,email:wangyunquan@live.com * 欢迎转载;转载时请著名出处 * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ExcelAnnotation { // excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入 public String exportName(); } 导出类 package com.love; import java.io.FileOutputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * 作者:王云权;QQ:1371392495,email:wangyunquan@live.com * 欢迎转载;转载时请著名出处 * */ public class ExcelExport<T> { /** * * @param title 标题 * @param dataset 集合 * @param out 输出流 */ public void exportExcel(String title, Collection<T> dataset, OutputStream out) { // 声明一个工作薄 try { //首先检查数据看是否是正确的 Iterator<T> its = dataset.iterator(); if(dataset==null||!its.hasNext()||title==null||out==null) { throw new Exception("传入的数据不对!"); } T ts = (T) its.next(); HSSFWorkbook workbook = new HSSFWorkbook(); // 生成一个表格 HSSFSheet sheet = workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth(15); // 生成一个样式 HSSFCellStyle style = workbook.createCellStyle(); // 设置标题样式 style = ExcelStyle.setHeadStyle(workbook, style); // 生成并设置主体样式 HSSFCellStyle style2 = workbook.createCellStyle(); style2 = ExcelStyle.setbodyStyle(workbook, style2); // 得到所有字段 Field filed[] = ts.getClass().getDeclaredFields(); // 标题 List<String> exportfieldtile = new ArrayList<String>(); // 导出的字段 List<String> fiedName = new ArrayList<String>(); // 遍历整个filed for (int i = 0; i < filed.length; i++) { Field f = filed[i]; ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class); // 如果设置了annottion if (exa != null) { String exprot = exa.exportName(); // 添加到标题 exportfieldtile.add(exprot); // 添加到需要导出的字段 fiedName.add(f.getName()); } } // 产生表格标题行 HSSFRow row = sheet.createRow(0); for (int i = 0; i < exportfieldtile.size(); i++) { HSSFCell cell = row.createCell(i); cell.setCellStyle(style); HSSFRichTextString text = new HSSFRichTextString( exportfieldtile.get(i)); cell.setCellValue(text); } Iterator<T> it = dataset.iterator(); int index = 0; // 循环整个集合 while (it.hasNext()) { index++; row = sheet.createRow(index); T t = (T) it.next(); for (int k = 0; k < fiedName.size(); k++) { HSSFCell cell = row.createCell(k); String fieldname = fiedName.get(k); String getMethodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); Class tCls = t.getClass(); Method getMethod = tCls.getMethod(getMethodName, new Class[] {}); Object value = getMethod.invoke(t, new Object[] {}); String textValue = getValue(value); HSSFRichTextString richString = new HSSFRichTextString( textValue); cell.setCellValue(richString); } } workbook.write(out); } catch (Exception e) { e.printStackTrace(); } } public String getValue(Object value) { String textValue = ""; if (value == null) return textValue; if (value instanceof Boolean) { boolean bValue = (Boolean) value; textValue = "是"; if (!bValue) { textValue = "否"; } } else if (value instanceof Date) { Date date = (Date) value; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); textValue = sdf.format(date); } else textValue = value.toString(); return textValue; } public static void main(String[] args) throws Exception { List list = new ArrayList(); for (int i = 0; i < 5000; i++) { Loginfo log = new Loginfo(); log.setLogInfo("测试一下"); log.setUserip("127.0.1.1"); log.setUsername("测试"); list.add(log); } OutputStream out = new FileOutputStream("D:\\testOne.xls"); Long l = System.currentTimeMillis(); ExcelExport<Loginfo> ex = new ExcelExport<Loginfo>(); ex.exportExcel("测试", list, out); out.close(); Long s = System.currentTimeMillis(); System.out.println("总共耗时:" + (s - l)); } } 导入类: package com.love; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; /** * 作者:王云权;QQ:1371392495,email:wangyunquan@live.com * 欢迎转载;转载时请著名出处 * */ public class ImportExcel<T> { Class<T> clazz; public ImportExcel(Class<T> clazz) { this.clazz = clazz; } public Collection<T> importExcel(File file ,String... pattern) { Collection<T> dist = new ArrayList(); try { /** * 类反射得到调用方法 */ // 得到目标目标类的所有的字段列表 Field filed[] = clazz.getDeclaredFields(); // 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中 Map fieldmap = new HashMap(); // 循环读取所有字段 for (int i = 0; i < filed.length; i++) { Field f = filed[i]; // 得到单个字段上的Annotation ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class); // 如果标识了Annotationd的话 if (exa != null) { // 构造设置了Annotation的字段的Setter方法 String fieldname = f.getName(); String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); // 构造调用的method, Method setMethod = clazz.getMethod(setMethodName, new Class[] { f.getType() }); // 将这个method以Annotaion的名字为key来存入。 fieldmap.put(exa.exportName(), setMethod); } } /** * excel的解析开始 */ // 将传入的File构造为FileInputStream; FileInputStream in = new FileInputStream(file); // // 得到工作表 HSSFWorkbook book = new HSSFWorkbook(in); // // 得到第一页 HSSFSheet sheet = book.getSheetAt(0); // // 得到第一面的所有行 Iterator<Row> row = sheet.rowIterator(); /** * 标题解析 */ // 得到第一行,也就是标题行 Row title = row.next(); // 得到第一行的所有列 Iterator<Cell> cellTitle = title.cellIterator(); // 将标题的文字内容放入到一个map中。 Map titlemap = new HashMap(); // 从标题第一列开始 int i = 0; // 循环标题所有的列 while (cellTitle.hasNext()) { Cell cell = cellTitle.next(); String value = cell.getStringCellValue(); titlemap.put(i, value); i = i + 1; } /** * 解析内容行 */ //用来格式化日期的DateFormat SimpleDateFormat sf; if(pattern.length<1) { sf=new SimpleDateFormat("yyyy-MM-dd"); } else sf=new SimpleDateFormat(pattern[0]); while (row.hasNext()) { // 标题下的第一行 Row rown = row.next(); // 行的所有列 Iterator<Cell> cellbody = rown.cellIterator(); // 得到传入类的实例 T tObject = clazz.newInstance(); int k = 0; // 遍历一行的列 while (cellbody.hasNext()) { Cell cell = cellbody.next(); // 这里得到此列的对应的标题 String titleString = (String) titlemap.get(k); // 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值 if (fieldmap.containsKey(titleString)) { Method setMethod = (Method) fieldmap.get(titleString); //得到setter方法的参数 Class<?>[] ts = setMethod.getParameterTypes(); //只要一个参数 Object xclass = ts[0]; //判断参数类型 if(xclass instanceof String) { setMethod.invoke(tObject, cell.getStringCellValue()); } else if(xclass instanceof Date) { setMethod.invoke(tObject, sf.parse(cell.getStringCellValue())); } else if(xclass instanceof Boolean) { String boolname="是"; if(cell.getStringCellValue().equals("否")) { boolname="否"; } setMethod.invoke(tObject,boolname ); } } // 下一列 k = k + 1; } dist.add(tObject); } } catch (Exception e) { e.printStackTrace(); return null; } return dist; } public static void main(String[] args) { ImportExcel<Loginfo> test = new ImportExcel(Loginfo.class); File file = new File("D:\\testOne.xls"); Long befor = System.currentTimeMillis(); List<Loginfo> result = (ArrayList) test.importExcel(file); Long after = System.currentTimeMillis(); System.out.println("此次操作共耗时:" + (after - befor) + "毫秒"); // for (int i = 0; i < result.size(); i++) { // Loginfo loginfo=result.get(i); // System.out.println("导入的信息为:"+loginfo.getLogInfo()+loginfo.getUserip()+loginfo.getUsername()); // } System.out.println("共转化为List的行数为:" + result.size()); } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-02
忘了贴一个类,补上:
package com.love; /** * 作者:王云权;QQ:1371392495,email:wangyunquan@live.com * 欢迎转载;转载时请著名出处 * */ public class Loginfo { @ExcelAnnotation(exportName = "用户IP地址") private String userip; @ExcelAnnotation(exportName = "用户姓名") private String username; @ExcelAnnotation(exportName = "操作信息") private String logInfo; /** * @return the userip */ public String getUserip() { return userip; } /** * @param userip the userip to set */ public void setUserip(String userip) { this.userip = userip; } /** * @return the username */ public String getUsername() { return username; } /** * @param username the username to set */ public void setUsername(String username) { this.username = username; } /** * @return the logInfo */ public String getLogInfo() { return logInfo; } /** * @param logInfo the logInfo to set */ public void setLogInfo(String logInfo) { this.logInfo = logInfo; } } 有需要完整包的联系我 |
|
返回顶楼 | |
发表时间:2010-05-02
还可以把
|
|
返回顶楼 | |
发表时间:2010-05-03
现在是实体类中有可能出现一对多,或者多对一的时候,改怎么弄呢?
有高人给指正一下吧 |
|
返回顶楼 | |
发表时间:2010-08-18
不知道有示例EXCEL吗?我用的EXCEL第一行分别用你的三个测试字段,但是找不到值,只会得到一个空的Loginfo,有示例文档吗?可以发给我一下吗?x-man198199@163.com
|
|
返回顶楼 | |
发表时间:2010-12-06
neilwang 写道 现在是实体类中有可能出现一对多,或者多对一的时候,改怎么弄呢?
有高人给指正一下吧 做excel导出时,指定导出字段。如在AaForm中有User的form,导出显示用户名汉字而不是id,则字段描述:user.username 通过反射机制就可以获得汉字名。 |
|
返回顶楼 | |