plupload 上传组件的使用

在这之前在感谢园子好多大牛的文章,在这里就不列出来了。

进入正题。

svn检索https://github.com/moxiecode/plupload 获取到代码,这篇文章使用的是v2.1.8

主要功能:

1、多文件上传

2、分片上传

3、显示进度条

先看看项目结构

<style>
        .trip-uploader .webuploader-container { float: left; position: relative; width: 20%; display: block; line-height: 1.4; background: #fff; border: 1px dashed #D2D1D6; border-radius: 6px; color: #ccc; padding: 15px 0; font-size: 13px; text-align: center; margin: 4px; cursor: pointer; }
        .webuploader-pick { width: 100%; display: block; cursor: pointer; overflow: hidden; }
        .trip-uploader .webuploader-container .icon-plus { width: 32px; height: 32px; display: block; margin: 10px auto; background: url(/images/upimagedefault.png) no-repeat; background-size: 32px; }
        .upload-btn { position: absolute; top: 0px; left: 0px; width: 100%; height: 98%; overflow: hidden; z-index: 0; }
        .file-item { width: 120px; height: 120px; float: left; position: relative; margin: 0 0 10px; padding: 4px; padding: 4px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: border .2s ease-in-out; -o-transition: border .2s ease-in-out; transition: border .2s ease-in-out; }
        .fancybox { display: block; overflow: hidden; background: #eee; height: 120px; }
        .file-item img { height: 110px; }
        .file-item .progress { position: absolute; right: 4px; bottom: 4px; left: 4px; height: 4px; overflow: hidden; z-index: 15; margin: 0; padding: 0; border-radius: 0; background: 0 0; }
        .file-item .progress span { display: block; overflow: hidden; width: 0; height: 100%; background: url(/images/progress.png) repeat-x #06BD01; -webit-transition: width .2s linear; -moz-transition: width .2s linear; -o-transition: width .2s linear; -ms-transition: width .2s linear; transition: width .2s linear; -webkit-animation: progressmove 2s linear infinite; -moz-animation: progressmove 2s linear infinite; -o-animation: progressmove 2s linear infinite; -ms-animation: progressmove 2s linear infinite; animation: progressmove 2s linear infinite; -webkit-transform: translateZ(0); }
    </style>

<form id="form1" runat="server">
        <div>
            <div class="trip-uploader" style="height: 160px;">
                <div class="uploader-images-list">
                </div>
                <div class="webuploader-container">
                    <div id="coverPicker" class="webuploader-pick webuploader-pick-hover" style="position: relative;">
                        <i class="icon icon-plus"></i>上传图片<br />
                        (最多N张)
                    </div>
                    <div id="imgupload" class="upload-btn"></div>
                </div>
            </div>
        </div> 
    </form>
 <script>
            var $list = $(".uploader-images-list");
            var uploader = new plupload.Uploader({ //实例化一个plupload上 传对象
                browse_button: 'imgupload',
                runtimes: 'html5,flash,silverlight,html4',
                url: '/Core/UploadHandler.ashx',
                flash_swf_url: '/js/plupload/Moxie.swf',
                silverlight_xap_url: '/js/plupload/Moxie.xap',
                filters: {
                    mime_types: [ //只允许上传图片文件
                      { title: "图片文件", extensions: "jpg,gif,png" }
                    ]
                }
                , prevent_duplicates: !1
                , max_file_size: '10mb'
                , chunk_size: '1mb'//分片上传一定要注意压缩的大小
                //, resize: { width: 320, height: 240, quality: 90 }
                , init:
                {
                    PostInit: function (a) {
                        console.log("初始化完毕");
                    },
                    FilesAdded: function (uder, files) {
                        console.log("添加进队列");
                        for (var i = 0; i < files.length; i++) {
                            var file = files[i];
                            appendimg(file.id);
                        }
                        uder.start();
                    },
                    BeforeUpload: function (uder, files) {
                        console.log("开始上传");
                    },
                    UploadProgress: function (uder, file) {
                        console.log("进度:[百分比:" + file.percent + ",状态:" + file.status + ",原始大小:" + file.origSize + ",已传:" + file.loaded + "]");
                        progress(file.id, file.percent);
                    },
                    UploadFile: function (uder) {
                        console.log(uder.id + "开始上传");
                    },
                    FileUploaded: function (uder, file, resObject) {
                        var result = resObject.response;
                        console.log("上传完成" + result);
                        var $fileitem = $("." + file.id)
                        $fileitem.find("img").attr("src", JSON.parse(result).data);
                        //移除进度条
                        $fileitem.find(".progress").remove();
                    },
                    ChunkUploaded: function (a, b, c) {
                        console.log("小片上传完成后");
                    },
                    UploadComplete: function (uder, files) {
                        alert("上传完毕");
                    },
                    Error: function () {
                        alert("ERROR");
                    }
                }

            });
            uploader.init(); //初始化

            function appendimg(id, imgurl) {
                var html = ' <div  class="' + id + ' file-item"><a class="fancybox"> <img /> </a> </div>';
                $(".uploader-images-list").append(html);
            }
            function progress(id, percent) {
                var c = $list.find("." + id);
                var d = c.find(".progress span");
                d.length || (d = $('<p class="progress"><span></span></p>').appendTo(c).find("span"));
                d.css("width",   percent + "%")
            }
            
        </script>

下面的是后台代码:

   /// <summary>
    /// BaseHandler 的摘要说明
    /// </summary>
    public class BaseHandler : IHttpHandler, IRequiresSessionState
    {
        public HttpRequest Request
        {
            get
            {
                return HttpContext.Current.Request;
            }
        }
        public HttpResponse Response
        {
            get
            {
                return HttpContext.Current.Response;
            }
        }
        public void ProcessRequest(HttpContext context)
        {
            var data = ProcessResponse(context);
            var newData = new { code = data.code, data = data.data, msg = data.msg };
            context.Response.ContentType = "application/json";
            string jsonData = JsonConvert.SerializeObject(newData);
            context.Response.Write(jsonData);
        }
        /// <summary>
        /// 定义输出函数
        /// </summary>
        /// <returns></returns>
        protected virtual ResponseData ProcessResponse(HttpContext context)
        {
            ResponseData data = new ResponseData { code = ReturnCode.error, data = "" };
            return data;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    /// <summary>
    ///  返回值
    /// </summary>
    public struct ResponseData
    {
        /// <summary>
        /// 返回的状态码
        /// </summary>
        public ReturnCode code;
        /// <summary>
        /// 返回状态码对应的消息
        /// </summary>
        public string msg;
        /// <summary>
        /// 附加内容
        /// </summary>
        public object data;
    }
    /// <summary>
    /// 操作代码 返回给前台JS
    /// </summary>
    public enum ReturnCode
    {
        /// <summary>
        /// 失败 0
        /// </summary>
        error = 0,
        /// <summary>
        /// 成功 1
        /// </summary>
        success = 1,
        /// <summary>
        /// 其他 ,自定义状态 返回9
        /// </summary>
        other = 9
    }
 public class UploadHandler : BaseHandler
    {
        ResponseData responseData = new ResponseData()
        {
            code = ReturnCode.error,
            msg = "未配置",
            data = null
        };
        protected override ResponseData ProcessResponse(HttpContext context)
        {
            Response.CacheControl = "no-cache";
            string dir = GetUploadPath();
            if (Request.Files.Count > 0)
            {
                try
                {
                    for (int j = 0; j < Request.Files.Count; j++)
                    {
                        int offset = Convert.ToInt32(Request["chunk"]); //当前分块
                        int total = Convert.ToInt32(Request["chunks"]);//总的分块数量
                        string name = Request["name"];
                        HttpPostedFile uploadFile = Request.Files[j];
                        if (total == 1)
                        {
                            if (uploadFile.ContentLength > 0)
                            {
                                string extname = Path.GetExtension(uploadFile.FileName);//.jpg
                                string filename = uploadFile.FileName; //xx.jpg
                                string path = dir + RndNum(6) + extname;
                                uploadFile.SaveAs(context.Server.MapPath(path));
                                responseData.msg = "上传成功";
                                responseData.data = path;
                            }
                        }
                        else
                        {
                            //文件 分成多块上传
                            string tempPath = WriteTempFile(uploadFile, offset);
                            if (total - offset == 1)
                            {
                                //如果是最后一个分块文件 ,则把文件从临时文件夹中移到上传文件夹中

                                string extname = Path.GetExtension(name);//.jpg
                                string newPath = dir + RndNum(6) + extname;
                                System.IO.FileInfo fi = new System.IO.FileInfo(context.Server.MapPath(tempPath));//临时文件名 
                                //把临时文件移动到新目录并重名
                                fi.MoveTo(context.Server.MapPath(newPath));
                                responseData.msg = "上传成功";
                                responseData.data = newPath;
                            }
                            else
                            {
                                responseData.msg = "上传成功";
                                responseData.data = tempPath;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    responseData.msg = ex.Message;
                    responseData.data = ex.ToString();
                }

            }
            return responseData;
        }

        /// <summary>
        /// 保存临时文件-返回相对路径
        /// </summary>
        /// <param name="uploadFile">文件流</param>
        /// <param name="chunk">第几个分块 从0开始</param>
        /// <param name="context"></param>
        /// <returns></returns>
        private string WriteTempFile(HttpPostedFile uploadFile, int chunk)
        {
            string tempPath = GetTempPath() + uploadFile.FileName + ".part"; //临时相对路径
            string saveTempPath = HttpContext.Current.Server.MapPath(tempPath);
            if (chunk == 0)
            {
                uploadFile.SaveAs(saveTempPath); //如果是第一个分块,则直接保存
            }
            else
            {
                //如果是其他分块文件 ,则原来的分块文件,读取流,然后文件最后写入相应的字节
                FileStream fs = new FileStream(saveTempPath, FileMode.Append);
                if (uploadFile.ContentLength > 0)
                {
                    int FileLen = uploadFile.ContentLength;
                    byte[] input = new byte[FileLen];
                    System.IO.Stream MyStream = uploadFile.InputStream;
                    MyStream.Read(input, 0, FileLen);
                    fs.Write(input, 0, FileLen);
                    fs.Close();
                }
            }

            return tempPath;
        }

        /// <summary>
        /// 该方法用于生成指定位数的随机数
        /// </summary>
        /// <param name="VcodeNum">参数是随机数的位数</param>
        /// <returns>返回一个随机数字符串</returns>
        public string RndNum(int VcodeNum)
        {
            string Vchar = "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            //string Vchar = "0,1,2,3,4,5,6,7,8,9";
            string[] VcArray = Vchar.Split(',');//拆分成数组

            string VNum = "";
            seed++;
            Random rand = new Random(seed);
            for (int i = 0; i < VcodeNum; i++)
            {
                VNum += VcArray[rand.Next(VcArray.Length - 1)];
            }
            return VNum;
        }
        private static int _seed = int.Parse(DateTime.Now.Ticks.ToString().Substring(10));
        private static int seed { get { return _seed; } set { _seed = value; } }

        //获取存放路径
        public static string GetUploadPath()
        {
            string path = HttpContext.Current.Server.MapPath("/upload/");
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            return "/upload/";
        }
        /// <summary>
        /// 获取临时目录 相对路径
        /// </summary>
        /// <returns></returns>
        public static string GetTempPath()
        {
            string path = GetUploadPath();
            path = HttpContext.Current.Server.MapPath("/upload/temp/");
            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            return "/upload/temp/";
        }
    }

源代码:

demoPlupload

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出

昨天文章太过仓促没有补充导出的示例源码,在者当时弄到到很晚没时间做出导出功能,对阅读理解造成影响,现补充一份示例源码,顺便补充导出的功能说明,望理解 示例代...

54570
来自专栏大内老A

我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案

几个星期之前写了一篇关于如何通过WCF进行 双向通信的文章([原创]我的WCF之旅(3):在WCF中实现双向通信(Bi-directional Communic...

18660
来自专栏技术小讲堂

探寻ASP.NET MVC鲜为人知的奥秘(3):寻找多语言的最佳实践方式

如果你的网站需要被世界各地的人访问,访问者会使用各种不同的语言和文字书写习惯,那么创建一个支持多语言的网站就是十分必要的了,这一篇文章就讲述怎么快速合理的创建网...

28980
来自专栏ASP.NET MVC5 后台权限管理系统

已经重写,源码和文章请跳转http://www.cnblogs.com/ymnets/p/5621706.html

文章由于写得比较仓促 已经重写,源码和文章请跳转 http://www.cnblogs.com/ymnets/p/5621706.html  前言: 导入导出实...

32280
来自专栏程序员的SOD蜜

一行代码调用实现带字段选取+条件判断+排序+分页功能的增强ORM框架

问题:3行代码 PDF.NET 是一个开源的数据开发框架,它的特点是简单、轻量、快速,易上手,而且是一个注释完善的国产开发框架,受到不少朋友的欢迎,也在我们公...

32090
来自专栏GuZhenYin

使用localResizeIMG3+WebAPI实现手机端图片上传

前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代...

23480
来自专栏.net core新时代

npoi批量导入实现及相关技巧

  批量导入功能对于大部分后台系统来说都是不可或缺的一部分,常见的场景-基础数据的录入(部门,用户),用批量导入方便快捷。最近项目需要用到批量导入,决定花点时间...

50750
来自专栏linjinhe的专栏

LevelDB:使用介绍

Get 接口和 Put 接口比较像,除了 leveldb::ReadOptions 参数是用来控制读操作的,具体见链接指向的代码。

79350
来自专栏菩提树下的杨过

FluorineFx:基于RSO(远程共享对象)的文本聊天室

在前一篇“FluorineFx:远程共享对象(Remote SharedObjects)”里,已经大致知道了在FluorineFX中如何使用RSO,这一篇将利用...

28180
来自专栏技术之路

Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想...

25470

扫码关注云+社区

领取腾讯云代金券