在给出代码之前,先说一下思想,要达到excel的上传,有两种方式可以选择,一种是打开grid,然后打开excel,选中要导入的excel记录,然后进行拖拽,在grid中要使用Ext.ux.grid.DataDrop插件,这种方式是在ext3.1中实现的,我没有在4.0中做过测试,这种方式的优点是比较直观,用户可以直接看到自己导入的数据,缺点是对于大批量的数据进行导入时比较困难;具体可参见http://loianegroner.com/2010/03/importing-an-excel-spreadsheet-into-an-extjs-datagrid-using-datadrop-grid-plugin/,例子下载:http://download.csdn.net/detail/jwl_yifeng/5997407
第二种方式便是通过poi对excel进行读取,然后存入数据库,我的整体思想是通过ext的upload将文件上传,然后再服务端给定地址进行保存文件,然后通过poi对文件进行读取,并把读取的数据插入数据库,然后返回成功标志,前台刷新grid;至于服务端要不要删除上传的文件随项目需求而定,用poi进行excel的导入与导出可以参见http://blog.csdn.net/jiawenlong_/article/details/10180967、http://blog.csdn.net/jiawenlong_/article/details/10181089;在spring+Ext环境下可参加如下代码:
相关jar包下载地址:http://download.csdn.net/detail/jwl_yifeng/5997427
1、首先给toolbar按钮添加事件:
{
itemId: 'uploadfile',
text: '导入',
iconCls: 'icon-grid',
handler: onItemUpload
}
2、onItemUpload函数,
function onItemUpload() {
var FileRname = new Ext.form.TextField({
name : 'FileRname',
fieldLabel : '文件名',
allowBlank : false,
emptyText : '发布用于显示的文件名',
anchor:'95%'
});
var AddfileForm=new Ext.FormPanel(
{
name : 'AddfileForm',
frame : true,
labelWidth : 90,
url : '../../uploadFiel.jspa',
fileUpload : true,
width : 420,
autoDestroy : true,
bodyStyle : 'padding:0px 10px 0;',
items : [{
xtype : 'filefield',
emptyText : '选择上传文件',
fieldLabel : '文件',
name : 'upfile',
buttonText : '',
anchor : '95%',
buttonCfg : {
iconCls : 'icon_upfile'
},
listeners : {
'fileselected' : function(fb, v) {
var temp = v.replace(
/^.*(\.[^\.\?]*)\??.*$/, '$1');
var temp1 = temp.toLocaleLowerCase();
alert(temp1);
if (allowfiletype.indexOf(temp1) == -1) {
Ext.Msg.alert("错误","不允许选择该类型文件,请重新选择!");
fb.setValue("");
FileRname.setValue("");
} else {
FileRname.setValue(v.replace(/^.+?\\([^\\]+?)(\.[^\.\\]*?)?$/gi,"$1"));
}
}
}
}]
});
var AddfileWin=new Ext.Window(
{
name : 'AddfileWin',
width : '450',
height : '340',
layout : 'fit',
closeAction : 'close',
title : '上传文件',
buttonAlign : 'center',
resizable : false,
modal : true,
autoDestroy : true,
items : AddfileForm,
buttons :[{
text : '保存',
handler : function() {
if (AddfileForm.getForm().isValid()) {
Ext.MessageBox.show({
title : '请稍等...',
msg : '文件上传中...',
progressText : '',
width : 300,
progress : true,
closable : false,
animEl : 'loding'
});
var tblname=document.getElementById("currentTbl").value;
AddfileForm.getForm().submit(
{
params: {
tbl: tblname
},
success : function(form, action) {
var Result = action.result.flag;
if (Result != 0) {
Ext.MessageBox.alert("提示",action.result.message);
AddfileWin.close();
var tabPanel = Ext.getCmp('centerTab');
SJSTgrid.getStore().reload();
tabPanel.setActiveTab(1);
} else if (Result == 0) {
Ext.MessageBox.alert("提示",action.result.message);
ds.load({
params : {
start : start,
limit : limit
}
});
AddfileForm.getForm().reset();
}
},
failure : function(form, action) {
Ext.MessageBox.alert("提示",
"服务器请求错误,请稍后再试!");
}
})
}
}
}, {
text : '重置',
handler : function() {
AddfileForm.getForm().reset();
}
}, {
text : '关闭',
handler : function() {
AddfileWin.close();
}
} ]
});
AddfileWin.show();
}
3、后台接收文件并读取插入导数据库:
@RequestMapping("uploadFiel.jspa")
public void upload(@RequestParam("upfile") CommonsMultipartFile upfile,@RequestParam("tbl") String tbl,HttpServletResponse rep) throws SQLException {
CommonsMultipartFile uploadExcel = upfile;
File file = new File("D://" + tbl+new Date().getTime()+".xlsx");
try {
uploadExcel.getFileItem().write(file);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
List<List> datas = this.getData(file, 1);//读取数据(读取数据的源Excel,读取数据忽略的行数)
String s="";
for(int i=0;i<datas.size();i++){
s +="insert into "+tbl+"(ids,name,color) values('"+datas.get(i).get(0)+"','"+datas.get(i).get(1)+"','"+datas.get(i).get(2)+"');";
}
if(s!=null&&!"".equals(s)){
String[] sqls = s.split(";");
for(int i=0;i<sqls.length;i++){
db.exec(sqls[i]);
}
}
PrintWriter out=null;
JSONObject jsonObject = JSONObject.fromObject( "{\"success\":true,\"message\":\"上传成功\"}" );
try {
rep.setContentType("text/html;charset=utf-8");
out = rep.getWriter();
// TODO Auto-generated catch block
out.write(jsonObject.toString());
} catch (IOException e) {
e.printStackTrace();
}
out.close();
}
protected List getData(File file, int ignoreRows) {
//result 第一维数组存储的是一行中格列的值,二维数组存储的是多少个行
List<List> result = new ArrayList<List>();
try {
//获取工作薄workbook
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(file)); //读取文件流
//获得 sheet总数
int sheetCount = workbook.getNumberOfSheets();
//遍历sheet
for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) {
//获得指定的sheet对象
HSSFSheet sheet = workbook.getSheetAt(sheetIndex);
//获得本sheet的总行数
int rowCount = sheet.getLastRowNum();
//如果没有数据
if(rowCount < 1){
return result;
}
//如果有数据 进入下边
//遍历行row ignoreRows忽略的行数。即标题行,不取
for (int rowIndex = ignoreRows; rowIndex <= rowCount; rowIndex++) {
//准备rowData 收集每一行数据
List<Object> rowData = new ArrayList<Object>();
//获得行row对象
HSSFRow row = sheet.getRow(rowIndex);
//如果此行为空,则进入下一个循环
if (row == null) {
continue;
}
//如果此行为不为空进入以下逻辑
//获得本行中单元格的个数
int cellCount = row.getLastCellNum();
//遍历每个单元格cell
for (int cellIndex = 0; cellIndex < cellCount; cellIndex++) {
//获得单元格cell对象
HSSFCell cell = row.getCell(cellIndex);
//获得指定单元格中的数据
Object cellContent = this.getCellContent(cell);
//将单元格内容放入 行数据中
rowData.add(cellContent);
}
//将每行的数据rowData 放入结果集中
result.add(rowData);
}
//将每个sheet的结果 此处忽略掉收集了
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//遍历完整个excel之后
return result;
}
}
/**
* 获取一个cell的数据类型
CELL_TYPE_STRING:字符型
CELL_TYPE_NUMERIC:数值型
CELL_TYPE_BOOLEAN:布尔型
CELL_TYPE_FORMULA:公式型
CELL_TYPE_BLANK:空值
* @param cell
* @return
*/
protected Object getCellContent(Cell cell) {
Object result = null;
//如果此单元格为空,则返回null;
if (cell == null) {
return result;
}
//单元格对象不为空
//单元格类型:Numeric:0, String:1, Formula:2, Blank:3, Boolean:4, Error:5
int cellType = cell.getCellType();
//判断单元格类型
switch (cellType) {
case HSSFCell.CELL_TYPE_STRING: //CELL_TYPE_STRING:字符型
String tempResult= cell.getRichStringCellValue().getString();
result=this.rightTrim(tempResult);
break;
case HSSFCell.CELL_TYPE_NUMERIC: //CELL_TYPE_NUMERIC:数值型
if(HSSFDateUtil.isCellDateFormatted(cell)){
result = cell.getDateCellValue();
}else{
result = cell.getNumericCellValue();
}
break;
case HSSFCell.CELL_TYPE_FORMULA: //CELL_TYPE_FORMULA:公式型
result = cell.getNumericCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: //CELL_TYPE_BOOLEAN:布尔型
result = cell.getBooleanCellValue();
break;
case HSSFCell.CELL_TYPE_BLANK:
result = null;
break;
case HSSFCell.CELL_TYPE_ERROR:
result = null;
break;
default:
System.out.println("枚举了所有类型");
break;
}
return result;
}
/**
* 去掉字符串右边的空格
* @param str 要处理的字符串
* @return 处理后的字符串
*/
protected static String rightTrim(String str) {
if (str == null) {
return "";
}
int length = str.length();
for (int i = length - 1; i >= 0; i--) {
if (str.charAt(i) != 0x20) {
break;
}
length--;
}
return str.substring(0, length);
}