大批量快速导出Excel方法

我的方法不是使用微软的excel操作类,因为那种实在爆慢,一个个单元格循环写,实在太慢了。【不信朋友们可以试试】
而使用io写的话  半分钟都不用
我数据库数据量为:120000行 29列

技术要点:1.使用的是StreamWriter sw = new StreamWriter(path, false,Encoding.GetEncoding("gb2312"));最终生成文件
2.使用  StringBuilder sb = new StringBuilder();类把查询出来的数据组合为一句超长字符串一次性插入到excel中,
sb.Append(ds.Tables[0].Columns[k].ColumnName.ToString() + "\t");
注意,可不能漏了"\t" 这个是非常重要的! 因为c# "\t"就等于 键盘上的Tab [朋友们可以试试:打开新的txt然后输入1按Tab,输入2按Tab,输入3按Tab保存,然后打开excel文件  把刚刚保存的txt文件拉进去打开你就发现原来。这样写的话1 2 3 会分别在每个单元格上的了。所以上面才使用 "\t"连起来数据库出来的那堆数据,这样一次性导进去,他们就会按照每个单元格来填充!]

方法如下(原文的代码):

private  void  button1_Click( object  sender, EventArgs e)
         {            
             saveFileDialog1.Title =  "保存的excel文件" ;
             saveFileDialog1.InitialDirectory =  "c:\\" ;
             saveFileDialog1.Filter =  "Excel97-2003 (*.xls)|*.xls|All Files (*.*)|*.*" ;
             saveFileDialog1.ShowDialog();
             if  (saveFileDialog1.FileName ==  ""  || saveFileDialog1.FileName ==  null )
             {
                 MessageBox.Show( "文件名不能为空!" );
                 return ;
             }
             string  path = saveFileDialog1.FileName;
             string  constr =  "Data Source=.;Initial Catalog=Exhibition;User ID=sa;Password=" ;
             string  sql = GetStrSql();
             DataSet ds= new  DataSet();
             using  (SqlConnection con =  new  SqlConnection(constr))
             {
                 SqlDataAdapter da =  new  SqlDataAdapter(sql, con);
                 da.Fill(ds);
             }
             if  (ds ==  null )
             {
                 MessageBox.Show( "数据获取有误!" );
                 return ;
             }
             WriteExcel(ds, path);      
         }
 
  public  void  WriteExcel(DataSet ds,  string  path)
         {
             try
             {
                 long  totalCount = ds.Tables[0].Rows.Count;
                 lblTip.Text =  "共有"  + totalCount +  "条数据。" ;
                 Thread.Sleep(1000);
                 long  rowRead = 0;
                 float  percent = 0;
 
                 StreamWriter sw =  new  StreamWriter(path,  false ,Encoding.GetEncoding( "gb2312" ));
                 StringBuilder sb =  new  StringBuilder();
                 for  ( int  k = 0; k < ds.Tables[0].Columns.Count; k++)
                 {
                     sb.Append(ds.Tables[0].Columns[k].ColumnName.ToString() +  "\t" );
                 }
                 sb.Append(Environment.NewLine);
 
                 for  ( int  i = 0; i < ds.Tables[0].Rows.Count; i++)
                 {
                     rowRead++;
                     percent = (( float )(100 * rowRead)) / totalCount;
                     Pbar.Maximum = ( int )totalCount;
                     Pbar.Value = ( int )rowRead;
                     lblTip.Text =  "正在写入["  + percent.ToString( "0.00" ) +  "%]...的数据" ;
                     System.Windows.Forms.Application.DoEvents();
 
                     for  ( int  j = 0; j < ds.Tables[0].Columns.Count; j++)
                     {
                         sb.Append(ds.Tables[0].Rows[i][j].ToString() +  "\t" );
                     }
                     sb.Append(Environment.NewLine);
                 }
                 sw.Write(sb.ToString());
                 sw.Flush();
                 sw.Close();
                 MessageBox.Show( "已经生成指定Excel文件!" );
             }
             catch  (Exception ex)
             {
                 MessageBox.Show(ex.Message);
             }            
         }
 
public  string  GetStrSql()
         {
             string  strSql =  "select d.* from ( select cBarcode ,max(case halldoorid  When '36' then '1' else '0' end ) [1.1号馆],max(case halldoorid  When '37' then '1' else '0' end ) [2.1号馆],max(case halldoorid  When '38' then '1' else '0' end ) [3.1号馆],max(case halldoorid  When '39' then '1' else '0' end ) [4.1号馆],max(case halldoorid  When '40' then '1' else '0' end ) [5.1号馆],max(case halldoorid  When '41' then '1' else '0' end ) [6.1号馆],max(case halldoorid When '42' then '1' else '0' end ) [8.1号馆],max(case halldoorid  When '43' then '1' else '0' end ) [1.2号馆],max(case halldoorid  When '44' then '1' else '0' end ) [2.2号馆],max(case halldoorid  When '45' then '1' else '0' end ) [3.2号馆],max(case halldoorid  When '46' then '1' else '0' end ) [4.2号馆],max(case halldoorid  When '47' then '1' else '0' end ) [5.2号馆],max(case halldoorid  When '48' then '1' else '0' end ) [9.1号馆],max(case halldoorid  When '49' then '1' else '0' end ) [10.1号馆],max(case halldoorid  When '50' then '1' else '0' end ) [11.1号馆],max(case halldoorid  When '51' then '1' else '0' end ) [12.1号馆],max(case halldoorid  When '52' then '1' else '0' end ) [13.1号馆],max(case halldoorid  When '53' then '1' else '0' end ) [9.2号馆],max(case halldoorid  When '54' then '1' else '0' end ) [10.2号馆],max(case halldoorid  When '55' then '1' else '0' end ) [11.2号馆],max(case halldoorid  When '56' then '1' else '0' end ) [12.2号馆],max(case halldoorid  When '57' then '1' else '0' end ) [13.2号馆],max(case halldoorid  When '58' then '1' else '0' end ) [9.3号馆],max(case halldoorid  When '59' then '1' else '0' end ) [10.3号馆],max(case halldoorid  When '60' then '1' else '0' end ) [11.3号馆],max(case halldoorid  When '61' then '1' else '0' end ) [VIP3.2号馆],max(case halldoorid  When '62' then '1' else '0' end ) [VIP11.3号馆],max(case halldoorid  When '63' then '1' else '0' end ) [VIP14.3号馆]from tblReadCard  group by cBarcode ) d left join ( select cBarcode 观众条码 from (select distinct cBarcode,cReadDate from tblReadCard where cReadDate between '2011-07-08' and '2011-07-11') a group by cBarcode  ) c on d.cBarcode=c.观众条码 group by cBarcode,[1.1号馆],[2.1号馆],[3.1号馆],[4.1号馆],[5.1号馆],[6.1号馆],[8.1号馆],[1.2号馆],[2.2号馆],[3.2号馆],[4.2号馆],[5.2号馆],[9.1号馆],[10.1号馆],[11.1号馆],[12.1号馆],[13.1号馆],[9.2号馆],[10.2号馆],[11.2号馆],[12.2号馆],[13.2号馆],[9.3号馆],[10.3号馆],[11.3号馆],[VIP3.2号馆],[VIP11.3号馆],[VIP14.3号馆]" ;
             return  strSql;
         }

---------------------------以下是用到自己项目中的代码片段--------------------------------------------
            string fileName= "XXXX导出"+DateTime.Now.ToString("yyyyMMddHHmmss")+".xls";//此时没有文件 后面会自动创建
            string path = Server.MapPath("~/") + @"ExcelTemp\" + fileName;
            string strResult = string.Empty;

                string strWhere = "XXXXXX";
                string orderby = "  XXXXX ";
                DataSet ds = bll.GetListOnExportExcel( strWhere, orderby);//此处获取DataSet(注意DataTable中的列名字就是表头,所以要提前在sql语句中写好中文列名)
                StreamWriter sw = new StreamWriter(path, false, Encoding.GetEncoding("gb2312"));
                StringBuilder sb = new StringBuilder();
                for (int k = 0; k < ds.Tables[0].Columns.Count; k++)
                {
                    sb.Append(ds.Tables[0].Columns[k].ColumnName.ToString().Replace("\n", " ") + "\t");
                }
                sb.Append(Environment.NewLine);


                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                    {
                        sb.Append(ds.Tables[0].Rows[i][j].ToString().Replace("\n", " ") + "\t");
                    }
                    sb.Append(Environment.NewLine);
                }
                sw.Write(sb.ToString());
                sw.Flush();
                sw.Close();
                //此时文件已经有了,传地址下载即可


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中进行大批量导出Excel时,可能会遇到内存溢出的问题。这是因为Excel文件通常占用较大的内存空间,当数据量较大时,可能会超过JVM所配的内存限制。 为了解决这个问题,可以采取以下几种方法: 1. 批次导出:将要导出数据多个批次进行导出,每次导出一部数据,以减少内存占用。可以根据数据的大小和服务器的内存情况来确定每个批次的大小。 2. 使用XSSFWorkbook替代HSSFWorkbook:HSSFWorkbook是用于处理Excel 97-2003格式的库,而XSSFWorkbook则是处理Excel 2007及更高版本的库。后者的内存占用要比前者低,因此可以考虑将工作簿对象由HSSFWorkbook替换为XSSFWorkbook。 3. 使用SXSSFWorkbook:SXSSFWorkbook是Apache POI提供的一种特殊的工作簿对象,它可以将数据直接写入磁盘而不是内存,从而大大降低内存占用。使用SXSSFWorkbook需要注意的是,导出Excel文件不能被随机访问,只能顺序读取。 4. 增加JVM内存限制:可以通过增加JVM的堆内存限制来解决内存溢出问题。可以通过修改JVM启动参数中的-Xmx和-Xms来增加堆内存限制。但是这种方法需要根据服务器的硬件资源和其他应用的内存需求进行合理的配置和调优。 5. 使用CSV格式代替Excel:如果Excel格式并不是必须要求,可以考虑将数据导出为CSV格式。CSV格式的文件较小,占用较少的内存,并且可以直接用文本编辑器打开和编辑。 以上是解决Java大批量导出Excel内存溢出问题的几种方法,可以根据具体情况选择适合的方法进行解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值