zoukankan      html  css  js  c++  java
  • 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个文件了。


                

           

  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3184842.html
Copyright © 2011-2022 走看看