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

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

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

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

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

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

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页面如下图所示:

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();

}

}

文件路径

required="true" type="file" missingMessage="请选择上传文件" />

导入excel

导出excel

5、action处理如下图所示:

注意:

这个name对应后台的 private File upload; 约定, 标志不仅仅是绑定到upload,

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

因此,对应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 values = new ArrayList();

List 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 listUsers = (List)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 exportFieldTitle = new ArrayList();

List exportFieldWidth = new ArrayList();

// 拿到所有列名,以及导出的字段的get方法

List methodObj = new ArrayList();

Map convertMethod = new HashMap();

// 得到所有字段

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();

try {

// 得到目标目标类的所有的字段列表

Field filed[] = pojoClass.getDeclaredFields();

// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中

Map fieldSetMap = new HashMap();

Map fieldSetConvertMap = new HashMap();

// 循环读取所有字段

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 = sheet.rowIterator();

// 得到第一行,也就是标题行

Row title = row.next();

// 得到第一行的所有列

Iterator 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 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;

}

jeecg输入中文查询导表为空_JEECG 通用数据库导入导出excel相关推荐

  1. jeecg输入中文查询导表为空_学术利器—SCI期刊影响因子查询/中文核心期刊查询系统更新...

    吐槽 想起自己第一次投中文期刊的情形:当时学校最低要求是发表一篇核心级别的期刊论文,但是哪些期刊是核心期刊呢?完全不知道!都怎么投稿呢?也完全不知道!只能问问周围的同学或者师兄师姐.他们也就知道谁谁谁 ...

  2. jeecg输入中文查询导表为空_简单查询

    语法 1.sql以 ; 结尾 2.sql不区分关键字大小写 3.输入符号时候只能使用英文 4.列名不加引号 基本查询语句 1. select 列名,列名 from 表名; 2. select * fr ...

  3. 将查询好的快递单号以及物流导出EXCEL表格

    最近有很多朋友在问,如何查询多家快递,并将物流导出EXCEL表格保存呢?今天小编给大家分享一个新的查询技巧,下面一起来试试吧. 材料准备: 一台Win系统的电脑 快递单号若干 步骤演示: 运行[快递批 ...

  4. java实现这个无表头空表格,《java程序导出excel表格是空白的没有数据?》 java怎么导入数据库...

    java程序导出excel表格是空白的没有数据? 看一下是否可以链接上数据库,或者查看一下链接的数据库是否有数据 java从数据库中导出excel poi 建议你使用pageoffice. java ...

  5. Java 实现查询数据库下载导出Excel详解

    Excel表头 测试→下载导出表头文件,也可以改成直接存到本地磁盘目录下. package com.kero99.utils;import java.io.File; import java.io.F ...

  6. 导Excel数据到Oracle的脚本,Oracle使用TOAD实现导入导出Excel数据

    在Oracle应用程序的开发过程中,访问数据库对象和编写SQL程序是一件乏味且耗费时间的工作,对数据库进行日常管理也是需要很多SQL脚本才能完成的.Quest Software为此提供了高效的Orac ...

  7. windows 导oracle用户,windows下Oracle导入导出用户数据

    Oracle导入导出用户数据 -- 导出用户 -- 一.新建目录.目录名称:third,目录路径:E:\OracleUserCeshi create directory third as 'E:\Or ...

  8. MySQL 中文查询条件返回结果为空 查询结果为空

    问题: 最近在做一个APP,APP要通过jdbc直接调用SQL访问MySQL的数据库,其他问题先不说,遇到一个奇怪的现象,同样一条SQL语句,用Navicat去执行的时候,就可以查出来数据库记录数据, ...

  9. php页面表格导出excel表格数据类型,php页面表格导出excel表格数据类型-php导出excel是不是导出整个表的?可不可以导出指......

    php 怎么把数据导出到excel表格 昨天项目里有个新需求,客户希望把一些数据能导出成为Excel表格,刚开始用PHP原生输入Excel表格,发现效果不是很理想,于是找到一个比较著名的库:PHPEx ...

最新文章

  1. 使用SQL Server Analysis Services数据挖掘的关联规则实现商品推荐功能(五)
  2. IntelliJ Idea 快捷键列表
  3. 自助建站软件越来越友好,三大优点值得用心体会
  4. java声明和初始化数组_Java 中初始化数组
  5. 【移植驱动到Linux3.4.2内核之一】移植DM9000C网卡驱动
  6. 阿里健康上线新冠核酸检测服务:本周覆盖北京武汉等38城
  7. c++中sort()及qsort()的使用方法总结
  8. MODIS数据介绍及下载
  9. 轻松学python(一)
  10. opencv 中x,y,height, width,rows,cols 的关系
  11. iOS-Core Animation 核心动画高级编程/5-变换
  12. 云服务 saas_SaaS和云服务策划
  13. go test进行单元测试时,出现undefined方法或者command-line-arguments [build failed]解决方案
  14. MATLAB通信工具箱仿真16QAM系统
  15. 强化学习算法(一)————表格型方法
  16. js实现将阿拉伯数字转换成中文大写
  17. 计算机考研复试----技术前沿知识
  18. HiveServer2 频繁宕机根本原因分析
  19. 黑作坊风光大师完美破解版
  20. 透明度色值转换成十六进制色值

热门文章

  1. 从业五年java的感受 十
  2. 自动登录远程服务器脚本,iTerm2使用脚本自动登录远程服务器
  3. Location specified by ndk.dir (**/Sdk/ndk-bundle) did not contain a valid NDK ...
  4. 梦幻测试服务器维护要多久,梦幻西游:2.9维护没有测试服,百服平转要开放了...
  5. 区块链 拜占庭算法
  6. 我的Windows8体验
  7. 学习记录:图形界面系列教材
  8. 考研英语长难句(刘晓燕)笔记 第三课 名词(短语)和名词性从句
  9. 20230614使用360安全卫士的断网急救箱解决不能上网的问题
  10. SQL基础——查询基础