• 多附件上传控件


    以前写过一篇《单页面多类型的多附件上传》的文章,但是在实际项目中,这样的并不多见,相比之下,多附件上传却经常用到。

    而每次使用都要复制粘贴相关的代码,虽然不麻烦,但用起来却不太方便,一旦忘记某段代码没复制过来,页面就会报错。

    于是,就想把现在用的这些代码,变成一个用户自定义控件,这样再次使用的时候就方便多了。

    话不多说,先看下界面吧。

    设计时

    运行后

    先介绍下控件界面,上下一共有两个repeater,分别用于编辑和查看时使用。上面的repeater,带有删除按钮,用于编辑时可以删除不需要的附件;下面的repeater,用于查看时使用,如果没有上传附件,则后台代码会给控件Literal赋值空格符( ),用于解决浏览器兼容问题(因为有些浏览器在表格行没有数据时,边框线不显示)。

    中间的上传控件,不用多说,用于上传附件;后面的“添加”按钮,点击后,会调用JS代码动态创建上传控件,以便能够上传多个附件;下面的隐藏控件,前期用于记录创建的上传控件个数,点击“提交”按钮后用于保存上传的附件路径,以便数据保存失败时删除附件。

    下面我们来看下前台的html代码。

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AttaUpload.ascx.cs"
        Inherits="WEB.webcontrols.AttaUpload" %>
    <script src="../js/AttaUpload.js" type="text/javascript"></script>
    <div id="tabEdit" runat="server">
        <asp:Repeater ID="rpFileE" runat="server" OnItemCommand="rpFile_ItemCommand">
            <ItemTemplate>
                <div>
                    <asp:LinkButton ID="lbn_load" CommandArgument='<%#Eval("ID") %>' CommandName="load"
                        runat="server" Style="line-height: 25px"><%# Eval("FileName").ToString() + Eval("FileType").ToString()%></asp:LinkButton>&emsp;&emsp;&emsp;
                    <asp:LinkButton ID="lbtn_del" Style="color: Blue" CommandArgument='<%#Eval("ID") %>'
                        CommandName="del" runat="server" OnClientClick='<%#"return DelMsg(""+Eval("FileName").ToString() + Eval("FileType").ToString()+"")" %>'>删除</asp:LinkButton>
                </div>
            </ItemTemplate>
        </asp:Repeater>
        <div id="atta" runat="server">
            <asp:FileUpload ID="fufile" runat="server" onchange="if(this.value)JudgeFile(this.value,this);" />
            <asp:ImageButton ID="imgbtn_add" runat="server" src="../images/add.gif" Style="margin-bottom: -2px;" />
        </div>
        <asp:HiddenField ID="hffile" runat="server" Value="1" />
    </div>
    <div id="tabView" runat="server" visible="false">
        <asp:Repeater ID="rpFileV" runat="server" OnItemCommand="rpFile_ItemCommand">
            <ItemTemplate>
                <div>
                    <asp:LinkButton ID="lbn_load" CommandArgument='<%#Eval("ID") %>' CommandName="load"
                        runat="server" Style="line-height: 25px"><%# Eval("FileName").ToString() + Eval("FileType").ToString()%></asp:LinkButton>
                </div>
            </ItemTemplate>
        </asp:Repeater>
        <asp:Literal ID="ltlfile" runat="server"></asp:Literal>
    </div>
    View Code

    其中引用的AttaUpload.js文件,就是该控件用到的所有JS代码所在,里面包含有动态创建上传控件,删除附件提示,删除动态创建的上传控件,判断附件类型等等相关功能的JS编码。

    /**********动态添加上传附件**********/
    function AddAtta(id, hfid) {
        //var hfid = jQuery("#" + id).next().attr('id'); //document.getElementById(id).nextSibling.id;(IE10不兼容)
        var d = document.createElement("div");
        var f = document.createElement("input");
        f.setAttribute("type", "file");
        f.setAttribute("name", "upfile");
        f.setAttribute("style", "margin-top:5px;");
        f.onchange = function () {
            if (this.value) JudgeFile(this.value, this);
        }
        d.appendChild(f);
    
        //添加删除按钮
        var im = document.createElement("img");
        im.setAttribute("src", "../images/close.gif");
        im.style.cssText = "margin-left:3px;margin-bottom: -2px;cursor:pointer";
        im.onclick = function () {
            document.getElementById(hfid).value = $val(hfid) - 1;
            return DelFile(this, "DIV");
        }
        d.appendChild(im);
        document.getElementById(id).appendChild(d);
    
        //添加计数
        document.getElementById(hfid).value = parseInt($val(hfid)) + 1;
        return false;
    }
    
    /**********删除**********/
    function DelFile(f, name) {
        while (f.tagName != name)
            f = f.parentNode;
        f.parentNode.removeChild(f);
        return false;
    }
    
    /**********判断文件类型和大小**********/
    function JudgeFile(file, node) {
        var typelist = ["txt", "doc", "xls", "ppt", "docx", "xlsx", "pptx", "pdf", "jpeg", "jpg", "png", "bmp", "gif"];
        if (file) {
            var match = 0;
            var suffix = file.split(".");
            var num = suffix.length - 1;
            var name = suffix[num].toLowerCase();
            for (var i = 0; i < typelist.length; i++) {
                if (name == typelist[i]) {
                    match = 1;
                    break;
                }
            }
            if (match != 1) {
                alert("暂不支持上传该类型的文件,请重新选择!");
                node.outerHTML = node.outerHTML;
            }
        }
        getFileSize(node);
    }
    
    //判断文件大小
    function getFileSize(obj) {
        var size = 0;
        if (navigator.userAgent.indexOf("MSIE") > 0) {
            try {
                var fso = new ActiveXObject('Scripting.FileSystemObject'); //获取上传文件的对象
                var file = fso.GetFile(obj.value);
                size = file.Size;
            }
            catch (err) {
                size = 0;
            }
        } else {
            size = obj.files[0].size;
        }
        if ((size / 1048576) > 40) {
            alert("上传文件大于40M,无法上传!");
            obj.outerHTML = obj.outerHTML;
        }
    }
    
    
    /**********删除信息提示框**********/
    function DelMsg(mess) {
        return confirm("系统提示:您确认删除" + mess + "吗?");
    }
    View Code


    现在我们来看下控件的后台编码:

    1、参数:

    /// <summary>
            /// 项目ID
            /// </summary>
            public string ProID
            {
                get
                {
                    if (ViewState["AttaProID"] == null)
                    {
                        return "";
                    }
                    else
                    {
                        return (string)ViewState["AttaProID"];
                    }
                }
                set
                {
                    ViewState["AttaProID"] = value;
                }
            }
    
            /// <summary>
            /// 控件ID
            /// </summary>
            public string WucID
            {
                get
                {
                    if (ViewState["AttaWucID"] == null)
                    {
                        return "AttaUp";
                    }
                    else
                    {
                        return (string)ViewState["AttaWucID"];
                    }
                }
                set
                {
                    ViewState["AttaWucID"] = value;
                }
            }
    
            /// <summary>
            /// 查看或编辑(0:编辑;1:查看)
            /// </summary>
            public string Flag
            {
                get
                {
                    if (ViewState["AttaFlag"] == null)
                    {
                        return "0";
                    }
                    else
                    {
                        return (string)ViewState["AttaFlag"];
                    }
                }
                set
                {
                    ViewState["AttaFlag"] = value;
                }
            }
    View Code

    2、页面加载:

    /// <summary>
    /// 加载
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            imgbtn_add.Attributes.Add("onclick", "return AddAtta('" + WucID   + "_atta','" + WucID + "_hffile')");
            //页面附件绑定
          if (ProID != "")
            {
                //读取现有数据
            InitData();
            }
        }
    }
    View Code

      关于在后台给“添加”按钮绑定JS方法,是为了要把控件的ID传到前台,否则“动态创建上传控件”和“保存累计个数”的方法就不能使用了。

      而如果id="atta"的div不加上runat="server"的话,那任何页面就只能使用一次了。

    3、绑定数据:

            /// <summary>
            /// 读取数据
            /// </summary>
            private void InitData()
            {
                PrjFileEntity model = new PrjFileEntity();
                model.ProID = ProID;
                model.FileFlag = -2;
                DataView dv = PrjFileBLL.GetContact(model).DefaultView;
                if (Flag == "0")
                {
                    // 编辑数据
                    rpFileE.DataSource = dv;
                    rpFileE.DataBind();
                }
                else
                {
                    // 查看数据
                    rpFileV.DataSource = dv;
                    rpFileV.DataBind();
                    tabEdit.Visible = false;
                    tabView.Visible = true;
                    if (dv == null || dv.Count <= 0)
                    {
                        ltlfile.Text = "&nbsp;";
                    }
                }
            }
    View Code

    4、保存附件:

            /// <summary>
            /// 保存附件
            /// </summary>
            /// <param name="proid"></param>
            public PrjFileEntity Save(int start, string path, string ucid)
            {
                int one = Convert.ToInt32(hffile.Value);
                PrjFileEntity filemodel = CommonFunction.FileUpLoad(start, one + start, hffile, path, ucid, (int)CommonEnum.FileFlag.上传);
                if (filemodel.ID == "-2")
                {
                    CommonFunction.delfile(hffile.Value.ToString());
                    hffile.Value = "1";
                    ShowMessages(filemodel.FileName);
                    return null;
                }
                else
                {
                    return filemodel;
                }
            }
    View Code
            /// <summary>
            /// 项目文档上传文件
            /// </summary>
            /// <param name="start">起始值</param>
            /// <param name="end">终止值</param>
            /// <param name="hfcount">隐藏控件</param>
            /// <param name="url">路径(例:project/123)</param>
            /// <param name="ucid">用户控件ID(UserContronlID)</param>
            /// <param name="fileflag">附件标识(CommonEnum.FileFlag)</param>
            /// <returns></returns>
            public static PrjFileEntity FileUpLoad(int start, int end, HiddenField hfcount, string url, string ucid, int fileflag)
            {
                int upsize = 40000000;
                try
                {
                    upsize = Convert.ToInt32(ConfigurationManager.AppSettings["upsize"].ToString());
                }
                catch (Exception)
                {
                    upsize = 40000000;
                }
    
                //清空隐藏控件的值,用于存放路径
                if (hfcount != null)
                {
                    hfcount.Value = "";
                }
    
                //设置上传路径
                string path = System.Web.HttpContext.Current.Server.MapPath("~/UpFile/" + url + "/");
                //判断上传文件夹是否存在,若不存在,则创建
                if (!Directory.Exists(path))
                {
                    //创建文件夹
                    Directory.CreateDirectory(path);
                }
    
                string attaname = "";
                string attaurl = "";
                string attatype = "";
                PrjFileEntity accessinfo = null;
                HttpFileCollection files = HttpContext.Current.Request.Files;
                for (int i = start; i < end; i++)
                {
                    HttpPostedFile postedFile = files[i];
                    if (postedFile.FileName != "")
                    {
                        if (postedFile.ContentLength < upsize)
                        {
                            string[] name = postedFile.FileName.ToString().Split('\');
                            //获取扩展名
                            string extname = System.IO.Path.GetExtension(postedFile.FileName);
                            //获取上传文件的名称
                            string oglname = name[name.Length - 1].ToString().Replace(extname, "");
                            //存储上传的文件名
                            attaname += oglname + ",";
                            attatype += extname + ",";
    
                            //为上传的文件设置新的名称,防止重名
                            string newname = System.DateTime.Now.ToString("yyyyMMddHHmmssffff") + i.ToString();
                            newname = newname + extname;
    
                            //设置完整的文件上传路径
                            string filepath = path + newname;
                            postedFile.SaveAs(filepath);
                            if (hfcount != null)
                            {
                                hfcount.Value += filepath + "$";
                            }
                            int j = filepath.IndexOf("UpFile");
                            string str = filepath.Substring(j - 1);
    
                            attaurl += "~" + str + ",";
    
                        }
                        else
                        {
                            accessinfo = new PrjFileEntity();
                            accessinfo.ID = "-2";
                            accessinfo.FileName = "上传失败,上传文件不能大于" + upsize / 1000000 + "M!";
                            return accessinfo;
                        }
                    }
                }
    
                attatype = attatype.TrimEnd(',');
                attaname = attaname.TrimEnd(',');
                attaurl = attaurl.TrimEnd(',');
                if (attaname != "" && attaurl != "" && attatype != "")
                {
                    accessinfo = new PrjFileEntity(attatype, attaname, attaurl, ucid, fileflag);
                }
                else
                {
                    accessinfo = new PrjFileEntity();
                }
                return accessinfo;
            }
    View Code

    5、删除附件:

            /// <summary>
            /// 删除附件
            /// </summary>
            public void Delete()
            {
                CommonFunction.delfile(hffile.Value.ToString());
                hffile.Value = "1";
            }
    View Code

    6、附件下载及删除:

            /// <summary>
            /// 附件下载及删除
            /// </summary>
            /// <param name="source"></param>
            /// <param name="e"></param>
            protected void rpFile_ItemCommand(object source, RepeaterCommandEventArgs e)
            {
                string id = e.CommandArgument.ToString().Trim();
                PrjFileEntity fileinfo = PrjFileBLL.GetUniqueObj(id);
                string path = fileinfo.FilePath;
    
                if (e.CommandName.ToString() == "del")
                {
                    path = HttpContext.Current.Server.MapPath(path);
                    bool istrue = PrjFileBLL.Delete(id);
                    if (istrue)
                    {
                        //物理路径的文件删除
                        if (System.IO.File.Exists(path))
                        {
                            System.IO.File.Delete(path);
                        }
                        ShowMessages("删除成功");
                        //InitData();
                        //表单附件绑定
                        if (WorkTaskInsID != "")
                        {
                            FormData();
                        }
                        //页面附件绑定
                        else if (ProID != "")
                        {
                            //读取现有数据
                            InitData();
                        }
                    }
                    else
                    {
                        ShowMessages("删除失败");
                    }
                }
                else
                {
                    ShowScript("AttaView("" + id + "",1)");
                }
            }
    View Code

    7、消息提醒:

            /// <summary>
            /// 消息提醒
            /// </summary>
            /// <param name="sMessage"></param>
            private void ShowMessages(string sMessage)
            {
                Page.ClientScript.RegisterStartupScript(this.GetType(), "Message", "<script>alert('系统提示:" + sMessage + "!');</script>");
                return;
            }
            /// <summary>
            /// 运行纯脚本
            /// </summary>
            /// <param name="sMessage"></param>
            public void ShowScript(string script)
            {
                Page.ClientScript.RegisterStartupScript(GetType(), "", script, true);
            }
    View Code

    8、获取隐藏控件的计数:

            /// <summary>
            /// 获取隐藏控件的数值
            /// </summary>
            /// <returns></returns>
            public int GetHiddenCount()
            {
                return Convert.ToInt32(hffile.Value);
            }
    View Code

      此方法在页面调用两个或两个以上此控件的时候使用。

    最后看下调用:

    1、在webconfig中注册:

     <add src="~/webcontrols/AttaUpload.ascx" tagName="AttaUp" tagPrefix="wuc"/>

    2、页面前台调用:

            <tr>
                <th>
                    附件
                </th>
                <td colspan="3">
                    <wuc:AttaUp ID="AttaUp" runat="server" />
                </td>
            </tr>

    3、页面加载时传递参数:

    //附件
    AttaUp.ProID = CID;
    //查看时才传,编辑时不需要
    AttaUp.Flag = "1";

      至于控件的WucID参数,再没有修改控件ID的情况下不需要传递,如果你把控件的ID重命名了,例如改为“FileUpControl”时,则一定要传递,否则会报错!!

    4、提交页面时调用:

     PrjFileEntity filemodel = AttaUp.Save(0, CommonFunction.GetProjectPath(hfproid.Value), "");

      第一参数“0”,表示是从第一个上传控件开始查找附件;如果有两个上传控件,那么第一个控件保存附件时,传“0”;第二个则要用第一控件的GetHiddenCount()方法,获取第一个控件的上传控件个数;如果有第三个控件,那就要“累加”第一个控件和第二个控件的GetHiddenCount()方法的返回值。以此类推!!

      注意:该方法只是返回了附件的实体类,多附件的每个属性值都以逗号(,)隔开,详情请仔细阅读FileUpLoad()方法。

         如果你需要返回List<PrjFileEntity>,那么请自行修改FileUpLoad()方法。

    5、页面数据保存失败时调用:

    AttaUp.Delete();//删除上传的附件

      因为我是通过点击“提交”按钮,来保存表单数据。而保存失败时会刷新页面,导致附件控件被重置,那么在保存数据前被上传的附件,就无法看到。

      所以我需要删除之前上传的附件,让客户重新选择附件上传,虽然这样有点反人类,呵呵。如果你有好的解决办法,还请不吝赐教!

    至此,整个多附件上传控件就介绍完毕了。

  • 相关阅读:
    shell习题第12题:批量创建用户
    shell习题第11题:输入数字执行命令
    二、python数据类型、字符编码、文件处理
    C语言之控制语言:分支和跳转
    c语言之控制语句:循环
    C语言之运算符、表达式和语句
    Python集合及其运算
    Python文本处理
    Python迭代器与格式化
    Python装饰器
  • 原文地址:https://www.cnblogs.com/lxc89/p/5580181.html
Copyright © 2020-2023  润新知