结合bootstrapfileinput插件和Bootstrap-table表格插件,实现。
。。
1、bootstrap-fileinpu的简单介绍
在前⾯的随笔,我介绍了Bootstrap-table表格插件的具体项⽬应⽤过程,本篇随笔介绍另外⼀个Bootstrap FieInput插件的使⽤,整合两者可以实现我们常规的Web数据导⼊操作,导⼊数据操作过程包括有上传⽂件,预览数据,选择并提交记录等⼀系列操作。
关于这个插件,我在早期随笔《》也做了⼀次介绍,这是⼀个增强的 HTML5 ⽂件输⼊控件,是⼀个 Bootstrap 3.x 的扩展,实现⽂件上传预览,多⽂件上传等功能。
bootstrap-fileinput源码:
bootstrap-fileinput在线API:
bootstrap-fileinput Demo展⽰:
这个插件主要是介绍如何处理图⽚上传的处理操作,原先我的Excel导⼊操作使⽤的是Uploadify插件,可
以参考我随笔《》,不过这个需要Flash控件⽀持,在某些浏览器(如Chrome)就⽐较⿇烦了,因此决定使⽤⼀种较为通⽤的上传插件,这次⾸先对基于Bootstrap前端架构的框架系统进⾏升级,替代原来的Uploadify插件,这样页⾯上传功能,在各个浏览器就可以⽆差异的实现了。
⼀般情况下,我们需要引⼊下⾯两个⽂件,插件才能正常使⽤:
bootstrap-fileinput/css/fileinput.min.css
bootstrap-fileinput/js/fileinput.min.js
在File input 插件使⽤的时候,如果是基于Asp.NET MVC的,那么我们可以使⽤BundleConfig.cs进⾏添加对应的引⽤,加⼊到Bundles集合引⽤即可。
//添加对bootstrap-fileinput控件的⽀持
css_metronic.Include("~/Content/MyPlugins/bootstrap-fileinput/css/fileinput.min.css");
js_metronic.Include("~/Content/MyPlugins/bootstrap-fileinput/js/fileinput.min.js");
js_metronic.Include("~/Content/MyPlugins/bootstrap-fileinput/js/locales/zh.js");
在页⾯中,我们使⽤以下HTML代码实现界⾯展⽰,主要的bootstrap fileinput插件声明,主要是基础的界⾯代码
<input id="excelFile" type="file">
Excel导⼊的的界⾯展⽰如下所⽰。
选择指定⽂件后,我们可以看到Excel的⽂件列表,如下界⾯所⽰。
上传⽂件后,数据直接展⽰在弹出层的列表⾥⾯,这⾥直接使⽤了 Bootstrap-table表格插件进⾏展⽰。
这样我们就可以把Excel的记录展⽰出来,实现了预览的功能,勾选必要的记录,然后保存即可提交到服务器进⾏保存,实现了Excel数据的真正导⼊数据库处理。
2、Excel导出操作详细介绍
我们在实际导⼊Excel的界⾯中,HTML代码如下所⽰。
<!--导⼊数据操作层-->
<div id="import" class="modal fade bs-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 class="modal-title">⽂件导⼊</h4>
</div>
<div class="modal-body">
<div >
<a href="~/Content/Template/TestUser-模板.xls" onclick="javascript:Preview();">
<img alt="测试⽤户信息-模板" src="~/Content/images/ico_excel.png"/>
<span >TestUser-模板.xls</span>
</a>
</div>
<hr/>
<form id="ffImport" method="post">
<div title="Excel导⼊操作" >
<input type="hidden" id="AttachGUID" name="AttachGUID"/>
<input id="excelFile" type="file">
inputtypefile不上传文件
</div>
</form>
<!--数据显⽰表格-->
<table id="gridImport" class="table table-striped table-bordered table-hover" cellpadding="0" cellspacing="0" border="0"> </table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="SaveImport()">保存</button>
</div>
</div>
</div>
</div>
对于bootstrap fileinput的各种属性,我们这⾥使⽤JS进⾏初始化,这样⽅便统⼀管理和修改。
//初始化Excel导⼊的⽂件
function InitExcelFile() {
//记录GUID
$("#AttachGUID").val(newGuid());
$("#excelFile").fileinput({
uploadUrl: "/FileUpload/Upload",//上传的地址
uploadAsync: true,              //异步上传
language: "zh",                //设置语⾔
showCaption: true,              //是否显⽰标题
showUpload: true,              //是否显⽰上传按钮
showRemove: true,              //是否显⽰移除按钮
showPreview : true,            //是否显⽰预览按钮
browseClass: "btn btn-primary", //按钮样式
dropZoneEnabled: false,        //是否显⽰拖拽区域
allowedFileExtensions: ["xls", "xlsx"], //接收的⽂件后缀
maxFileCount: 1,                        //最⼤上传⽂件数限制
previewFileIcon: '<i class="glyphicon glyphicon-file"></i>',
allowedPreviewTypes: null,
previewFileIconSettings: {
'docx': '<i class="glyphicon glyphicon-file"></i>',
'xlsx': '<i class="glyphicon glyphicon-file"></i>',
'pptx': '<i class="glyphicon glyphicon-file"></i>',
'jpg': '<i class="glyphicon glyphicon-picture"></i>',
'pdf': '<i class="glyphicon glyphicon-file"></i>',
'zip': '<i class="glyphicon glyphicon-file"></i>',
},
uploadExtraData: {  //上传的时候,增加的附加参数
folder: '数据导⼊⽂件', guid: $("#AttachGUID").val()
}
})  //⽂件上传完成后的事件
.on('fileuploaded', function (event, data, previewId, index) {
var form = data.form, files = data.files, extra = a,
response = sponse, reader = ader;
var res = sponse; //返回结果
if (res.Success) {
showTips('上传成功');
var guid = $("#AttachGUID").val();
//提⽰⽤户Excel格式是否正常,如果正常加载数据
$.ajax({
url: '/TestUser/CheckExcelColumns?guid=' + guid,
type: 'get',
dataType: 'json',
success: function (data) {
if (data.Success) {
InitImport(guid); //重新刷新表格数据
showToast("⽂件已上传,数据加载完毕!");
//重新刷新GUID,以及清空⽂件,⽅便下⼀次处理
RefreshExcel();
}
else {
showToast("上传的Excel⽂件检查不通过。请根据页⾯右上⾓的Excel模板格式进⾏数据录⼊。", "error");
}
}
});
}
else {
showTips('上传失败');
}
});
}
上⾯的逻辑具体就是,设置上传⽂件的后台页⾯为:/FileUpload/Upload,以及各种插件的配置参数,uploadExtraData⾥⾯设置的是提交的附加参数,也就是后台控制器接收的参数,其中
.on('fileuploaded', function (event, data, previewId, index) {
的函数处理⽂件上传后的处理函数,如果上传⽂件返回的结果是成功的,那么我们再次调⽤ajax来检查这个Excel的字段是否符合要求,如下地址:
url: '/TestUser/CheckExcelColumns?guid=' + guid,
如果这个检查的后台返回成功的记录,那么再次需要把Excel记录提取出来预览,并清空bootstrap fileinput⽂件上传插件,⽅便下次上传⽂件。如下代码所⽰。
if (data.Success) {
InitImport(guid); //重新刷新表格数据
showToast("⽂件已上传,数据加载完毕!");
//重新刷新GUID,以及清空⽂件,⽅便下⼀次处理
RefreshExcel();
}
else {
showToast("上传的Excel⽂件检查不通过。请根据页⾯右上⾓的Excel模板格式进⾏数据录⼊。", "error");
}
其中RefreshExcel就是重新更新上传的附加参数值,⽅便下次上传,否则附加参数的值⼀直不变化,就会导致我们设置的GUID没有变化⽽出现问题。
//重新更新GUID的值,并清空⽂件
function RefreshExcel() {
$("#AttachGUID").val(newGuid());
$('#excelFile').fileinput('clear');//清空所有⽂件
//附加参数初始化后⼀直不会变化,如果需要发⽣变化,则需要使⽤refresh进⾏更新
$('#excelFile').fileinput('refresh', {
uploadExtraData: { folder: '数据导⼊⽂件', guid: $("#AttachGUID").val() },
});
}
⽽其中InitImport就是获取预览数据并展⽰在Bootstrap-table表格插件上的,关于这个插件的详细使⽤,可以回顾下随笔《》进⾏了解即可。
//根据条件查询并绑定结果
var $import;
function InitImport(guid) {
var url = "/TestUser/GetExcelData?guid=" + guid;
$import = $('#gridImport').bootstrapTable({
url: url,                          //请求后台的URL(*)
method: 'GET',                      //请求⽅式(*)
striped: true,                      //是否显⽰⾏间隔⾊
cache: false,                      //是否使⽤缓存,默认为true,所以⼀般情况下需要设置⼀下这个属性(*)
pagination: false,                  //是否显⽰分页(*)
sidePagination: "server",          //分页⽅式:client客户端分页,server服务端分页(*)
pageNumber: 1,                      //初始化加载第⼀页,默认第⼀页,并记录
pageSize: 100,                    //每页的记录⾏数(*)
pageList: [10, 25, 50, 100],        //可供选择的每页的⾏数(*)
search: false,                      //是否显⽰表格搜索
strictSearch: true,
showColumns: true,                  //是否显⽰所有的列(选择显⽰的列)
showRefresh: true,                  //是否显⽰刷新按钮
minimumCountColumns: 2,            //最少允许的列数
clickToSelect: true,              //是否启⽤点击选中⾏
uniqueId: "ID",                    //每⼀⾏的唯⼀标识,⼀般为主键列
queryParams: function (params) { },
columns: [{
checkbox: true,
visible: true//是否显⽰复选框
}, {
field: 'Name',
title: '姓名'
}, {
field: 'Mobile',
title: '⼿机'
}, {
field: 'Email',
title: '邮箱',
formatter: emailFormatter
}, {
field: 'Homepage',
title: '主页',
formatter: linkFormatter
}, {
field: 'Hobby',
title: '兴趣爱好'
}, {
field: 'Gender',
title: '性别',
formatter: sexFormatter
}, {
field: 'Age',
title: '年龄'
}, {
field: 'BirthDate',
title: '出⽣⽇期',
formatter: dateFormatter
}, {
field: 'Height',
title: '⾝⾼'
}, {
field: 'Note',
title: '备注'
}],
onLoadSuccess: function () {
},
onLoadError: function () {
showTips("数据加载失败!");
},
});
}
最后就是确认提交后,会通过JS提交数据到后台进⾏处理,如下代码所⽰。
//保存导⼊的数据
function SaveImport() {
var list = [];//构造集合对象
var rows = $import.bootstrapTable('getSelections');
for (var i = 0; i < rows.length; i++) {
list.push({
'Name': rows[i].Name, 'Mobile': rows[i].Mobile, 'Email': rows[i].Email, 'Homepage': rows[i].Homepage,
'Hobby': rows[i].Hobby, 'Gender': rows[i].Gender, 'Age': rows[i].Age, 'BirthDate': rows[i].BirthDate,
'Height': rows[i].Height, 'Note': rows[i].Note
});
}
if (list.length == 0) {
showToast("请选择⼀条记录", "warning");
return;
}
var postData = { 'list': list };//可以增加其他参数,如{ 'list': list, 'Rucanghao': $("#Rucanghao").val() };
postData = JSON.stringify(postData);
$.ajax({
url: '/TestUser/SaveExcelData',
type: 'post',
dataType: 'json',
contentType: 'application/json;charset=utf-8',
traditional: true,
success: function (data) {
if (data.Success) {
//保存成功  1.关闭弹出层,2.清空记录显⽰ 3.刷新主列表
showToast("保存成功");
$("#import").modal("hide");
$(bodyTag).html("");
Refresh();
}
else {
showToast("保存失败:" + data.ErrorMessage, "error");
}
},
data: postData
});
}
3、后台控制器代码分析