導入EXCEL報錯:"外部表不是預期的格式錯誤"、文件格式和擴展名不匹配,文件可能已損壞或不安全的解決方法

開發環境:C# + EXCEL2003 + VS2008

問題:

當使用如下代碼從gridview導出數據到excel後,無法從excel取出數據,具體如下:

1、原使用的代碼:

        protected void ExcelOut_Click(object sender, EventArgs e)
        {
            Response.Clear(); //清除緩衝區流中的所有內容輸出
            Response.Buffer = true; //
            Response.Charset = "";    //設置輸出流的http字符集
            //保存附件用"attachment;filename=bang.xls";在線打開用"online;filename=bang.xls"
            //可以是.doc、.xls、.txt、.htm、
            Response.AppendHeader("Content-Disposition", "attachment;filename=bang.xls");
            Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//設置輸出流爲簡體中文

            //設置輸出文件類型爲excel文件。保存爲word時,應爲"application/ms-word" 
            //可以爲application/ms-excel、application/ms-word、application/ms-txt、application/ms-html、或其他瀏覽器可直接支持文檔  
            Response.ContentType = "application/vnd.ms-excel";

            this.EnableViewState = false;   //關閉保存視圖狀態 
            System.Globalization.CultureInfo myCItrad = new System.Globalization.CultureInfo("ZH-CN", true);//區域設置
            System.IO.StringWriter oStringWriter = new System.IO.StringWriter(myCItrad);
 
            System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
            DepartList.RenderControl(oHtmlTextWriter); //將DataGrid(dgBang)中的內容輸出到oHtmlTextWriter
            Response.Write(oStringWriter.ToString());
            Response.End();//將當前所有緩衝的輸出發送到客戶端,並停止該頁執行
       }
使用這段代碼確實可以導出數據,並以excel的格式保存在用戶的客戶端電腦裏,但當使用到這些導出的excel文件時就出問題了,下面代碼是使用這些excel文件的:

前臺頁面需要一個控件配合:

<asp:FileUpload ID="ExcelIn" runat="server" Width="250px" CssClass="inputcss" 
                                            Height="16px" ></asp:FileUpload>  <font face="宋體"></font>

        protected void ExcelInButton_Click(object sender, EventArgs e)
        {
            string strFilePath = "";
            string serverPath = "";
            //通過控件來獲取用戶待上傳的excel文件名,這個excel文件其實是上面程序產生的文件
            strFilePath = ExcelIn.PostedFile.FileName;
            // strFilePath = strFilePath.Substring(strFilePath.LastIndexOf("."));
            // 獲取系統時間生成附件名
            //strFilePath = DateTime.Now.ToFileTime().ToString() + strFilePath;
            // 將附件保存到服務器上
            ExcelIn.PostedFile.SaveAs(("D:") + "\\空調標杆附件\\" + strFilePath);
            serverPath = "D:\\空調標杆附件\\" + strFilePath;

            string strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + serverPath + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
            OleDbConnection ExcelConn = new OleDbConnection(strCon);
            try
            {
                string strCom = "SELECT * FROM [Sheet1$]";
                <span style="background-color: rgb(255, 102, 102);">ExcelConn.Open();</span>
                OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, ExcelConn);
                DataSet ds = new DataSet();
                myCommand.Fill(ds, "[Sheet1$]");<pre>                //由於excel列名“當月效益”和gridview中“當月效益”指定的數據源"效益"不一樣,無法匹配數據源,因此要把excel中列名改爲“效益”
                ds.Tables[0].Columns["當月效益"].ColumnName = "效益";
                DepartList.DataSource = ds;
                DepartList.DataBind();
                ExcelConn.Close();
            }
            catch (MembershipCreateUserException ex)
            {
                ExcelConn.Close();
                Response.Write("<script>alert('導入內容:" + ex.Message + "')</script>");
            }
        }

當程序運行到下面程序時,會報錯,錯誤代碼爲:"外部表不是預期的格式錯誤"。

ExcelConn.Open();

分析:

當我們用2003以上版本的excel打開這些excel文件時,會出現:文件格式和擴展名不匹配,文件可能已損壞或不安全。


這說明我們用

 ExcelOut_Click(object sender, EventArgs e)
來生成excel文件的方法不是很好,我在網上查閱了大量資料,按照各種方法也沒有解決這個問題,然後我用另外一種方法從gridview導出數據到excel,結果成功了,不再出現:“文件格式和擴展名不匹配,文件可能已損壞或不安全”這個錯誤。代碼如下:

       /// <summary>
        /// 將數據從gridview導入到本地excel,文件保存在D:\\調試文件\\中,文件名爲當時的時間
        /// </summary>
        /// <param name="FileName"></param>
        private void SaveFile(String FileName)
        {
            try
            {

                string fileNameString = "D:\\調試文件\\" + FileName;

                //驗證strFileName是否爲空或值無效   
                if (fileNameString.Trim() == " ")
                { return; }
                //定義表格內數據的行數和列數   
                int rowscount = DepartList.Rows.Count;
                int colscount = DepartList.Columns.Count;
                //行數必須大於0   
                if (rowscount <= 0)
                {
                    System.Web.HttpContext.Current.Response.Write("沒有數據可供保存");
                    return;
                }

                //列數必須大於0   
                if (colscount <= 0)
                {
                    System.Web.HttpContext.Current.Response.Write("沒有數據可供保存");
                    return;
                }

                //行數不可以大於65536   
                if (rowscount > 65536)
                {
                    System.Web.HttpContext.Current.Response.Write("數據記錄數太多(最多不能超過65536條)");
                    return;
                }

                //列數不可以大於255   
                if (colscount > 255)
                {
                    System.Web.HttpContext.Current.Response.Write("數據記錄行數太多,不能保存");
                    return;
                }



                Microsoft.Office.Interop.Excel.Application objExcel = null;
                Microsoft.Office.Interop.Excel.Workbook objWorkbook = null;
                Microsoft.Office.Interop.Excel.Worksheet objsheet = null;

                try
                {
                    //申明對象   
                    objExcel = new Microsoft.Office.Interop.Excel.Application();
                    objWorkbook = objExcel.Workbooks.Add(true);
                    objsheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.ActiveSheet;
                    //設置EXCEL不可見   
                    objExcel.Visible = false;

                    //設置列寬
                    //objExcel.Range objRng = objsheet.get_Range(objsheet.Cells[1, 1], objsheet.Cells[1, 1]);


                    //向Excel中寫入表格的表頭   
                    int displayColumnsCount = 1;
                    for (int i = 0; i <= DepartList.Columns.Count - 1; i++)
                    {
                        if (DepartList.Columns[i].Visible == true)
                        {
                            objExcel.Cells[1, displayColumnsCount] = DepartList.Columns[i].HeaderText.Trim();
                            displayColumnsCount++;
                        }
                    }
                    //向Excel中逐行逐列寫入表格中的數據   
                    for (int row = 0; row <= DepartList.Rows.Count - 1; row++)
                    {
                        displayColumnsCount = 1;
                        for (int col = 0; col < 2; col++)
                        {
                            if (DepartList.Columns[col].Visible == true)
                            {
                                try
                                {
                                    if (DepartList.Rows[row].Cells[col].Text != null)
                                    {
                                        objExcel.Cells[row + 2, displayColumnsCount] = DepartList.Rows[row].Cells[col].Text.ToString();
                                    }
                                    else
                                    {
                                        objExcel.Cells[row + 2, displayColumnsCount] = "";
                                    }
                                    displayColumnsCount++;
                                }
                                catch (Exception ex)
                                {
                                    System.Web.HttpContext.Current.Response.Write(ex.Message);
                                }

                            }
                        }
                    }

                    //保存文件   
                    objWorkbook.SaveAs(fileNameString, true, null, null, null,
                            null, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, true, true, true,
                            true, true);
                    objExcel.Quit();

                }
                catch (Exception error)
                {
                    System.Web.HttpContext.Current.Response.Write(error.Message);
                    return;
                }
            }
            catch (Exception ex)
            {
                System.Web.HttpContext.Current.Response.Write(ex.Message);
            }
        }
上面的函數只能實現從gridview導出數據到excel,要使得用戶可以下載生成的文件,那得用到另一個函數:

        /// 下載服務器上已有文件
        /// </summary>
        /// <param name="fileName">保存到客戶端時的文件名</param>
        /// <param name="filePath">下載文件在服務器上所在物理路徑全名</param>
        public static void DownloadFile(String fileName, String filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            System.Web.HttpContext.Current.Response.Clear();
            System.Web.HttpContext.Current.Response.ClearContent();
            System.Web.HttpContext.Current.Response.ClearHeaders();
            System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
            System.Web.HttpContext.Current.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
            System.Web.HttpContext.Current.Response.AddHeader("Content-Transfer-Encoding", "binary");
            System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
            System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
            System.Web.HttpContext.Current.Response.WriteFile(fileInfo.FullName);
            System.Web.HttpContext.Current.Response.Flush();
            System.Web.HttpContext.Current.Response.End();
        }

使用方法如下:

       protected void ExcelOut_Click(object sender, EventArgs e)
        {
            string FileName = DateTime.Now.ToFileTime().ToString() + ".xls";
            string FilePath = "D:\\調試文件\\" + FileName;
            SaveFile(FileName);
            DownloadFile(FileName, FilePath);

        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章