论坛首页 入门技术论坛

发一个本人写的通用Excel导入导出组件类,请高手指正!

浏览 6638 次
精华帖 (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());
	}
}
   发表时间: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;
	}
	
}




有需要完整包的联系我
0 请登录后投票
   发表时间:2010-05-02  
还可以把 
0 请登录后投票
   发表时间:2010-05-03  
现在是实体类中有可能出现一对多,或者多对一的时候,改怎么弄呢?
有高人给指正一下吧
0 请登录后投票
   发表时间:2010-08-18  
不知道有示例EXCEL吗?我用的EXCEL第一行分别用你的三个测试字段,但是找不到值,只会得到一个空的Loginfo,有示例文档吗?可以发给我一下吗?x-man198199@163.com
0 请登录后投票
   发表时间:2010-12-06  
neilwang 写道
现在是实体类中有可能出现一对多,或者多对一的时候,改怎么弄呢?
有高人给指正一下吧



做excel导出时,指定导出字段。如在AaForm中有User的form,导出显示用户名汉字而不是id,则字段描述:user.username
通过反射机制就可以获得汉字名。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics