`
宋双旺
  • 浏览: 156837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JEECG 通用数据库导入导出excel

阅读更多

需求:在实际J2EE项目中,经常遇到需要导入导出excel文件的情况;

解决方案: 利用java的annotation,自定义一个annotation ,在声明pojo的时候对需要操作字段的属性进行声明,

                   然后通用的处理类运行时,读取annotation 相关信息进行解析。

                   对于导入,读入是一个excel文件,输出一个list<pojo> ,如果你用hibernate操作的话相当方便。

                   对于导出,你需要组织一个List<pojo>传入,将得到一个excel。

 

1、页面效果如下图所示:

excel导入导出

 2、自定义的Exel的annotation如下图所示:

@Retention(RetentionPolicy.RUNTIME)   
@Target(ElementType.FIELD)
public @interface Excel {
//导入时,对应数据库的字段 主要是用户区分每个字段,不能有annocation重名的
//导出时的列名   导出排序跟定义了annotation的字段的顺序有关  
public String exportName();
//导出时在excel中每个列的宽  单位为字符,一个汉字=2个字符 
//如 以列名列内容中较合适的长度   例如姓名列6 【姓名一般三个字】  性别列4【男女占1,但是列标题两个汉字】
//限制1-255
public int exportFieldWidth();
//导出时是否进行字段转换   例如 性别用int存储,导出时可能转换为男,女
//若是sign为1,则需要在pojo中加入一个方法 get字段名Convert()
//例如,字段sex ,需要加入 public String getSexConvert()  返回值为string
//若是sign为0,则不必管
public int exportConvertSign();
//导入数据是否需要转化      及 对已有的excel,是否需要将字段转为对应的数据
//若是sign为1,则需要在pojo中加入   void set字段名Convert(String text)
public int importConvertSign();
}

  

3、model类如下图所示:

@Entity
@Table(name = "JEECG_TUSER", schema = "")
public class Tuser implements java.io.Serializable {

	// Fields

	private String cid;
	@Excel(exportName="真实姓名", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)
	private String realname;
	@Excel(exportName="所属部门", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)
	private String org;
	@Excel(exportName="邮箱", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private String mail;
	@Excel(exportName="手机", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private String mobile;
	@Excel(exportName="用户类型", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private String usertype;
	@Excel(exportName="状态", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private String status;
	@Excel(exportName="创建时间", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private Date ccreatedatetime;
	@Excel(exportName="修改时间", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private Date cmodifydatetime;
	@Excel(exportName="用户名", exportConvertSign = 0, exportFieldWidth = 10, importConvertSign = 0)	
	private String cname;
	@Excel(exportName="密码", exportConvertSign = 0, exportFieldWidth = 30, importConvertSign = 0)	
	private String cpwd;
}

 

4、jsp页面如下图所示:

<head>
<jsp:include page="/inc.jsp"></jsp:include>
   <script>  
       function exportExcel(){
    	   window.location.href="demoAction!exportExcel.action";
       }
       function importExcel(){
			$('#excelForm').form({
				success : function(result) {
					try {
						var r = $.parseJSON(result);
						$.messager.show({
							title : '提示',
							msg : r.msg
						});
					} catch (e) {
						$.messager.alert('提示', result);
					}
				}
			});    	   
    		if($('#excelForm').form('validate')){
    			$('#excelForm').submit();	
     		}
       }
   </script>  
</head>

<body>  
    <div style="margin:10px 0;"></div>  
    <div class="easyui-panel" title="用户信息" style="width:400px">  
        <div style="padding:10px 0 10px 60px">  
        <form id="excelForm" method="post" enctype="multipart/form-data" action="demoAction!importExcel.action">  
            <table>  
				<tr>
					<td>文件路径</td>
					<td><input name="filedata" class="easyui-validatebox" 
					                                   required="true" type="file" missingMessage="请选择上传文件" /></td>
				</tr>            
            </table>  
        </form>  
        </div>  
        <div style="text-align:center;padding:5px">  
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="importExcel()">导入excel</a>  
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="exportExcel()">导出excel</a>  
        </div>  
    </div>  

</body> 

 

5、action处理如下图所示:

    注意:

       <input type="file" name="upload"> 这个name对应后台的 private File upload; 约定, <s:file/>标志不仅仅是绑定到upload,

       还有uploadContentType(上传文件的MIME类型)和 uploadFileName(上传文件的文件名,该文件名不包括文件的路径)。

       因此,<s:file name="xxx" />对应Action类里面的xxx、xxxContentType和xxxFileName三个属性。

/**
	 * 跳转到excel导入导出页面
	 * @return
	 * 
	 */	
	public String goExcelOpt(){
		return "excel-opt";
	}
	//供浏览器读取的信息
	private String fileName;
	private InputStream inputStream;
	
	private String filedataFileName;

	public String getFiledataFileName() {
		return filedataFileName;
	}


	public void setFiledataFileName(String filedataFileName) {
		this.filedataFileName = filedataFileName;
	}


	public InputStream getInputStream() {
		return inputStream;
	}
	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	/**
	 * 导出Excel
	 * @return
	 * 
	 */	
	public String exportExcel(){
		fileName = "导出信息.xls";
		try {
			fileName = new String(fileName.getBytes(), "ISO8859-1");
			inputStream = demoService.exportExcel();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(ExceptionUtil.getExceptionMessage(e));			
		}
		return "export";
	}
	/**
	 * 导入Excel
	 * @return
	 * 
	 */	
	public void importExcel(){
		Json j = new Json();
		try {
			demoService.importExcel(filedataFileName, filedata);
			j.setSuccess(true);
			j.setMsg("文件导入成功!");		
		} catch (Exception e) {
			j.setSuccess(false);
			j.setMsg("文件导入失败!");			
			logger.error(ExceptionUtil.getExceptionMessage(e));			
		}
		writeJson(j);
	}	

 

 

6、service如下图所示:

	/**
	 * 导出excel
	 */
	@Override
	public InputStream exportExcel()  throws  Exception{
		//获取数据
		String hql = "from Tuser t where 1=1 ";	
		List<Object> values = new ArrayList<Object>();
		List<Tuser> listUser = userDao.find(hql, values);
		File file = new File(new Date(0).getTime()+".xls");
		OutputStream outputStream = new FileOutputStream(file);
		ExcelExportUtil.exportExcel("导出信息", Tuser.class, listUser, outputStream);
		InputStream is = new BufferedInputStream(new FileInputStream(file.getPath()));
		file.delete();		
		return is;
	}	
	
    /** 
     * 导入excel
     *  
     * @param fileName 文件名称
     * @param excelFile 文件
     * @return 
     */  	
	public void importExcel(String fileName,File excelFile){
		List<Tuser> listUsers = (List<Tuser>)ExcelUtil.importExcel(excelFile, Tuser.class);
		for(Tuser user : listUsers){
			user.setCid(UUID.randomUUID().toString());
			userDao.saveOrUpdate(user);
		}
	}	

 7、util的工具类如下图所示:

 

【导出工具类】

	/**
	 * 
	 * @param title     Sheet名字
	 * @param pojoClass Excel对象Class
	 * @param dataSet   Excel对象数据List
	 * @param out       输出流
	 */
	public static void exportExcel(String title, Class<?> pojoClass,
			Collection<?> dataSet, OutputStream out) {
		// 使用userModel模式实现的,当excel文档出现10万级别的大数据文件可能导致OOM内存溢出
		exportExcelInUserModel(title, pojoClass, dataSet, out);
		// 使用eventModel实现,可以一边读一边处理,效率较高,但是实现复杂,暂时未实现
	}

	private static void exportExcelInUserModel(String title, Class<?> pojoClass,
			Collection<?> dataSet, OutputStream out) {
		try {
			// 首先检查数据看是否是正确的
			if (dataSet == null || dataSet.size() == 0) {
				throw new Exception("导出数据为空!");
			}
			if (title == null || out == null || pojoClass == null) {
				throw new Exception("传入参数不能为空!");
			}
			// 声明一个工作薄
			Workbook workbook = new HSSFWorkbook();
			// 生成一个表格
			Sheet sheet = workbook.createSheet(title);

			// 标题
			List<String> exportFieldTitle = new ArrayList<String>();
			List<Integer> exportFieldWidth = new ArrayList<Integer>();
			// 拿到所有列名,以及导出的字段的get方法
			List<Method> methodObj = new ArrayList<Method>();
			Map<String, Method> convertMethod = new HashMap<String, Method>();
			// 得到所有字段
			Field fileds[] = pojoClass.getDeclaredFields();
			// 遍历整个filed
			for (int i = 0; i < fileds.length; i++) {
				Field field = fileds[i];
				Excel excel = field.getAnnotation(Excel.class);
				// 如果设置了annottion
				if (excel != null) {
					// 添加到标题
					exportFieldTitle.add(excel.exportName());
					// 添加标题的列宽
					exportFieldWidth.add(excel.exportFieldWidth());
					// 添加到需要导出的字段的方法
					String fieldname = field.getName();
					// System.out.println(i+"列宽"+excel.exportName()+" "+excel.exportFieldWidth());
					StringBuffer getMethodName = new StringBuffer("get");
					getMethodName.append(fieldname.substring(0, 1)
							.toUpperCase());
					getMethodName.append(fieldname.substring(1));

					Method getMethod = pojoClass.getMethod(getMethodName
							.toString(), new Class[] {});

					methodObj.add(getMethod);
					if (excel.exportConvertSign() == 1) {
						StringBuffer getConvertMethodName = new StringBuffer(
								"get");
						getConvertMethodName.append(fieldname.substring(0, 1)
								.toUpperCase());
						getConvertMethodName.append(fieldname.substring(1));
						getConvertMethodName.append("Convert");
						// System.out.println("convert: "+getConvertMethodName.toString());
						Method getConvertMethod = pojoClass
								.getMethod(getConvertMethodName.toString(),
										new Class[] {});
						convertMethod.put(getMethodName.toString(),
								getConvertMethod);
					}
				}
			}
			int index = 0;
			// 产生表格标题行
			Row row = sheet.createRow(index);
			for (int i = 0, exportFieldTitleSize = exportFieldTitle.size(); i < exportFieldTitleSize; i++) {
				Cell cell = row.createCell(i);
				// cell.setCellStyle(style);
				RichTextString text = new HSSFRichTextString(exportFieldTitle
						.get(i));
				cell.setCellValue(text);
			}

			// 设置每行的列宽
			for (int i = 0; i < exportFieldWidth.size(); i++) {
				// 256=65280/255
				sheet.setColumnWidth(i, 256 * exportFieldWidth.get(i));
			}
			Iterator its = dataSet.iterator();
			// 循环插入剩下的集合
			while (its.hasNext()) {
				// 从第二行开始写,第一行是标题
				index++;
				row = sheet.createRow(index);
				Object t = its.next();
				for (int k = 0, methodObjSize = methodObj.size(); k < methodObjSize; k++) {
					Cell cell = row.createCell(k);
					Method getMethod = methodObj.get(k);
					Object value = null;
					if (convertMethod.containsKey(getMethod.getName())) {
						Method cm = convertMethod.get(getMethod.getName());
						value = cm.invoke(t, new Object[] {});
					} else {
						value = getMethod.invoke(t, new Object[] {});
					}
					cell.setCellValue(value == null ? "" : value.toString());
				}
			}

			workbook.write(out);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

 【导入工具类】

 

 注意: 

				//先设置Cell的类型,然后就可以把纯数字作为String类型读进来了:
				cell.setCellType(Cell.CELL_TYPE_STRING);
/**
		 * 导入 excel
		 * @param file
		 * @param pojoClass
		 * @param pattern
		 * @return
		 */
		public static Collection importExcel(File file ,Class pojoClass) {
			Collection dist = new ArrayList<Object>();
			try {
			// 得到目标目标类的所有的字段列表
			Field filed[] = pojoClass.getDeclaredFields();
			// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
			Map<String,Method> fieldSetMap = new HashMap<String,Method>();
			Map<String,Method> fieldSetConvertMap = new HashMap<String,Method>();
			// 循环读取所有字段
			for (int i = 0; i < filed.length; i++) {
			Field f = filed[i];
			// 得到单个字段上的Annotation
			Excel excel = f.getAnnotation(Excel.class);
			// 如果标识了Annotationd的话
			if (excel != null) {
			// 构造设置了Annotation的字段的Setter方法
			String fieldname = f.getName();
			String setMethodName = "set"
			+ fieldname.substring(0, 1).toUpperCase()
			+ fieldname.substring(1);
			// 构造调用的method,
			Method setMethod = pojoClass.getMethod(setMethodName,
			new Class[] { f.getType() });
			// 将这个method以Annotaion的名字为key来存入。
			//对于重名将导致 覆盖 失败,对于此处的限制需要
			fieldSetMap.put(excel.exportName(), setMethod);
			if(excel.importConvertSign()==1)
			{
			StringBuffer setConvertMethodName = new StringBuffer("set");
			setConvertMethodName.append(fieldname.substring(0, 1)
			.toUpperCase());
			setConvertMethodName.append(fieldname.substring(1));
			setConvertMethodName.append("Convert");
			Method getConvertMethod = pojoClass.getMethod(setConvertMethodName.toString(),
			new Class[] {String.class});
			fieldSetConvertMap.put(excel.exportName(), getConvertMethod);
			}
			}
			}
			// 将传入的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;
			while (row.hasNext()) {
			// 标题下的第一行
			Row rown = row.next();
			// 行的所有列
			Iterator<Cell> cellbody = rown.cellIterator();
			// 得到传入类的实例
			Object tObject = pojoClass.newInstance();
			int k = 0;
			// 遍历一行的列
			while (cellbody.hasNext()) {
			Cell cell = cellbody.next();
			// 这里得到此列的对应的标题
			String titleString = (String) titlemap.get(k);
			// 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
			if (fieldSetMap.containsKey(titleString)) {
			Method setMethod = (Method) fieldSetMap.get(titleString);
			//得到setter方法的参数
			Type[] ts = setMethod.getGenericParameterTypes();
			//只要一个参数
			String xclass = ts[0].toString();
			//判断参数类型
			if (fieldSetConvertMap.containsKey(titleString)) {
			fieldSetConvertMap.get(titleString).invoke(tObject,
			cell.getStringCellValue());
			} else {
			if (xclass.equals("class java.lang.String")) {
				//先设置Cell的类型,然后就可以把纯数字作为String类型读进来了:
				cell.setCellType(Cell.CELL_TYPE_STRING);
			setMethod.invoke(tObject, cell
			.getStringCellValue());
			}
			else if (xclass.equals("class java.util.Date")) {
				try{
					setMethod.invoke(tObject, cell
							.getDateCellValue());
												
				}catch(Exception e){
					
				}
			}
			else if (xclass.equals("class java.lang.Boolean")) {
			setMethod.invoke(tObject, cell
			.getBooleanCellValue());
			}
			else if (xclass.equals("class java.lang.Integer")) {
			setMethod.invoke(tObject, new Integer(cell
			.getStringCellValue()));
			}else if(xclass. equals("class java.lang.Long"))
			{
			setMethod.invoke(tObject,new Long( cell.getStringCellValue()));
			}
			}
			}
			// 下一列
			k = k + 1;
			}
			dist.add(tObject);
			}
			} catch (Exception e) {
			e.printStackTrace();
			return null;
			}
			return dist;
		}

 

 

 

  • 大小: 50.3 KB
分享到:
评论
1 楼 sudaxian 2016-06-30  
哥啊。得多少jar支持说一声啊,你这完全是写给自己看的。jar包我找了好久都找不全。

相关推荐

    通用数据库导入导出excel.pdf

    通用数据库导入导出excel.pdf

    jeecg Excel通过模板导出

    Jeecg提供了相应的API或服务,开发者可以通过这些接口指定模板文件的位置,并指定导出的数据源,如数据库查询结果或内存中的数据对象。 在实际应用中,导出过程会根据数据填充模板。Jeecg会遍历数据源,将每一条...

    excel表导入数据库 数据库导出excel(idea平台)

    - 数据校验:在将Excel数据导入数据库前,进行数据格式和完整性检查。 - 错误处理:捕获并处理可能出现的异常,如文件读取错误、数据库连接失败等。 - 性能优化:大量数据导入时,可以使用批处理操作,减少与数据库...

    数据库 导入 导出 Excel(程序和源码)

    描述中提到的“程序可以完成从 数据库 生成 Excel 或者从Excel导入数据库”,这涉及到两个主要操作:导出和导入。导出是从数据库中提取数据并将其格式化为Excel文件,而导入则是反过来,将Excel文件的数据加载到...

    一个通用从数据库导出excel、excel导入数据库组件所用到的jar包

    标题中的“一个通用从数据库导出excel、excel导入数据库组件所用到的jar包”指的是一个Java开发的工具,主要用于数据的导入导出操作。这个工具可以方便地将数据库中的数据导出为Excel格式,同时也可以将Excel文件中...

    Oracle数据库导入导出工具

    本工具是一款基于Java编写的桌面应用程序,专为Oracle数据库的导入导出提供便利。 1. **Oracle数据库导入导出的重要性** - 数据迁移:当需要将数据从一个Oracle实例迁移到另一个实例时,导入导出工具是关键。 - ...

    sql server 数据库导入导出方法

    SQL Server 数据库导入导出的方法 SQL Server 数据库导入导出是数据库管理员和开发者常用的操作,目的是将数据库备份到本地或网络存储设备中,以便在需要时恢复数据库或将数据库迁移到其他服务器上。下面将详细介绍...

    MYSQL 数据库导入导出命令

    MYSQL 数据库导入导出命令 MySQL 数据库导入导出命令是数据库管理员和开发者经常使用的命令,用于将 MySQL 数据库导出到文件中,以便备份、还原或迁移到其他服务器。下面将详细介绍 MySQL 数据库导入导出的命令和...

    数据库结构导出excel

    总结来说,“数据库结构导出Excel”是一项实用的技巧,它能够帮助我们更方便地管理和交流数据库的信息。通过选择合适的工具和方法,我们可以将复杂的数据库结构转化为直观易懂的Excel文件,从而提高工作效率和协作...

    DB2数据库导入导出

    DB2 数据库导入导出 DB2 数据库导入导出的操作方法是指将用户的 DB2 数据库导出并导入到自己的 DB2 数据库上。由于 DB2 没有直接的数据库导出功能,因此需要导出表结构、表数据,然后在导入。 一、导出表结构 在 ...

    linux下数据库导入导入导出EXCEL文件

    然而,在实际应用中,我们经常需要将数据库中的数据导出到Excel文件中进行查看或者编辑,反之亦然。本文将详细介绍如何在Linux环境下通过命令行操作SQLite数据库,实现数据的导入导出功能。 #### 二、准备工作 在...

    数据库和excel之间的导入导出

    总的来说,熟练掌握数据库和Excel之间的导入导出技巧,对于数据工作者来说是至关重要的技能。这不仅可以提高工作效率,还能在各种数据处理和分析场景中发挥关键作用。通过不断学习和实践,我们可以更好地应对日益...

    【转】通用从数据库导出excel、excel导入数据库组件

    标题中的“通用从数据库导出excel、excel导入数据库组件”是指一种软件工具或技术,它允许用户方便地将数据从数据库导出到Excel电子表格格式,并能将Excel数据反向导入回数据库。这样的组件通常在数据迁移、数据分析...

    易语言超级列表框一秒极速导入导出excel和数据库模块

    以往的易程序导出excel太慢了,特别是数据比较多的时候,本程序写excel模板的方法极速导入导出excel或者数据库,1万条数据不用一秒钟的时间,速度杠杠的,大家可以试试效果。本例子是用超级列表框做例子,如有需要...

    spring boot+mybatis plus+easy poi实现数据库导出成excel和excel导入到数据库.zip

    在本项目中,"spring boot+mybatis plus+easy poi实现数据库导出成excel和excel导入到数据库",开发者利用了Spring Boot、MyBatis Plus和EasyPoi库来实现了一个功能强大的数据交互系统,允许用户将数据库中的数据...

    不同类型数据库导入导出

    ### 不同类型数据库导入导出详解 在信息技术领域中,数据迁移是一项常见且重要的任务,尤其是在不同的数据库系统间进行数据转换时。本文将基于提供的部分代码样例,深入探讨Access、Visual FoxPro(VFP)、SQL等...

    NPOI_数据库导入导出Excel运用Excel

    利用NPOI组件,将数据库中表,或查询结果导出Excel以及将Excel中数据导入到数据库中

    数据库导入导出工具DataPie3.0

    功能:DataPie可以把EXCEL2007的数据导入SQL server2008或者ACCESS 2007数据库中,也可以把数据库中的表导出到excel2007,同时可以通过该工具运算数据库中的存储过程。 更新 V1.0,2012年2月3日 支持sql server导入...

    数据库导入导出工具(可以导出ORACLE)

    数据库导入导出是数据库管理中的重要环节,尤其在数据迁移、备份、恢复和系统整合时显得尤为关键。这里我们主要讨论的是针对ORACLE数据库的导入导出工具,它能够帮助用户方便地处理大量数据的传输。 Oracle数据库...

Global site tag (gtag.js) - Google Analytics