php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤...

这篇文章主要介绍了BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤,需要的朋友可以参考下

bootstrap-fileinput源码:https://github.com/kartik-v/bootstrap-fileinput

bootstrap-fileinput在线API:http://plugins.krajee.com/file-input

bootstrap-fileinput Demo展示:http://plugins.krajee.com/file-basic-usage-demo

这个插件主要是介绍如何处理图片上传的处理操作,原先我的Excel导入操作使用的是Uploadify插件,可以参考我随笔《附件上传组件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插件声明,主要是基础的界面代码

Excel导入的的界面展示如下所示。

php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤..._第1张图片

选择指定文件后,我们可以看到Excel的文件列表,如下界面所示。

php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤..._第2张图片

上传文件后,数据直接展示在弹出层的列表里面,这里直接使用了 Bootstrap-table表格插件进行展示。

php 表格导入excel插件,BootStrap Fileinput插件和表格插件相结合实现导入Excel数据的文件上传、预览、提交的步骤..._第3张图片

这样我们就可以把Excel的记录展示出来,实现了预览的功能,勾选必要的记录,然后保存即可提交到服务器进行保存,实现了Excel数据的真正导入数据库处理。

2、Excel导出操作详细介绍

我们在实际导入Excel的界面中,HTML代码如下所示。

TestUser-模板.xls


关闭

保存

对于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: '',

allowedPreviewTypes: null,

previewFileIconSettings: {

'docx': '',

'xlsx': '',

'pptx': '',

'jpg': '',

'pdf': '',

'zip': '',

},

uploadExtraData: { //上传的时候,增加的附加参数

folder: '数据导入文件', guid: $("#AttachGUID").val()

}

}) //文件上传完成后的事件

.on('fileuploaded', function (event, data, previewId, index) {

var form = data.form, files = data.files, extra = data.extra,

response = data.response, reader = data.reader;

var res = data.response; //返回结果

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表格插件上的,关于这个插件的详细使用,可以回顾下随笔《基于Metronic的Bootstrap开发框架经验总结(16)-- 使用插件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、后台控制器代码分析

这里我们的JS代码里面,涉及了几个MVC后台的方法处理:Upload、CheckExcelColumns、GetExcelData、SaveExcelData。这里分别进行介绍。

文件上传的后台控制器方法如下所示。///

/// 上传附件到服务器上

///

/// 附件信息

/// 附件组GUID

/// 指定的上传目录

///

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Upload(string guid, string folder)

{

CommonResult result = new CommonResult();

HttpFileCollectionBase files = HttpContext.Request.Files;

if (files != null)

{

foreach (string key in files.Keys)

{

try

{

#region MyRegion

HttpPostedFileBase fileData = files[key];

if (fileData != null)

{

HttpContext.Request.ContentEncoding = Encoding.GetEncoding("UTF-8");

HttpContext.Response.ContentEncoding = Encoding.GetEncoding("UTF-8");

HttpContext.Response.Charset = "UTF-8";

// 文件上传后的保存路径

string filePath = Server.MapPath("~/UploadFiles/");

DirectoryUtil.AssertDirExist(filePath);

string fileName = Path.GetFileName(fileData.FileName); //原始文件名称

string fileExtension = Path.GetExtension(fileName); //文件扩展名

//string saveName = Guid.NewGuid().ToString() + fileExtension; //保存文件名称

FileUploadInfo info = new FileUploadInfo();

info.FileData = ReadFileBytes(fileData);

if (info.FileData != null)

{

info.FileSize = info.FileData.Length;

}

info.Category = folder;

info.FileName = fileName;

info.FileExtend = fileExtension;

info.AttachmentGUID = guid;

info.AddTime = DateTime.Now;

info.Editor = CurrentUser.Name;//登录人

result = BLLFactory.Instance.Upload(info);

if (!result.Success)

{

LogTextHelper.Error("上传文件失败:" + result.ErrorMessage);

}

}

#endregion

}

catch (Exception ex)

{

result.ErrorMessage = ex.Message;

LogTextHelper.Error(ex);

}

}

}

else

{

result.ErrorMessage = "fileData对象为空";

}

return ToJsonContent(result);

}

文件上传处理后,返回一个通用的CommonResult 的结果对象,也方便我们在JS客户端进行判断处理。

而其中检查我们导入Excel的数据是否满足列要求的处理,就是判断它的数据列和我们预先设置好的列名是否一致即可。//导入或导出的字段列表

string columnString = "姓名,手机,邮箱,主页,兴趣爱好,性别,年龄,出生日期,身高,备注";

///

/// 检查Excel文件的字段是否包含了必须的字段

///

/// 附件的GUID

///

public ActionResult CheckExcelColumns(string guid)

{

CommonResult result = new CommonResult();

try

{

DataTable dt = ConvertExcelFileToTable(guid);

if (dt != null)

{

//检查列表是否包含必须的字段

result.Success = DataTableHelper.ContainAllColumns(dt, columnString);

}

}

catch (Exception ex)

{

LogTextHelper.Error(ex);

result.ErrorMessage = ex.Message;

}

return ToJsonContent(result);

}

而GetExcelData则是格式化Excel数据到具体的List集合里面,这样我们方便在客户端进行各种属性的操作,它的代码如下所示。///

/// 获取服务器上的Excel文件,并把它转换为实体列表返回给客户端

///

/// 附件的GUID

///

public ActionResult GetExcelData(string guid)

{

if (string.IsNullOrEmpty(guid))

{

return null;

}

List list = new List();

DataTable table = ConvertExcelFileToTable(guid);

if (table != null)

{

#region 数据转换

int i = 1;

foreach (DataRow dr in table.Rows)

{

bool converted = false;

DateTime dtDefault = Convert.ToDateTime("1900-01-01");

DateTime dt;

TestUserInfo info = new TestUserInfo();

info.Name = dr["姓名"].ToString();

info.Mobile = dr["手机"].ToString();

info.Email = dr["邮箱"].ToString();

info.Homepage = dr["主页"].ToString();

info.Hobby = dr["兴趣爱好"].ToString();

info.Gender = dr["性别"].ToString();

info.Age = dr["年龄"].ToString().ToInt32();

converted = DateTime.TryParse(dr["出生日期"].ToString(), out dt);

if (converted && dt > dtDefault)

{

info.BirthDate = dt;

}

info.Height = dr["身高"].ToString().ToDecimal();

info.Note = dr["备注"].ToString();

info.Creator = CurrentUser.ID.ToString();

info.CreateTime = DateTime.Now;

info.Editor = CurrentUser.ID.ToString();

info.EditTime = DateTime.Now;

list.Add(info);

}

#endregion

}

var result = new { total = list.Count, rows = list };

return ToJsonContent(result);

}

另一个SaveExcelData的函数就是处理数据导入的最终处理函数,主要就是把集合写入到具体的数据库里面即可,具体代码如下所示。///

/// 保存客户端上传的相关数据列表

///

/// 数据列表

///

public ActionResult SaveExcelData(List list)

{

CommonResult result = new CommonResult();

if (list != null && list.Count > 0)

{

#region 采用事务进行数据提交

DbTransaction trans = BLLFactory.Instance.CreateTransaction();

if (trans != null)

{

try

{

//int seq = 1;

foreach (TestUserInfo detail in list)

{

//detail.Seq = seq++;//增加1

detail.CreateTime = DateTime.Now;

detail.Creator = CurrentUser.ID.ToString();

detail.Editor = CurrentUser.ID.ToString();

detail.EditTime = DateTime.Now;

BLLFactory.Instance.Insert(detail, trans);

}

trans.Commit();

result.Success = true;

}

catch (Exception ex)

{

LogTextHelper.Error(ex);

result.ErrorMessage = ex.Message;

trans.Rollback();

}

}

#endregion

}

else

{

result.ErrorMessage = "导入信息不能为空";

}

return ToJsonContent(result);

}

上面这几个函数的代码一般是比较有规律的,不需要一个个去编写,一般通过代码生成工具Database2Sharp批量生成即可。这样可以有效提高Web的界面代码和后台代码的开发效率,减少出错的机会。

整个导入Excel数据的处理过程,所有代码都贴出来了,基本上整个逻辑了解了就可以很好的了解这个过程的代码了。

你可能感兴趣的:(php,表格导入excel插件)