C#通過OLEDB導出大數據到Excel


        C#導出數據到Excel,基本有兩種方法,一種方法是通過Microsoft.Office.Interop.Excel.Application,一行一列的寫入Excel中;另一種方法是通過OLEDB,利用DataSet批量更新的放大寫入Excel中。

        這兩種方法各有用處。通過Microsoft.Office.Interop.Excel.Application傳數據到Excel中,可以比較好的控制表格的格式,以便於直接 查看和打印,但效率低;通過OLEDB傳數據到Excel中,格式不方便控制,但效率高。

        我最近在導出大數據時(750w用戶數據,分城市導出,每個Excel文件只有一個sheet,其中最多1000條),通過Microsoft.Office.Interop.Excel.Application傳數據到Excel中一直沒有成功,這種方法通過COM傳數據的方法存在內存釋放以及FrameWork框架方面的問題;后來我通過OLEDB成功導出。


      1、准備工作:在磁盤中建立一個模版Excel文件,這個Excel文件的sheet1的第一行填寫好表頭。

      2、核心代碼:

           2.1、 取出城市數據到 DataTable cityDt="所有城市並按id排序";

           2.2、文件存放的文件夾 fileOutFolder

          2.3、我把數據分在五台計算機上導出,於是有一個城市分類的方法

           private void city(int cityMode)
           {
                   int cityRowNum = cityDt.Rows.Count;
                   int cityColumnNum = cityDt.Columns.Count;
                  for (int i = 0; i < cityRowNum; i++)
                 {
                         if (i % 5 == cityMode)  fileOutOleDb(i);
                 }            
                 this.Close();
           }

         2.4、讀取需要導出的城市的用戶記錄數

          private int  findUserCount(int cityId)

         {

                  讀取數據庫數據

        }

        2.5、讀取相應頁的用戶數

        private DataTable findUser(int cityId,int int skipNum)

        {

              return DataTable("select * from user where id="+cityId.toString()+" limit "+skipNum.tostring+",1000");

        }

       2.6、導出Excel文件處理

 

        private void fileOutOleDb(int i)
        {
            int city_id = Convert.ToInt32(cityDt.Rows[i][0]);
            string city_ename = cityDt.Rows[i]["ename"].ToString();
            string city_name = cityDt.Rows[i]["ename"].ToString();
            int userCount = findUserCount(city_id);
            int pageCount = userCount / 1000;
            if (pageCount * 1000 < userCount) userCount += 1;
            int beginPageNo = 1;// Convert.ToInt32(textBox3.Text);
            int endPageNo = pageCount;// Convert.ToInt32(textBox4.Text);
            string curDirectory = fileOutFolder + "\\" + city_name;
            if (!Directory.Exists(curDirectory))
            {
                Directory.CreateDirectory(curDirectory);
            }

            for (int j = beginPageNo; j <= endPageNo; j++)
            {
                textBox2.Text = j.ToString();
                try
                {
                    //1、讀出數據
                    DataTable tempdt = findUser(Convert.ToInt32(cityDt.Rows[i][0]), j * 1000);
                    //判斷文件是否存在,不存在則拷貝一個文件
                    string fileFullName = curDirectory + "\\" + city_name + "_" + j.ToString() + ".xls";
                    if (!File.Exists(fileFullName))
                    {
                        File.Copy("d:\\model.xls", fileFullName);
                    }

                    //2、得到連接對象
                    string strCon = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=YES;IMEX=0'", fileFullName);
                    OleDbConnection myConn = new OleDbConnection(strCon);
                    string strCom = "SELECT * FROM [Sheet1$]";
                    myConn.Open();
                    OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(strCom, myConn);
                    DataSet myDataSet = new DataSet();
                    myDataAdapter.Fill(myDataSet, "[Sheet1$]");
                    myConn.Close();
                    DataTable dt = myDataSet.Tables[0]; //初始化DataTable實例
                    dt.PrimaryKey = new DataColumn[] { dt.Columns["id"] };//創建索引列

                    int rowNum = tempdt.Rows.Count;
                    int colNum = tempdt.Columns.Count;
                    for (int k = 0; k < rowNum; k++)
                    {
                        DataRow myRow = dt.NewRow();
                        for (int m = 0; m < colNum; m++) myRow[m] = tempdt.Rows[k][m];
                        dt.Rows.Add(myRow);
                    }
                    OleDbCommandBuilder odcb = new OleDbCommandBuilder(myDataAdapter);
                    odcb.QuotePrefix = "[";   //用於搞定INSERT INTO 語句的語法錯誤
                    odcb.QuoteSuffix = "]";

                    myDataAdapter.Update(myDataSet, "[Sheet1$]"); //更新數據集對應的表
                }
                catch
                {
                }
                if (j == pageCount) break;
                //System.Threading.Thread.Sleep(1000);
            }
        }


 

這個數據導出,有兩個瓶頸,一個是讀取數據,一個是一個城市數據量特別大。我導出100w的需要37分鍾,開始導出非常快(20個文件,2W左右),到后面1分鍾就2個文件了。


            

       

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM