前提:领导给了我一个文件夹,里面有4000千多张产品图片,每张图片已产品编号+产品名称命名,要求是让我把4000多张产品图片上传到服务器端,而且要以产品编码创建n个文件夹,每张图片放到对应的文件夹下。
思路:1、开始的思路是将整个文件夹都上传到服务器端,但查找资料获得,FileUpload只能上传文件,不能上传文件夹,从而得出另外一种方案,将文件夹压缩,然后便可以上传到服务器端,然后再服务器端解压,解压之后再去每个文件从新读取并放到对应的文件夹下。思量再三,觉得很是麻烦。
2、第二个思路,文件批量上传,在将文件上传到服务器端对应的文件夹下。感觉思路甚好。再查询资料,发现FileUpload控件的使用中,一个FileUpload控件一次只能选择一个文件,不能同时选择多个文件,果断放弃使用FileUpload上传文件,发现Jquery Uploadify是个不错的选择(注:为了安全,上传文件时是获得不到用户上传文件的本地路径)。
实战:Jquery Uploadify的使用
1、需要的js和css文件
2、添加产品类别的选择,用于向数据库新增数据时区分图片类别,图片类别分三种(1:包装;2:产品;3:标识)
js的引用:
1 <link href="../js/Uploadify/uploadify.css" rel="stylesheet" type="text/css" /> 2 <script src="../js/jquery-1.6.js" type="text/javascript"></script> 3 <script type="text/javascript" src="../js/Uploadify/jquery.uploadify.min.js"></script>
前端html代码:
1 <form id="form1" runat="server"> 2 <div style="position:absolute; top:10px; left:150px; 500px;"> 3 <%--用来作为文件队列区域--%> 4 <div id="fileQueue"> 5 </div> 6 <table style="font-size:15px; font-family:宋体;"> 7 <tr> 8 <th>产品图片类型:</th> 9 <td> 10 <input type="radio" id="rad1" value="1" name="radImageflg" checked="checked"/>包装 11 <input type="radio" id="rad2" value="2" name="radImageflg"/>产品 12 <input type="radio" id="rad3" value="3" name="radImageflg" />标识 13 </td> 14 </tr> 15 <tr> 16 <td> 17 <input type="file" name="uploadify" id="uploadify" /> 18 <%--<a href="javascript:$('#uploadify').uploadify('upload')">上传</a>| --%> 19 </td> 20 <td> 21 <img src="../images/quxiao.gif" onclick="cancelUpload()" /> 22 </td> 23 </tr> 24 </table> 25 </div> 26 </form>
效果图:
js代码:
1 <script type="text/javascript"> 2 //取消上传 3 function cancelUpload() { 4 $('#uploadify').uploadify('cancel') 5 } 6 $(function () { 7 $("#uploadify").uploadify({ 8 //指定swf文件 9 'swf': '../js/Uploadify/uploadify.swf', 10 //后台处理的页面 11 'uploader': 'PicUploadHandler.ashx', 12 //按钮显示的文字 13 'buttonText': '上传图片', 14 //显示的高度和宽度,默认 height 30;width 120 15 //'height': 15, 16 //'width': 80, 17 //上传文件的类型 默认为所有文件 'All Files' ; '*.*' 18 //在浏览窗口底部的文件类型下拉菜单中显示的文本 19 'fileTypeDesc': 'Image Files', 20 //允许上传的文件后缀 21 'fileTypeExts': '*.gif; *.jpg; *.png', 22 //发送给后台的其他参数通过formData指定 23 //'formData': { 'opt': 'upload', 'imageflg': $('input:radio[name="radImageflg"]:checked').val() }, 24 //上传文件页面中,你想要用来作为文件队列的元素的id, 默认为false 自动生成, 不带# 25 //'queueID': 'fileQueue', 26 //选择文件后自动上传 27 'auto': true, 28 //设置为true将允许多文件上传 29 'multi': true, 30 'queueSizeLimit': "100000", 31 'onUploadStart':function(file){ 32 var data = {}; 33 data.opt = 'upload'; 34 data.imageflg = $('input:radio[name="radImageflg"]:checked').val(); 35 $("#uploadify").uploadify('settings', 'formData', data); 36 }, 37 'onUploadSuccess': function (file, data, response) { //当文件上传成功时触发 38 if (data) { 39 if (data.indexOf("error") != -1) { 40 alert("上传失败:" + data); 41 } 42 } 43 }, 44 'onUploadError': function (file, errorCode, errorMsg) { 45 alert("上传失败:" + errorMsg); 46 this.settings.removeCompleted = false; 47 }54 55 }); 56 }); 57 58 </script>
说明:uploadify参数:swf:swf在下载的文档中就可以找到,路径一定要正确,否则不能打开选择文件的窗口;
动态传递参数:用户选择的图片类别,图片上传时,将图片类别传到后台,在页面加载的时候就直接加了Uploadify的相关参数设置,所以不能在Uploadify中传递参数,如何动态传递参数呢?
在页面此时就用到了'onUploadStart'方法,当开始上传时调用该方法,使用的方法是设置uploadify的formData参数
1 'onUploadStart':function(file){ 2 var data = {}; 3 data.opt = 'upload'; 4 data.imageflg = $('input:radio[name="radImageflg"]:checked').val(); 5 $("#uploadify").uploadify('settings', 'formData', data); 6 }
一般处理程序:
1 /// <summary> 2 /// 上传文件 3 /// </summary> 4 /// <param name="context"></param> 5 private void UploadFile(HttpContext context) 6 { 7 //接收上传后的文件 8 HttpPostedFile file = context.Request.Files["Filedata"]; 9 int imageflg = context.Request["imageflg"] != null ? int.Parse(context.Request["imageflg"].ToString()) : -1; 10 if (imageflg == -1 || file == null) 11 { 12 context.Response.Write("参数有错"); 13 } 14 else 15 { 16 //获取文件的保存路径 17 string filePath = HttpContext.Current.Server.MapPath(@"~/JTERPIMG"); 18 //判断上传的文件是否为空 19 if (file != null) 20 { 21 try 22 { 23 string res = (new ERPCLB.BLL.BasicData.PicUploadBLL()).UploadPic(file, filePath, imageflg); 24 context.Response.Write(res); 25 } 26 catch (Exception ex) 27 { 28 context.Response.Write("error:错误图片名称:" + file.FileName + ";" + ex.Message); 29 } 30 } 31 else 32 { 33 context.Response.Write("没有检测到要上传的文件"); 34 } 35 } 36 }
后台代码:
1 /// <summary> 2 /// 导入图片并新增数据 3 /// </summary> 4 /// <param name="file">上传的文件信息</param> 5 /// <param name="filePath">文件路径</param> 6 /// <param name="imageflg">文件类型(1:包装;2:产品;3:标识)</param> 7 /// <returns></returns> 8 public string UploadPic(HttpPostedFile file, string filePath, int imageflg) 9 { 10 PicUploadDAL dal=new PicUploadDAL(); 11 string fileName = file.FileName; 12 13 //string fileName = "0000002 2 副箱中间轴焊接总成1"; 14 15 string itemno = fileName.Substring(0, 7); //截取前7位获得产品编码 16 //string imageflg = fileName.Substring(itemno.Length, 1); //获得图片类型 17 18 int lined = dal.GetLineByItemno(itemno);//获得该产品图片的最大项号 19 #region 上传图片 20 //上传图片 21 filePath = Path.Combine(filePath, itemno); //服务器端图片路径 22 if (!Directory.Exists(filePath)) //如果目录不存在,则新建 23 { 24 Directory.CreateDirectory(filePath); 25 } 26 file.SaveAs(filePath + "\" + fileName);//保存文件 27 #endregion 28 29 #region 对图片重命名 30 string currFilePath = Path.Combine(filePath, fileName); //上传到服务器端的路径 31 string sourceFileName = currFilePath; 32 FileInfo fileInfo = new FileInfo(sourceFileName); 33 string newName = itemno + "_" + lined + fileInfo.Extension; //重新组织文件名称 34 currFilePath = Path.Combine(filePath, newName); 35 //判断重命名的文件是否存在,如果存在,则删除 36 if (File.Exists(currFilePath)) 37 { 38 File.Delete(currFilePath); 39 } 40 fileInfo.MoveTo(currFilePath); 41 #endregion 42 43 if (File.Exists(currFilePath)) //如果该路径下已经存在图片,说明导入成功,导入成功后,向数据库插入数据 44 { 45 PicExplorer pic = new PicExplorer() 46 { 47 itemno = itemno, 48 lineid = lined, 49 filename = newName, 50 imageflg = imageflg 51 }; 52 int res = (new PicUploadDAL()).InsertPic(pic); 53 if (res > 0) 54 { 55 return newName; 56 } 57 else 58 { 59 return "error"; 60 } 61 } 62 else 63 { 64 return "error"; 65 } 66 67 } 68 }
遇到的问题:
文件上传过程中,不但要将文件保存到服务器端的某个文件夹下,同时还要向数据库中插入数据,一开的想法是文件上传成功之后,向数据库中插入数据,也就是说放到"OnUploadSuccess"事件中,在使用ajax的Post方式调用后台插入数据的方法。但是插入少点图片没有问题,当插入700多张图片时,就会报错(此时我是设置了用户选择文件之后自动上传(auto参数设置为true),而不需要用户手动点击上传按钮。如果设置文件不是自动上传,也就是说用户手动点击了上传按钮之后再上传,估计问题会解决,但未尝试),原因是违反了主键约束,思量再三,感觉是上传成功与调用Post方法时产生冲突,未找到原因。
所以改为另外一种方案,在文件上传的过程中,判断服务器端对应的路径下面是否已经存在该图片,如果存在,则说明上传成功,如果不存在则说明上传失败,失败的话也就不需要再走向数据库插入数据的方法。