应无所住,而生其心
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

ASP.NET MVC + WebUploader+BootStrap实现文件上传进度条显示

8982人阅读 2019/9/21 14:41 总访问:4811985 评论:0 收藏:0 手机
分类: .NET MVC


引入需要的资源文件:

<script src="~/Content/jquery-1.9.1.min.js"></script>
<link href="~/Content/webuploader/webuploader.css" rel="stylesheet" />
<script src="~/Content/webuploader/webuploader.min.js"></script>

html:

<div id="uploader" class="wu-example">
    <!--用来存放文件信息-->
    <ul id="thelist" class="list-group"></ul>
    <div class="uploader-list"></div>
    <div class="btns">
        <div id="picker" style="float: left;">选择文件</div>
        <input id="ctlBtn" type="button" value="开始上传" class="btn btn-default" style="width: 78px; height: 37px; margin-left: 10px;" />
    </div>
</div>

<!-- 自己简单弄一个进度条-->
<div id="progressdiv" style="width: 500px; background: #f5f5f5; height: 34px; margin-top: 50px;">
    <div class="progress-bar" style="height: 34px; background: #53CED9; width: 0px">
    </div>
</div>

js:

<script>

    var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";
    var GUID = WebUploader.Base.guid();//一个GUID
    $(function () {
        var $ = jQuery;
        var $list = $('#thelist');
        var uploader = WebUploader.create({
            // 选完文件后,是否自动上传。
            auto: false,
            // swf文件路径
            swf: applicationPath + '../Content/webuploader/Uploader.swf',

            // 文件接收服务端。
            //server: applicationPath + '/home/Upload',
            server: '/home/Upload',
            // 选择文件的按钮。可选。
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#picker',

            // 只允许选择office文件。
            accept: {
                title: 'Office',
                extensions: "pdf,doc,ppt,pptx,xls,xlsx,docx,rar,zip,7z,tar.gz,war,jar,txt,chm,pdr,azw,prc,mbp,tan,tpz,epub,mobi,rp",
                mimeTypes: ".pdf,.doc,.ppt,.pptx,.xls,.xlsx,.docx,.rar,.zip,.7z,.tar.gz,.war,.jar,.txt,.chm,.pdr,.azw,.prc,.mbp,.tan,.tpz,.epub,.mobi,.rp"
            },
            // 只允许选择视频文件。
            //accept: {
            // title: 'Video', 文字描述
            // extensions: 'mp4,ogv,webm', 允许的文件后缀,不带点,多个用逗号分割。
            // mimeTypes: 'video/*', 多个用逗号分割。
            // },

            fileNumLimit: 10,                              //最大上传数量为10
            fileSingleSizeLimit: 50 * 1024 * 1024,         //限制上传单个文件大小20M  (上传文件过大居然没有提示,我说什么效果都没有)
            fileSizeLimit: 200 * 1024 * 1024,              //限制上传所有文件大小200M
            //上传文件数量限制
            fileNumLimit: 1,

            // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
            resize: false
        });
        // 当有文件被添加进队列的时候
        uploader.on('fileQueued', function (file) {

            $list.append('<div id="' + file.id + '" class="item">' +
                '<h4 class="info">' + file.name + '</h4>' +
                '<p class="state">等待上传...</p>' +
                '</div>');

            var name = file.name;	//文件名
            var type = fileType(file.name);	//文件类型,获取的是文件的后缀
            var volume = bytesToSize(file.size);	//文件大小格式化
            var oTr = $("<tr></tr>");
            var str = '<td><cite title="' + name + '">' + name + '</cite></td>';
            str += '<td>' + type + '</td>';
            str += '<td>' + volume + '</td>';
            str += '<td id="jintutiao">';
            str += '<span id="baifenbi"></span>0%';
            str += '</td>';
            str += '<td id="uploding">等待上传</td>';
            $(".fileList").html(str)
        });
        var aa = 1;
        // 文件上传过程中创建进度条实时显示。
        uploader.on('uploadProgress', function (file, percentage) {
            console.log("上传中");
            //计算进度条应该显示的宽度(进度条div的宽度*百分比即可)
            var precentWidth = parseInt($("#progressdiv").width()) * percentage;
            console.log(percentage);
            console.log("计算出来的宽度:" + precentWidth);
            $(".progress-bar").width(precentWidth)
            // $percent.css('width', percentage * 100 + '%');
            // console.log(percentage * 100 + '%');

            if (percentage == 1) {
                aa++;
            }
            if (aa <= 2) {
                var shuzi = percentage * 100;
                $("#baifenbi").html(shuzi.toFixed(2));
            }

        });

        // 文件上传成功,给item添加成功class, 用样式标记上传成功。
        uploader.on('uploadSuccess', function (file, response) {
            console.log("已上传");
            $('#' + file.id).find('p.state').text('已上传');
            //上传成功后,到Merge控制器
            $.post('/#/Merge', { guid: GUID, fileName: file.name }, function (data) {
                $("#uploader .state").html("上传成功...");
                $("#uploding").html("上传成功");
            });
        });

        /**
         * 验证文件格式以及文件大小
         */
        uploader.on("error", function (type) {
            if (type == "Q_TYPE_DENIED") {
                alert("请上传JPG、PNG、GIF、BMP格式文件");
            } else if (type == "Q_EXCEED_SIZE_LIMIT") {
                alert("文件大小不能超过50M");
            } else {
                alert("上传出错!请检查后重新上传!错误代码" + type);
            }
        });

        // 完成上传完了,成功或者失败,先删除进度条。
        uploader.on('uploadComplete', function (file) {
            console.log("uploadComplete");
            $('#' + file.id).find('.progress').fadeOut();
        });

        //所有文件上传完毕
        uploader.on("uploadFinished", function () {
            //提交表单
            console.log("提交表单");
        });
        //开始上传
        $("#ctlBtn").click(function () {
            uploader.upload();

        });

    });
    //字节大小转换,参数为b
    function bytesToSize(bytes) {
        var sizes = ['Bytes', 'KB', 'MB', 'G'];
        if (bytes == 0) return 'n/a';
        var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
        return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
    };

    //通过文件名,返回文件的后缀名
    function fileType(name) {
        var nameArr = name.split(".");
        return nameArr[nameArr.length - 1].toLowerCase();
    }

</script>

后台:

public ActionResult Upload()
{
    string fileName = Request["name"];
    //string fileRelName = fileName.Substring(0, fileName.LastIndexOf('.'));//设置临时存放文件夹名称
    //int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
    //var guid = Request["guid"];//前端传来的GUID号
    var data = Request.Files["file"];//表单中取得分块文件
    string extension = data.FileName.Substring(data.FileName.LastIndexOf(".") + 1,
        (data.FileName.Length - data.FileName.LastIndexOf(".") - 1));//获取文件扩展名
    if (data != null)//为null可能是暂停的那一瞬间
    {
        data.SaveAs(Server.MapPath("~/Upload") + "/" + fileName);
    }
    return Json(new { erron = 0 });//Demo,随便返回了个值,请勿参考
}

这里要注意asp.net  mvc中上传文件大小的限制,如果超过了就会报错,我们可以在web.config中配置

1:system.webServer中加入或修改配置

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="2147483647" ></requestLimits>
  </requestFiltering>
</security>

2:system.web中加入或修改配置

<!--最大请求长度,单位为kb-->
<httpRuntime targetFramework="4.5" maxRequestLength="100000"  />

来看一个简单的效果:


上传文件的时候传递其他参数的问题,我们一般不是仅仅就只传递一个问题

  • 方法1:在添加文件的时候就直接先传递了,然后在传递其他参数(表单提交或者ajax看你喽)

    监听事件:当有文件被添加进队列的时候,直接提交文件上传

   // 当有文件被添加进队列的时候
   uploader.on('fileQueued', function (file) {
      //选择文件的时候直接上传
      uploader.upload();
   });
  • 方法2:监听文件发送之前的事件 , 文件和参数一起传递

    //监听文件发送之前的事件
    uploader.on('uploadBeforeSend', function (block, data) {
        // file为分块对应的file对象。
        var file = block.file;
        // 修改data可以控制发送哪些携带数据。
        data.username = "xj";
        data.number = "a";
    });

        这里参数的传递可以直接表单序列化成功json字符串来传递还方便快捷一点,不用一个一个的取出来赋值


  • 方法3:监听上传完成事件uploadFinished,文件传递成功后在提交其他参数

    //所有文件上传完毕
    uploader.on("uploadFinished", function () {
        //提交表单
        console.log("提交表单");
    });

万事开头难,demo就是这样了,大家实际用的时候可以随意的自由发挥



webuploader 接收后台返回值

我们不仅仅是需要前台验证后台也需要验证,所以真正的成功与否应该还需要根据后台的信息来进行验证

接收后台验证其实就是监听:uploadSuccess事件即可

uploader.on('uploadSuccess', function (file, response) {
        //其他操作
    //console.log(response);
    if (response.Code == 500) {
       alert(response.Message);
    }
});

其中的response就是后台的返回值,一般都是json所以可以直接点出来判断

tip:uploadSuccess事件比uploadComplete早一点


下面说一下博客项目中资源上传界面的处理

博客项目后台目前使用的是bootstrap,实际项目中运行肯定界面这些要做好看一点嘛

先看看效果图

上传文件的界面如下:

上传中的时候就显示出来进度条:

其实就是上传前显示点击上传文件,点击提交后就显示进度条而已。

就是一个小技巧在进度条div里边在加一个div来显示文字,上传前就显示出来,上传中就隐藏掉只显示进度条了

<div class="progress progress-striped" style="height: 34px; margin-bottom: 5px; text-align: center">
    <!-- 放个span来显示文字-->
    <span style="display: inline-block;cursor:pointer; margin-top: 7px; display:block;"><i class="fa fa-folder"></i>请选择文件</span>
    <!-- 实际进度条-->
    <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
    </div>
</div>

当然也可以不隐藏,上传中就显示文件的名字也是可以的,这样的话就会写一点样式来让里边的文字悬浮不影响进度条的显示


bootstrap进度条显示百分比

把span里边的样式删除掉即可

去掉这个sr-only样式后就可以显示了



demo下载地址:https://download.tnblog.net/resource/index/42AE33C8112246B79F4444B5596E94DA
.net core版本下载地址:https://download.tnblog.net/resource/index/d46969b5a1c840878c06485bff8173b0



欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739

评价