C#网站开发----在服务器上生成临时文件,下载到客户端,然后删除临时文件

来源:互联网 发布:js对象数组删除元素 编辑:程序博客网 时间:2024/06/06 10:14

//点击按钮,完成在服务器上生成文件,并下载到客户端的任务.

  protected void btnOutput_Click(object sender, EventArgs e)
    {
        try
        {
            fillGridView_emp(this.grd_employee, this.grd_emp_temp);

            string strYear = this.lstYear.Text;
            string strSeason = this.lstPeriod.Text;

            foreach (GridViewRow grdRow in this.grd_employee.Rows)
            {


                //本想做成一次下载多个选中的对象,但是后来却发现做不了,于是就改成了CheckBox只能选中一个.这样就不会出问题了.    

                if(((CheckBox)(grdRow.Cells[4]).FindControl("ckb_Output")).Checked == true)
                {
                    string strLocalEmpNo = ((LinkButton)(grdRow.Cells[1].Controls[0])).Text.ToString();
                    string strLocalEmpName =  (grdRow.Cells[2]).Text.ToString();

                    //write to excel
                    if (false == writeToExcel(strYear, strSeason, strLocalEmpNo, strLocalEmpName))
                    {
                        //error message
                    }
                    else
                    {
                        //System.GC.Collect();放在这个地方,服务器上的EXCEL进程杀不了,

                   //若放在下面(蓝色部分)则可以,具体原因不明,有待研究.
                        string strFileName = Session["fullName"].ToString();
                        FileDownload(strFileName);
                    }
                    break;
                }
            }

        }
        catch (System.Exception ex)
        {
            ExceptionHandler.HandleException(ex);
        }
        finally
        {
            System.GC.Collect();
        }

    }



    /// <summary>
    /// 在服务器上生成一个包含所需内容的临时文件
    /// </summary>
    /// <param name="strYear"></param>
    /// <param name="strSeason"></param>
    /// <param name="strEmpNo"></param>
    /// <param name="strEmpName"></param>
    /// <returns></returns>
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern int GetWindowThreadProcessId(IntPtr hwnd,out int ID);
    public Boolean writeToExcel(string strYear, string strSeason, string strEmpNo,  string strEmpName)
    {
        //定义一个Excel程序对象          
        Excel.ApplicationClass excelApp = new Excel.ApplicationClass();
        //Excel.Workbook excelWorkBook = new Excel.Workbook();
        Excel.Worksheet excelWorkSheet = new Excel.Worksheet();

        try
        {
            //定义一个缺少的object对象
            object oMis = System.Reflection.Missing.Value;

            //由Execl程序创建一个工作薄对象,打开服务器上的一个模板文件.
            Excel.Workbook excelWorkBook = excelApp.Workbooks.Open(Server.MapPath("/EvaluationWeb/Temp/EvaluationFormat.xls"),
                oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis);

            //由工作薄对象创建一个工作表
            excelWorkSheet = (Excel.Worksheet)excelWorkBook.Worksheets[1];

            //设置工作的表的名字          
            excelWorkSheet.Name = strEmpName;

            //姓名
            ((Excel.Range)excelWorkSheet.Cells[1, 1]).set_Item(3, 4, strEmpName);
            //员工号
            ((Excel.Range)excelWorkSheet.Cells[1, 1]).set_Item(3, 14, strEmpNo);



            //要往文件里写的其他内容

//***********************Some other code*******************************     

            string strTempFileName = Session.SessionID + System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fffff") + ".xls";//防止临时文件重名,
            string address = @"/EvaluationWeb/Temp/" + strTempFileName;
           
            Session["year"] = strYear;
            Session["season"] = strSeason;
            Session["empName"] = strEmpName;
            Session["empNo"] = strEmpNo;
            Session["fullName"] = Server.MapPath(address).ToString();
           
            excelWorkSheet.SaveAs(Server.MapPath(address),
                oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis, oMis);

            if (excelWorkSheet != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkSheet);
            }

            if (excelWorkBook != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkBook);
            }
//
//             IntPtr t = new IntPtr(excelApp.Hwnd);
//             int k = 0;
//             GetWindowThreadProcessId(t, out k);
//             System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
//             p.Kill();


            if (excelApp != null)
            {
                excelApp.Workbooks.Close();
                excelApp.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
            }

            excelWorkSheet = null;
            excelWorkBook = null;
            excelApp = null;
//
//             System.GC.Collect();
//             System.GC.WaitForPendingFinalizers();
        }
        catch (Exception ex)
        {
            ExceptionHandler.HandleException(ex);

            //close excel file
            if (excelWorkSheet != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelWorkSheet);
            }

            if (excelApp != null)
            {
                excelApp.Workbooks.Close();
                excelApp.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
            }

            return false;
        }

        return true;
    }



//从服务器上下载所生成的临时文件,在网上找了N种方法,始终不能正确下载,没有被注释掉是能正确执行的.
// <param name="FullFileName">临时文件在服务器上的全路径</param>
    protected void FileDownload(string FullFileName)
    {
        //method 1
        //Response.Clear();
        //Response.Charset = "";
        //Response.ContentType = "Application/vnd.ms-excel";
        //Response.AppendHeader("content-disposition", "attachment; filename= Report.xls");

        //Byte[] exl = readFile(FullFileName);

        //Response.OutputStream.Write(exl, 0, exl.Length);
        //Response.OutputStream.Flush();
        //Response.End();


        //method 2
        //FileInfo DownloadFile = new FileInfo(FullFileName);
        //Response.Clear();
        //Response.ClearHeaders();
        //Response.Buffer = false;
        //Response.ContentType = "application/vnd.ms-excel";
        //Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(DownloadFile.FullName, System.Text.Encoding.UTF8));
        //Response.AppendHeader("Content-Length", DownloadFile.Length.ToString());
        //Response.WriteFile(DownloadFile.FullName);
        //Response.Flush();
        //Response.End();



        //method 3
        //string pathfile = FullFileName;  //pathfile 是要下载的文件名称
        //FileInfo file = new FileInfo(pathfile);
        //Response.Clear();
        //Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(file.Name));
        //Response.AddHeader("Content-Length", file.Length.ToString());
        //Response.ContentType = "application/vnd.ms-excel";
        //Response.WriteFile(file.FullName);
        //Response.End();

        //method 4
        //string fileName = Session["year"].ToString() + Session["season"].ToString() +
        //    Session["empName"].ToString() + Session["empNo"].ToString() + ".xls";
        //string filePath = FullFileName;//路径
        //Response.ContentType = "Application/vnd.ms-excel";
        //Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
        //Response.TransmitFile(FullFileName);


        //method 5
        //string fileName = Session["year"].ToString() + Session["season"].ToString() +
        //    Session["empName"].ToString() + Session["empNo"].ToString() + ".xls";

        string fileName = String.Format(Evaluation.Fw.Constants.BusinessConstants.formatFileName,
            Session["year"].ToString(), Session["season"].ToString(),
            Session["empName"].ToString(), Session["empNo"].ToString());
        string filePath = FullFileName;//路径

        System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

        if (fileInfo.Exists == true)
        {
            const long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力
            byte[] buffer = new byte[ChunkSize];

            Response.Clear();
            System.IO.FileStream iStream = System.IO.File.OpenRead(filePath);
            long dataLengthToRead = iStream.Length;//获取下载的文件总大小
            Response.ContentType = "application/octet-stream";
            Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName));
            while (dataLengthToRead > 0 && Response.IsClientConnected)
            {
                int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小
                Response.OutputStream.Write(buffer, 0, lengthRead);
                Response.Flush();
                dataLengthToRead = dataLengthToRead - lengthRead;
            }
            Response.Close();
        }
    }

 

/******************************************************************

//最后,在Global.asax中的Session_End中删除生成的临时文件

在Session结束时,会执行该函数,从而删除生成的临时文件.

本来的想法是在执行完FileDownload(string FullFileName)函数后,手动删除的,却发现没有自己想的那么简单,只好用这种方法处理了.还好生成的临时文件是以SessionID加上生成的临时文件的时间(精确到毫秒的1/10000,肯定不会重名了.

/******************************************************************

void Session_End(object sender, EventArgs e)
    {
        string strPattern = Session.SessionID + "*";
        string strFullName = Session["fullName"].ToString();

        string strPath = strFullName.Substring(0, strFullName.LastIndexOf('//'));
        try
        {
            string[] strFileNameAry = System.IO.Directory.GetFiles(strPath, strPattern);
           
            foreach (string strFileName in strFileNameAry)
            {
                if (strFileName != null && strFileName.Length > 0)
                {
                    try
                    {
                        System.IO.File.Delete(strFileName);
                    }
                    catch (Exception ex)
                    {
                       //some code
                    }

                }
            }
        }
        catch (Exception ex)
        {
             //some code    
        }

    }

 

以前从来没有接触过B/S的程序,就是连这方面的知识,也仅仅只是听过而矣,没有任何的知识储备,所以对B/S完全是一知半解.

做完这个下载功能,我明白了原来用户LOGOFF后,他的Session还是存在的,还在服务器上运行(晕,这不是最基础的知识吗?)这个Session会在Session的TimeOut规定的时间之后,才会被杀死.(呵呵,那天跟组长说起这事,被组长一顿BS,^_^)

 

原创粉丝点击