1. 程式人生 > >詳講:C#快速匯出多個sheet到excel的兩種方法(Cell和Range方法), 解決了(匯入時外部表不是預期的格式)

詳講:C#快速匯出多個sheet到excel的兩種方法(Cell和Range方法), 解決了(匯入時外部表不是預期的格式)

C# 匯出的表載入時報錯:外部表不是預期的格式。的解決方案

在網絡卡找了一些Excel匯出的方法,大部分能匯出,但時不能將匯出的Excel匯入。總是報:外部表不是預期的格式

找了好久終於找到了解決方案。

這是本人整理修改後的的可以實現匯出匯入的方法。供大家學習參考,方法就是用一個沒問題的Excel模板,在模板的基礎上進行操作。

 

引用空間:using Excel = Microsoft.Office.Interop.Excel;

  //匯出方案
        private void simpleButton5_Click(object sender, EventArgs e)
        {
        

            saveFileDialog1.Filter = "Execl files (*.xls)|*.xls";
            saveFileDialog1.FilterIndex = 0;
            saveFileDialog1.RestoreDirectory = true;
            saveFileDialog1.CreatePrompt = true;
            saveFileDialog1.Title = "匯出檔案儲存路徑";
            saveFileDialog1.FileName = "方案檔案";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                 BLL.T_Project bllProject = new BLL.T_Project();
                 System.Data.DataTable dt1 = bllProject.GetList("1=1 order by Start_State desc ,id desc").Tables[0];
            
                 BLL.T_Plan bll_Plan = new BLL.T_Plan();
                 System.Data.DataTable dt2 =bll_Plan.GetList("plan_type='***'  order by id asc").Tables[0];        
                 System.Data.DataTable dt3 =bll_Plan.GetList("plan_type='***' order by id asc").Tables[0];
              
                 DataSet ds = new DataSet();
                 ds.Tables.Add(GetTable(dt1, "T_Project"));
                 ds.Tables.Add(GetTable(dt2, "T_PlanJian"));
                 ds.Tables.Add(GetTable(dt3, "T_PlanPing"));

                string strName = saveFileDialog1.FileName;
                ToExcelSheet(ds, "mysheet", strName);
            }
          
            //ToExcel2(gridView2, saveFileDialog1);
        }
        public System.Data.DataTable GetTable(System.Data.DataTable Dt, string tablename)
        {

            Dt.AcceptChanges();

            System.Data.DataTable m_Dt = new System.Data.DataTable();//定義一個新的Table

            int m_RowCount = (int)Dt.Rows.Count;//定義一個變數,值為Dt的行數

            int m_ColCount = Dt.Columns.Count;//定義一個變數,值為Dt的列數

            for (int j = 0; j < m_ColCount; j++)
            {

                m_Dt.Columns.Add(Dt.Columns[j].ColumnName, Dt.Columns[j].DataType);

            }

            for (int i = 0; i < m_RowCount; i++)//增加記錄在臨時表中
            {

                if (Dt.Rows[i].RowState.ToString() != "Deleted")
                {

                    DataRow NewRow = m_Dt.NewRow();//定義一個新行為m_Dt表的新行

                    for (int j = 0; j < m_ColCount; j++)//迴圈行
                    {

                        NewRow[j] = Dt.Rows[i][j];

                    }

                    m_Dt.Rows.Add(NewRow);//臨時表中增加新行

                }

            }

            m_Dt.TableName = tablename;

            return m_Dt;//返回臨時表

        }

 


 


        #region 匯出到excel多sheet的兩種方法

        private void ToExcelSheet(DataSet ds, string sheetName, string strFileName)
        {
            //Exsel模板
            string templetFile = System.Windows.Forms.Application.StartupPath + @"/Temp/template.xls";
            System.Reflection.Missing miss = System.Reflection.Missing.Value;
            //建立EXCEL物件appExcel,Workbook物件,Worksheet物件,Range物件
            Excel.Application appExcel;
            appExcel = new Excel.Application();

            Excel.Workbook workbookData;
            Excel.Worksheet worksheetData;
            Excel.Range rangedata;
            //設定物件不可見
            appExcel.Visible = false;
            /* 在呼叫Excel應用程式,或建立Excel工作簿之前,記著加上下面的兩行程式碼
             * 這是因為Excel有一個Bug,如果你的作業系統的環境不是英文的,而Excel就會在執行下面的程式碼時,報異常。
             */
            System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
            //以新建的方式
           // workbookData = appExcel.Workbooks.Add(miss);
            //以模板的方式
            workbookData = appExcel.Workbooks.Open(templetFile, miss, miss, miss, miss, miss,miss, miss, miss, miss, miss, miss, miss);

        
            try
            {
                for (int k = 0; k < ds.Tables.Count; k++)
                {
                    worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
                    //worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add();
                    worksheetData.Name = ds.Tables[k].TableName;

                    if (ds.Tables[k] != null)
                    {
                        //表字段(表頭)
                        for (int i = 0; i < ds.Tables[k].Columns.Count; i++)
                        {
                            worksheetData.Cells[i + 1] = ds.Tables[k].Columns[i].ColumnName.ToString();
                        }
                        //先給Range物件一個範圍為A2開始,Range物件可以給一個CELL的範圍,也可以給例如A1到H10這樣的範圍
                        //因為第一行已經寫了表頭,所以所有資料都應該從A2開始
                        rangedata = worksheetData.get_Range("A2", miss);
                        Excel.Range xlRang = null;
                        //總行數
                        int iRowCount = ds.Tables[k].Rows.Count;
                        //iEachSize當前每次匯出的行數的頁面大小,可以自己設定
                        int iEachSize = 2;
                        //已匯出的行數     ,當前每次匯出的行數大小
                        int iParstedRow = 0, iCurrSize = 0;

                        //列數
                        int iColumnAccount = ds.Tables[k].Columns.Count;
                        //在記憶體中宣告一個iEachSize×iColumnAccount的陣列,iEachSize是每次最大儲存的行數,iColumnAccount就是儲存的實際列數
                        object[,] objVal = new object[iEachSize, iColumnAccount];

                        iCurrSize = iEachSize;
                        /*
                        //方法一:Cell方法匯出表資料
                        for (int i = 0; i < ds.Tables[k].Rows.Count; i++)
                        {
                            for (int j = 0; j < ds.Tables[k].Columns.Count; j++)
                            {
                                //worksheetData.Cells[i + 2, j + 1] = ds.Tables[k].Rows[i][j].ToString();
                                objVal[i, j] = ds.Tables[k].Rows[i][j].ToString();
                            }
                            System.Windows.Forms.Application.DoEvents();
                        }
                         */
                        //方法二:Range方法匯出表資料(此方法匯出很快,建議用此方法)
                        while (iParstedRow < iRowCount)
                        {
                            //總行數-已匯出行數;剩餘行數是否小於頁面大小,小於的話,當前匯出行數為餘行
                            if ((iRowCount - iParstedRow) < iEachSize)
                            {
                                iCurrSize = iRowCount - iParstedRow;
                            }
                            for (int i = 0; i < iCurrSize; i++)
                            {
                                for (int j = 0; j < iColumnAccount; j++)
                                {
                                    //objVal[i, j] = gridView[j, i + iParstedRow].Value.ToString();
                                    objVal[i, j] = ds.Tables[k].Rows[i + iParstedRow][j].ToString();

                                }

                                System.Windows.Forms.Application.DoEvents();
                            }

                            /*
                                 * 建議使用設定斷點研究下哈
                                 * 例如A1到H10的意思是從A到H,第一行到第十行
                                 * 下句很關鍵,要保證獲取workSheet中對應的Range範圍
                                 * 下句實際上是得到這樣的一個程式碼語句xlRang = worksheetData.get_Range("A2","H100");
                                 * 注意看實現的過程
                                 * 'A' + iColumnAccount - 1這兒是獲取你的最後列,A的數字碼為65,大家可以仔細看下是不是得到最後列的字母
                                 * iParstedRow + iCurrSize + 1獲取最後行
                                 * 若WHILE第一次迴圈的話這應該是A2,最後列字母+最後行數字
                                 * iParstedRow + 2要注意,每次迴圈這個值不一樣,他取決於你每次迴圈RANGE取了多大,也就是iEachSize設定值的大小哦
                                 */
                            xlRang = worksheetData.get_Range("A" + ((int)(iParstedRow + 2)).ToString(), ((char)('A' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());
                            // 呼叫Range的Value2屬性,把記憶體中的值賦給Excel
                            xlRang.Value2 = objVal;
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
                            xlRang = null;
                            //已匯出的行數=已匯出的行數+當前匯出行數
                            iParstedRow = iParstedRow + iCurrSize;
                        }
                    }

                    worksheetData.Columns.EntireColumn.AutoFit();
                    workbookData.Saved = true;

                }

                
                //workbookData.SaveAs(strFileName);
                workbookData.SaveAs(strFileName + "", miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
                appExcel.Quit();
                // 別忘了在結束程式之前恢復你的環境!
               System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();               
                XtraMessageBox.Show("匯出完成!", "提示資訊", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch {
                appExcel.Quit();
                //呼叫方法關閉EXCEL程序,大家可以試下不用的話如果程式不關閉在程序裡一直會有EXCEL.EXE這個程序並鎖定你的EXCEL表格
                this.KillSpecialExcel(appExcel);
                // 別忘了在結束程式之前恢復你的環境!
                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                GC.Collect();
                XtraMessageBox.Show("匯出失敗!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);

            }

        }
        #endregion

、、、、、、、、、、、、、、、

此方法本人測試通過,如有不完善地方,望指出!