首先从数据库读取数据到DataTable,这我就不提了,大家都明白。下面直接介绍如何从DataTable高效率导出数据到Excel中的方法,代码如下:

 1 using Microsoft.Office.Interop.Excel;
 2 using System.Runtime.InteropServices;
 3 
 4 [DllImport("User32.dll", CharSet = CharSet.Auto)]
 5 public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int pid);
 6 //函数原型;DWORD GetWindowThreadProcessld(HWND hwnd,LPDWORD lpdwProcessld);
 7 //参数:hWnd:窗口句柄
 8 //参数:lpdwProcessld:接收进程标识的32位值的地址。如果这个参数不为NULL,GetWindwThreadProcessld将进程标识拷贝到这个32位值中,否则不拷贝
 9 //返回值:返回值为创建窗口的线程标识。
10 
11 //dt:从数据库读取的数据;file_name:保存路径;sheet_name:表单名称
12 private void DataTableToExcel(DataTable dt, string file_name, string sheet_name)
13 {
14        Microsoft.Office.Interop.Excel.Application Myxls = new  Microsoft.Office.Interop.Excel.Application();
15        Microsoft.Office.Interop.Excel.Workbook Mywkb = Myxls.Workbooks.Add();
16        Microsoft.Office.Interop.Excel.Worksheet MySht = Mywkb.ActiveSheet;
17        MySht.Name = sheet_name;
18        Myxls.Visible = false;
19        Myxls.DisplayAlerts = false;
20        try
21        {
22               //写入表头
23               object[] arrHeader = new object[dt.Columns.Count];
24               for(int i = 0; i < dt.Columns.Count; i++)
25               {
26                      arrHeader[i] = dt.Columns[i].ColumnName;
27               }
28               MySht.Range[Mysht.Cells[1,1], MySht.Cells[1,dt.Columns.Count]].Value2 = arrHeader;
29               //写入表体数据
30               object[,] arrBody = new object[dt.Rows.Count, dt.Columns.Count];
31               for(int i = 0; i < dt.Rows.Count; i++)
32               {
33                       for(int j = 0; j < dt.Columns.Count; j++)
34                       {
35                               arrBody[i,j] = dt.Rows[i][j].ToString();
36                       }
37               }
38               MySht.Range[MySht.Cells[2,1], MySht.Cells[dt.Rows.Count + 1, dt.Columns.Count]].Value2 = arrBody;
39               if(Mywkb != null)
40               {
41                       Mywkb.SaveAs(file_name);
42                       Mywkb.Close(Type.Missing, Type.Missing, Type.Missing);
43                       Mywkb = null;
44               }
45        }
46        catch(Exception ex)
47        {
48                MessageBox.Show(ex.Message, "系统提示");
49        }
50        finally
51        {
52                 //彻底关闭Excel进程
53                 if(Myxls != null)
54                 {
55                        Myxls.Quit();
56                        try
57                        {
58                               if(Myxls != null)
59                               {
60                                     int pid;
61                                     GetWindowThreadProcessId(new IntPtr(Myxls.Hwnd), out pid);
62                                     System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(pid);
63                                      p.Kill();
64                               }
65                        }
66                        catch(Exception ex)
67                        {
68                               MessageBox.Show("结束当前EXCEL进程失败:" + ex.Message);
69                        }
70                        Myxls = null;
71                 }
72                 GC.Collect();
73        }
74 }

说明:

1)上述方法中,将DataTable单元格内容写入数组后一次性赋值给Excel的Range,效率非常高,比之循环DataTable单元格逐个赋值给Excel的Cell的方法,速度快多了;

2)Excel的Range.Value(2)既可以给Excel的区域赋值,也可以获取Excel区域的值,通过Excel的Range.Value(2)来获取区域的值,比之循环区域Cell逐个获取值存储在数组中的方法,效率高得多;

3)上述方法中用到的彻底关闭Excel进程的方式,也值得注意。

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!