FineUploader既是开源的又是收费的,这个没搞懂。
先看效果:
.....
很清爽。
成功和失败很清楚。
从网上找到了这个插件的几个文件:
- fineuploader-4.1.0.min.css
- jquery.fineuploader-4.1.0.min.js
- loading.gif
- processing.gif
后2个是动画效果。
环境:
ASP.NET MVC 4
使用到的文件:
- fineuploader-4.1.0.min.css
- jquery.fineuploader-4.1.0.min.js
- loading.gif
- processing.gif
- jquery-1.8.3.min.js
View
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.8.3.min.js" type="text/javascript"></script>
<script src="~/Scripts/FineUploader/jquery.fineuploader-4.1.0.min.js" type="text/javascript"></script>
<link href="~/Scripts/FineUploader/fineuploader-4.1.0.min.css" rel="stylesheet" /> <script type="text/javascript">
$(document).ready(function () {
var manualuploader = $('#manual-fine-uploader').fineUploader({
request: {
endpoint: '/FineUploader/Index'
},
validation: {
//itemLimit: 3,
allowedExtensions: ['jpg', 'xlsx','xls', 'txt'],
sizeLimit: 10240000 // 10M
},
template: "qq-template-manual-noedit",
autoUpload: false, callbacks:
{
//文件开始提交(在浏览窗口中选择的每个文件都会触发该事件)
//id:文件在队列中的索引
//fileName:文件名称
onSubmit: function (id, fileName) {
//alert('this is onSubmit Function,your selected is:' + fileName);
//只能上传规定的文件
var name = fileName.split('.')[0];//不带后缀名
switch (name) {
case 'Member':
break;
case 'Guestbook':
break;
default:
alert('请选择正确的文件上传!');
return false;
break;
}
},
//文件开始上传
onUpload: function (id, fileName) {
$('#file-' + id).addClass('alert-info')
.html('<img src="../Scripts/FineUploader/loading.gif" alt="" /> alt="Initializing. Please hold."> ' +
'Initializing ' +
'“' + fileName + '”');
$('#progress').show();//显示进度动画
},
//文件上传失败
onError: function (event, id, name, errorReason, xhrOrXdr) {
//alert(qq.format("Error on file number {} - {}. Reason: {}", id, name, errorReason));
//$('#message').append('上传文件失败:' + id, '<br/>' + name,+'<br/>'+ errorReason.response + '<br/>');
},
//文件上传结束
onComplete: function (id, fileName, responseJSON) {
//alert('This is onComplete function.');
//alert("complete name:"+responseJSON.name);//responseJSON就是controller传来的return Json
$('#message').append(responseJSON.msg);
$('#progress').hide();//隐藏进度动画
//清除已上传队列
$('.qq-upload-list').hide();
//$('#manual-fine-uploader').fineUploader('reset');//(这个倒是清除了,但是返回的信息$('#message')里只能保留一条。)
}
}
}); $('#triggerUpload').click(function () {
manualuploader.fineUploader('uploadStoredFiles');
});
});
</script>
<script type="text/template" id="qq-template-manual-noedit">
<div class="qq-uploader-selector qq-uploader">
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
<span>Drop files here to upload</span>
</div>
<div class="qq-upload-button-selector qq-upload-button">
<div>选择文件</div>
</div>
<span class="qq-drop-processing-selector qq-drop-processing">
<span>Processing dropped files...</span>
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
</span>
<ul class="qq-upload-list-selector qq-upload-list">
<li>
@*<div class="qq-progress-bar-container-selector">
<div class="qq-progress-bar-selector qq-progress-bar"></div>
</div>*@
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
<span class="qq-upload-file-selector qq-upload-file"></span>
<span class="qq-upload-size-selector qq-upload-size"></span>
<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">取消</a>
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
</li>
</ul>
</div>
</script>
<style type="text/css">
.btn {
background-color: #F87436;
background-image: -moz-linear-gradient(center top, #F88D5A, #E65C47);
color: #FFFFFF;
text-shadow: none;
width: 93px;
text-align: center;
cursor: pointer;
padding: 6px;
} #message {
margin-top: 1px;
} #message p {
margin: 0px;
padding: 9px;
color: white;
}
</style>
</head>
<body>
<!-- Fine Uploader DOM Element -->
<div id="manual-fine-uploader"></div>
<div id="triggerUpload" class="btn btn-primary" style="margin-top: 10px;">
开始上传
</div>
<img id="progress" src="../Scripts/FineUploader/loading.gif" style="display: none;" />
<div id="message"></div>
</body>
</html>
这里使用了js的模板<script type="text/template" id="qq-template-manual-noedit">
Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase qqfile)//qqfile是个固定的名称!
{
string msg = "";
if (qqfile != null && qqfile.ContentLength > )
{
var fileNameWithExtension = Path.GetFileName(qqfile.FileName);
var fileName = Path.GetFileNameWithoutExtension(qqfile.FileName);
var path = Path.Combine(Server.MapPath("~/Uploads"), fileNameWithExtension); try
{
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
qqfile.SaveAs(path); //写入数据库
string tbName = "";
List<string> columnMapping = null;
ImportAndExport.MappingColumn(fileName, out tbName, out columnMapping);
ImportAndExport.ImportExcel(path, tbName, columnMapping);
System.IO.File.Delete(path);
msg = "<p style='background-color:#5DA30C'>写入成功: " + fileName + "</p>";
}
catch (Exception ex)
{
System.IO.File.Delete(path);
msg = "<p style='background-color:#D60000'>写入失败: " + fileName + " [" + ex.Message + "]</p>";
return Json(new { success = false, error = ex.Message, msg = msg }, "text/html");
}
}
//返回的json要有success字段:success = true 上传成功;success=false 上传失败。
return Json(new { success = true, name = qqfile.FileName, msg = msg }, "text/html");
}
帮助类:ImportAndExport
///<summary>导入Excel数据</summary>
/// <param name="filePath">上传文件路径</param>
/// <param name="dbTableName">数据库表名</param>
/// <param name="columnMapping">数据表列映射</param>
public static void ImportExcel(string filePath, string dbTableName, List<string> columnMapping = null)
{
//Create connection string to Excel work book
string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1';";
//Create Connection to Excel work book
using (OleDbConnection excelConnection = new OleDbConnection(excelConnectionString))
{
using (OleDbCommand excelCommand = new OleDbCommand("Select * from [Sheet1$]", excelConnection))
{
excelConnection.Open();//打开连接
OleDbDataReader excelReader = excelCommand.ExecuteReader();
using (DataTable dt = new DataTable())
{
dt.Load(excelReader);//转为DataTable
//已映射的列会传递给批量写入模块,此处只添加不在Excel表格中出现的字段,如一些共有字段或特殊字段。
dt.Columns.Add(new DataColumn("CreatedBy", typeof(System.String)));
dt.Columns.Add(new DataColumn("CreatedOn", typeof(System.DateTime))); //填充字段值
foreach (DataRow dr in dt.Rows)
{
dr["CreatedBy"] = "Test";
dr["CreatedOn"] = DateTime.Now;
} try
{//包含增加的字段映射传递给批量写入模块
BatchCopy0(dt, dbTableName, columnMapping);
}
catch (Exception)
{
excelCommand.Dispose();
excelConnection.Close();//关闭excel连接
throw;
}
}
excelConnection.Close();//关闭连接
}
}
}
///<summary>字段映射</summary>
///<param name="fileName">文件名称</param>
///<param name="columnMapping">输出映射表</param>
///<param name="tbName">数据库表名</param>
public static void MappingColumn(string fileName, out string tbName, out List<string> columnMapping)
{
tbName = "";
columnMapping = new List<string>(); if (fileName != null)
{
switch (fileName)
{
case "Member":
tbName = "Member";
columnMapping.Add("姓名,Name");
columnMapping.Add("邮箱,Email");
columnMapping.Add("生日,Birthday");
columnMapping.Add("年龄,Age");
break;
case "Guestbook":
tbName = "Guestbooks";
columnMapping.Add("消息,Message");
break;
default:
break;
}
////以下字段未在Excel表格中出现,需传给SqlBulkCopy。
columnMapping.Add("CreatedBy,CreatedBy");
columnMapping.Add("CreatedOn,CreatedOn");
}
}
///<summary>复制数据-不带事务的</summary>
/// <param name="dt">源数据</param>
/// <param name="tbName">目标数据表名称</param>
///<param name="columnMapping">完整的字段映射</param>
public static void BatchCopy0(DataTable dt, string tbName, List<string> columnMapping)
{
using (SqlBulkCopy sbc = new SqlBulkCopy(sqlConnectionString, SqlBulkCopyOptions.KeepNulls))
{
sbc.DestinationTableName = tbName; if (columnMapping != null)
{
foreach (var mapping in columnMapping)
{
var split = mapping.Split(new[] { ',' });
sbc.ColumnMappings.Add(split.First(), split.Last());
}
}
try
{
sbc.WriteToServer(dt);
}
catch (Exception ex)
{
throw ex;
}
}
}
Excel表格样式:
--End--