• 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个文件了。


                

           

  • 相关阅读:
    定点数的表示
    [收集]XMPP使用tls 和sasl登录
    socket函数
    [收集] SendMessage、PostMessage原理
    DLL中用malloc分配了一块内存,但是在exe程序中释放引发的错误:其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。
    关于在IWebBrowser中无法响应Ctrl+C等快捷键的解决方法
    Enum 操作
    程序员面对分歧和难题应当具备的态度【转】
    NDIS学习笔记一
    NDIS学习笔记二——(模拟丢包)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3184842.html
Copyright © 2020-2023  润新知