原文链接:http://www.iteye.com/topic/657977
闲来无事,做了一个通用的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());
- }
- }
-
- 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;
- }
- }