CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

C#快速往Excel中插入数据的问题,请小山,秋枫等热心高手帮忙

楼主sywcf(wcf)2006-01-12 10:30:59 在 .NET技术 / C# 提问

我现在是做access数据导入到Excel中的程序.  
  我先把access中的数据存入了DataTable中,现在导入Excel中,查了好多资料,都说明了速度快是先把数据放入一个二维数组中,然后再赋给Range,我也这样试了。但速度并不快。现在只有2万多条记录,一个10个字段,  
  请高手给个能真正加快速度的好用实例。 问题点数:100、回复次数:33Top

1 楼hyj_828(水梦)回复于 2006-01-12 10:44:22 得分 6

文本流瀉cvs最快.  
   
  不過你點名了請人,我就不多嘴了.Top

2 楼lidong6(立冬)回复于 2006-01-12 10:50:01 得分 10

能不能导出到CSV格式的文件中,   CSV文件也是用EXCEL打开的.  
  或是导出到CSV文件再转换成EXCEL  
   
  导出到CSV应该是最快的了,   就和写文本文件一样.Top

3 楼sywcf(wcf)回复于 2006-01-12 10:50:24 得分 0

楼上老兄别误会,还请多多指教,下次就点你了。--)  
   
  还有我的是winform的程序。Top

4 楼hyj_828(水梦)回复于 2006-01-12 10:53:16 得分 10

可以直接倒入csv文件。  
   
  table列用vbTab分隔,行用vbLf分隔。  
   
  然後用file直接寫。  
   
  Top

5 楼sywcf(wcf)回复于 2006-01-12 10:53:28 得分 0

导出到csv也行了,只要楼上老兄能给个好用的实例就行了,记得要快速导入啊Top

6 楼sywcf(wcf)回复于 2006-01-12 10:57:11 得分 0

hyj_828(水梦),能不能给个例子,我现在主要是要导入的速度,现在是记录上万条后,导入太慢了。我都受不了。Top

7 楼add8849(雁南飞)回复于 2006-01-12 11:03:44 得分 5

友情UPTop

8 楼singlepine(小山)回复于 2006-01-12 11:06:57 得分 10

http://singlepine.cnblogs.com/articles/305843.html  
  你试一下这个,速度方面没有测试,你测试看是否可以Top

9 楼sywcf(wcf)回复于 2006-01-12 11:14:59 得分 0

singlepine(小山),这个网址目前不能访问.  
   
  还请各位好心兄弟积极参与,最终帮我解决问题的,兄弟会另开贴重谢。Top

10 楼hyj_828(水梦)回复于 2006-01-12 11:18:57 得分 0

Function   ExportToFile(strExcelFile,   table)  
      Dim   fso   As   New   FileSystemObject  
      If   fso.FileExists(strExcelFile)   Then   fso.DeleteFile   strExcelFile  
      Set   xslFile   =   fso.CreateTextFile(strExcelFile,   True)  
      xslFile.WriteLine   (table)  
      xslFile.Close  
      Set   fso   =   Nothing  
  End   Function  
   
  d1   =   "1"   &   vbTab   &   "2"   vbTab   &   vbLf  
   
  ExportToFile   "Tradiitonal.xls",   d1  
   
  這個是vb的代碼,不過該成vb.dotnet很easy的。  
   
  Top

11 楼sywcf(wcf)回复于 2006-01-12 11:28:08 得分 0

用vb可以直接调用系统的导入导出,但是C#兄弟不会。Top

12 楼ChengKing((.net: http://blog.csdn.net/ChengKing ))回复于 2006-01-12 12:30:39 得分 10

参考:  
  生成/读取(反向更新数据库)   Excel文件(示例代码下载)    
  http://blog.csdn.net/ChengKing/archive/2005/11/29/539514.aspxTop

13 楼lidong6(立冬)回复于 2006-01-12 12:44:24 得分 0

csv文件用"\r\n"分隔行用"\t"分隔列的文本文件.  
   
  相信楼主应该很容易的实现的.Top

14 楼luojinat2005()回复于 2006-01-12 12:47:18 得分 1

up  
  --------------------------------------------------------Top

15 楼singlepine(小山)回复于 2006-01-12 23:32:07 得分 10

试试这个  
  -----------------------  
   
  利用系统剪切板,System.Windows.Forms.Clipboard;  
   
   
      ///   <summary>  
      ///   将DataSet里所有数据导入Excel.  
      ///   需要添加COM:   Microsoft   Excel   Object   Library.  
      ///   using   Excel;  
      ///   </summary>  
      ///   <param   name="filePath"></param>  
      ///   <param   name="ds"></param>  
      public   static   void   ExportToExcel(string   filePath,   DataSet   ds)  
      {  
        object   oMissing   =   System.Reflection.Missing.Value;  
        Excel.ApplicationClass   xlApp   =   new   Excel.ApplicationClass();  
        try  
        {  
          //   打开Excel文件。以下为Office   2000.  
          Excel.Workbook   xlWorkbook   =   xlApp.Workbooks.Open(filePath,   oMissing,   oMissing,   oMissing,   oMissing,   oMissing,    
            oMissing,   oMissing,   oMissing,   oMissing,   oMissing,   oMissing,  
            oMissing);  
          Excel.Worksheet   xlWorksheet;  
          //   循环所有DataTable  
          for(   int   i=0;   i<ds.Tables.Count;   i++   )  
          {  
            //   添加入一个新的Sheet页。  
            xlWorksheet   =   (Excel.Worksheet)xlWorkbook.Worksheets.Add(oMissing,oMissing,1,oMissing);  
            //   以TableName作为新加的Sheet页名。  
            xlWorksheet.Name   =   ds.Tables[i].TableName;  
            //   取出这个DataTable中的所有值,暂存于stringBuffer中。  
            string   stringBuffer   =   "";  
            for(   int   j=0;   j<ds.Tables[i].Rows.Count;   j++   )  
            {  
              for(   int   k=0;   k<ds.Tables[i].Columns.Count;   k++   )  
              {  
                 
                stringBuffer   +=   ds.Tables[i].Rows[j][k].ToString();  
                if(   k   <   ds.Tables[i].Columns.Count   -   1   )  
                  stringBuffer   +=   "\t";  
              }  
              stringBuffer   +=   "\n";  
            }  
            //   利用系统剪切板  
            System.Windows.Forms.Clipboard.SetDataObject("");  
            //   将stringBuffer放入剪切板。  
            System.Windows.Forms.Clipboard.SetDataObject(stringBuffer);  
            //   选中这个sheet页中的第一个单元格  
            ((Excel.Range)xlWorksheet.Cells[1,1]).Select();  
            //   粘贴!  
            xlWorksheet.Paste(oMissing,oMissing);  
            //   清空系统剪切板。  
            System.Windows.Forms.Clipboard.SetDataObject("");  
          }  
          //   保存并关闭这个工作簿。  
          xlWorkbook.Close(   Excel.XlSaveAction.xlSaveChanges,   oMissing,   oMissing   );  
          System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook);  
          xlWorkbook   =   null;  
        }  
        catch(Exception   ex)  
        {  
          MessageBox.Show(ex.Message);  
        }  
        finally  
        {  
          //   释放...  
          xlApp.Quit();  
          System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);  
          xlApp   =   null;  
          GC.Collect();  
        }  
      }  
  Top

16 楼sywcf(wcf)回复于 2006-01-13 08:51:36 得分 0

to     singlepine(小山):  
  这个我用过,如果记果几百条还可以,如果几万条,太慢了。  
            for(   int   k=0;   k<ds.Tables[i].Columns.Count;   k++   )  
              {  
                 
                stringBuffer   +=   ds.Tables[i].Rows[j][k].ToString();  
                if(   k   <   ds.Tables[i].Columns.Count   -   1   )  
                  stringBuffer   +=   "\t";  
              }  
              stringBuffer   +=   "\n";  
  这里会执行很长时间.  
  我的表中的10个字段,几万个数据。  
  Top

17 楼chenkejun(我的生活很无聊)回复于 2006-01-13 09:21:37 得分 10

系统剪切板的方法和那种用vbtab分割数据组成文件流的方法某些情况下会出错。  
  例如数据中存在回车换行的情况,就是Excel中一个cell中两行数据的情况。  
  还有要设定输出Excel的cell的属性,否则不好对应日期型、数字型的格式化。  
  你可以把二维数组设置成object型,直接把datatable中的数据赋值进去,再根据datatable的每列属性设置好excel的cell的属性,选取好要填充的区域,把设置好的数组填充过去。Top

18 楼3000sunqin(3000sunqin)回复于 2006-01-13 09:28:34 得分 10

这个问题我碰到过,建议使用VBA来解决,以下是VB代码经过测试,3000条数据从Access中导出大概时间3秒不到;  
  Dim   Rs_Data   As   New   ADODB.Recordset  
  Dim   Irowcount   As   Integer  
  Dim   Icolcount   As   Integer  
           
          Dim   xlApp   As   New   Excel.Application  
          Dim   xlBook   As   Excel.Workbook  
          Dim   xlSheet   As   Excel.Worksheet  
          Dim   xlQuery   As   Excel.QueryTable  
           
          With   Rs_Data  
                  If   .State   =   adStateOpen   Then  
                          .Close  
                  End   If  
                  .ActiveConnection   =   Cn  
                  .CursorLocation   =   adUseClient  
                  .CursorType   =   adOpenStatic  
                  .LockType   =   adLockReadOnly  
                  .Source   =   strOpen  
                  .Open  
          End   With  
          With   Rs_Data  
                  If   .RecordCount   <   1   Then  
                          MsgBox   ("没有记录!")  
                          Exit   Function  
                  End   If  
                  '记录总数  
                  Irowcount   =   .RecordCount  
                  '字段总数  
                  Icolcount   =   .Fields.Count  
          End   With  
           
          Set   xlApp   =   CreateObject("Excel.Application")  
          Set   xlBook   =   Nothing  
          Set   xlSheet   =   Nothing  
          Set   xlBook   =   xlApp.Workbooks().Add  
          Set   xlSheet   =   xlBook.Worksheets("sheet1")  
          xlApp.Visible   =   True  
           
          '添加查询语句,导入EXCEL数据  
          Set   xlQuery   =   xlSheet.QueryTables.Add(Rs_Data,   xlSheet.Range("a1"))  
           
          With   xlQuery  
                  .FieldNames   =   True  
                  .RowNumbers   =   False  
                  .FillAdjacentFormulas   =   False  
                  .PreserveFormatting   =   True  
                  .RefreshOnFileOpen   =   False  
                  .BackgroundQuery   =   True  
                  .RefreshStyle   =   xlInsertDeleteCells  
                  .SavePassword   =   True  
                  .SaveData   =   True  
                  .AdjustColumnWidth   =   True  
                  .RefreshPeriod   =   0  
                  .PreserveColumnInfo   =   True  
          End   With  
           
          xlQuery.FieldNames   =   True   '显示字段名  
          xlQuery.Refresh  
           
          With   xlSheet  
                  .Range(.Cells(1,   1),   .Cells(1,   Icolcount)).Font.Name   =   "黑体"  
                  '设标题为黑体字  
                  .Range(.Cells(1,   1),   .Cells(1,   Icolcount)).Font.Bold   =   True  
                  '标题字体加粗  
                  .Range(.Cells(1,   1),   .Cells(Irowcount   +   1,   Icolcount)).Borders.LineStyle   =   xlContinuous  
                  '设表格边框样式  
          End   With  
           
          With   xlSheet.PageSetup  
                  .LeftHeader   =   ""   &   Chr(10)   &   "&""楷体_GB2312,常规""&10公司名称:"       '   &   Gsmc  
                  .CenterHeader   =   "&""楷体_GB2312,常规""公司人员情况表&""宋体,常规"""   &   Chr(10)   &   "&""楷体_GB2312,常规""&10日   期:"  
                  .RightHeader   =   ""   &   Chr(10)   &   "&""楷体_GB2312,常规""&10单位:"  
                  .LeftFooter   =   "&""楷体_GB2312,常规""&10制表人:"  
                  .CenterFooter   =   "&""楷体_GB2312,常规""&10制表日期:"  
                  .RightFooter   =   "&""楷体_GB2312,常规""&10第&P页   共&N页"  
          End   With  
           
          xlApp.Application.Visible   =   True  
          Set   xlApp   =   Nothing     '"交还控制给Excel  
          Set   xlBook   =   Nothing  
          Set   xlSheet   =   Nothing  
  End   Function  
   
  不知道新的office2003中VBA是否支持.NET,这里使用的是ado的recordSet,看看新版的office有没有支持ado.net的方法  
  Top

19 楼sywcf(wcf)回复于 2006-01-13 09:38:59 得分 0

昨天下午忙别的去了,没及时回贴,多谢大家关注。  
   
  多谢chenkejun(我的生活很无聊)   ,现在问题是将数据导入到Excel中,有几种方法,但是我试过都不太理想,比如利用剪切板的这种,还有可以设置range的方法,最后通过range.set_Value(Missing.Value,   saRet   );   把值传给excel,但是这些方法,在几K条记录时,还可以,几万条时,都很慢。Top

20 楼sywcf(wcf)回复于 2006-01-13 09:42:17 得分 0

谢3000sunqin(3000sunqin),但是请注意,一定要是C#才行,别的现在是不能考虑,由不得自已定.  
  最好是那种能用C#调用access里的导出功能。vb好像可以,但不知C#怎么样?Top

21 楼chenkejun(我的生活很无聊)回复于 2006-01-13 13:37:19 得分 10

range设置的方法还算凑合吧。  
  我是先设置列属性,然后选定range,用range.value   =   array的方法。  
  生成Excel一共三个sheet,分别为24000行,36列;12000行,42列;3200行,20列。  
  整个文件大小14M左右。  
  用时不到30秒。  
  另外机器配置为迅驰1.7G   /   2G   DDR333内存。  
  运行时excel进程占用内存最大60M,最小20M。平均30到35M之间。Top

22 楼chenkejun(我的生活很无聊)回复于 2006-01-13 13:40:28 得分 1

当然是没法和生成CSV文件的速度相比,但CSV不能设置cell属性,看你怎么取舍了。  
  另外我是用VB.NET实现的,应给和C#没什么差别吧。Top

23 楼chenkejun(我的生活很无聊)回复于 2006-01-13 13:47:49 得分 1

还有注意控制一下数据的大小,excel最多65535条数据,1024列。多了会出错。Top

24 楼sywcf(wcf)回复于 2006-01-13 16:32:46 得分 0

问题已经解决,将主要代码贴出,与大家一起分享。  
  1.引用COM组件access10  
   
  Access.ApplicationClass   oAccess   =   new   Access.ApplicationClass();  
  oAccess.Visible   =   false;  
  //ACCESS10:  
  oAccess.OpenCurrentDatabase("d:\\test.mdb",false,"");  
  //导入access  
  oAccess.DoCmd.TransferSpreadsheet(Access.AcDataTransferType.acExport,Access.AcSpreadSheetType.acSpreadsheetTypeExcel9,"一个表名","d:\\test.xls",true,null,null);  
  //导入txt  
  //oAccess.DoCmd.TransferText(Access.AcTextTransferType.acExportDelim,"","一个表名","d:\\test.txt",true,"",0);  
  oAccess.CloseCurrentDatabase();  
  oAccess.DoCmd.Quit(Access.AcQuitOption.acQuitSaveNone);  
  System.Runtime.InteropServices.Marshal.ReleaseComObject   (oAccess);  
  oAccess   =   null;  
  MessageBox.Show("导入成功");  
   
  这是调用access数据库的导出功能直接导出到Excel文件中,速度超级快,10条数据,只需几秒钟。  
   
  相关资料:  
  http://blog.csdn.net/wukong777/archive/2004/10/09/129329.aspx  
  http://wier.csse.monash.edu.au/live/file_data/wier_projects/306/codemodule.htm  
  http://book.77169.org/ask20/how124372.htm  
   
   
  Top

25 楼sywcf(wcf)回复于 2006-01-13 16:35:29 得分 0

10几万条数据,只需几秒钟,哈哈,打错了Top

26 楼chenkejun(我的生活很无聊)回复于 2006-01-13 19:16:09 得分 1

恩,不错。Top

27 楼azmiao(amiao)回复于 2006-01-13 19:50:05 得分 1

我的环境是ASP.NET,在服务器端生成Excel文件,但是如果运行到xlWorkbook.Save时,程序一下就过去了,但是网页还是显示秒漏形状,文件也没有保存下来。我把ASP.NET用户设置成超级用户了。  
  Top

28 楼TT008(T T)回复于 2006-01-13 20:03:19 得分 1

Study  
  如果是SQL的话就直接用邹健老大写的存储过程就行了  
  不过数据量多于六万之后有些数据就导不出了Top

29 楼ttrice(天天米饭)回复于 2006-01-15 01:46:11 得分 1

mark  
  Top

30 楼tangxuehua(netfocus)回复于 2006-01-15 22:20:10 得分 1

能不能先把数据放到SqlServer中,然后利用存储过程来实现;或者也可以考虑用bcp导入导出工具来实现。Top

31 楼echoxue(咱当过兵的人)回复于 2006-01-15 23:34:15 得分 1

学习一下Top

32 楼dashen()回复于 2006-02-08 09:29:05 得分 0

学习Top

33 楼mybobby(天天晴)回复于 2006-02-21 07:47:01 得分 0

markTop

相关问题

  • 关于C#与javascript的两个问题,请秋枫,凡瑞,小山等热心高手帮帮
  • 机器没装office,怎样用程序导出数据到Excel文件,小山,秋枫等热心高手帮忙
  • 关于多线程的问题,请小山,秋枫等热心高手帮助
  • c#与Excel
  • C# 操作Excel
  • 表格横向显示的问题,小山,秋枫,目标是五星等热心高手帮帮忙
  • DataGrid中嵌入省市二级联动的问题,请小山,秋枫,蟑螂等热心人帮忙
  • c++数据结构的入门级问题,热心人求救。
  • asp.net2(c#)+SQL SERVER2005的web.sitemap问题(思归,小山等高手请进....)
  • C#访问Excel 的问题?

关键词

  • c#
  • excel
  • 文件
  • 数据
  • vb
  • strexcelfile
  • 导入
  • omissing
  • xslfile
  • 分隔

得分解答快速导航

  • 帖主:sywcf
  • hyj_828
  • lidong6
  • hyj_828
  • add8849
  • singlepine
  • ChengKing
  • luojinat2005
  • singlepine
  • chenkejun
  • 3000sunqin
  • chenkejun
  • chenkejun
  • chenkejun
  • chenkejun
  • azmiao
  • TT008
  • ttrice
  • tangxuehua
  • echoxue

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo