What is the fastest way to export dataGridView rows to Excel or into an SQL Server database
将460328-800328范围内的DataGridView行导出到Excel或SQL Server数据库表时,如果不使用Microsoft Office Interop,则最快的方法是什么?因为Interop速度非常慢,而且对系统资源的占用非常大?
对于导出到Excel,如果不使用基于XML的2007或2010,则interop几乎是唯一的方法。不过,它并没有它的名声那么坏。我将列出一些解决方案。
1到Excel首先将Microsoft.Office.Interop.Excel组件引用添加到项目中。这应该在"项目"->"添加引用"中的.NET选项卡下。将using语句添加到表单中:
0添加按钮控件,并将此代码添加到其正文:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | private void btnExport_Click(object sender, EventArgs e) { Excel.Application app = new Excel.Application(); app.Visible = true; Excel.Workbook wb = app.Workbooks.Add(1); Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1]; // changing the name of active sheet ws.Name ="Exported from gridview"; ws.Rows.HorizontalAlignment = HorizontalAlignment.Center; // storing header part in Excel for (int i = 1; i < dataGridView1.Columns.Count + 1; i++) { ws.Cells[1, i] = dataGridView1.Columns[i - 1].HeaderText; } // storing Each row and column value to excel sheet for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { for (int j = 0; j < dataGridView1.Columns.Count; j++) { ws.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString(); } } // sizing the columns ws.Cells.EntireColumn.AutoFit(); // save the application wb.SaveAs("c:\\output.xls",Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive , Type.Missing, Type.Missing, Type.Missing, Type.Missing); // Exit from the application app.Quit(); } } |
2-到SQL Server
这不需要互操作。为便于使用,请将列表对象传递给执行插入的事件。如果设置了与网格视图列相对应的表,则很容易。在这里,我使用一个存储过程。
2如果我需要为你调整一下,请告诉我。在最初的示例中,我在表单_Load方法中声明了list rows=new list()。这对该解决方案有效,但其范围现在太有限了。我已经将其向上/向外移动到类中,以便可以在表单的任何位置调用in(特别是btnotsql_click)。我已经在下面发表了评论:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | List<Row> rows = new List<Row>(); private void Form1_Load(object sender, EventArgs e) { //var rows = new List<Row>(); //limited scope var sr = new StreamReader(@"C:\so_test.txt"); while (!sr.EndOfStream) { string s = sr.ReadLine(); if (!String.IsNullOrEmpty(s.Trim())) { rows.Add(new Row(s)); } } sr.Close(); dataGridView1.DataSource = rows; } |
在没有Office的情况下从C中签出创建Excel文件,因为这意味着使用EPPLUS非常有效-我可以从数据表中创建我的csv数据,并在内存中大容量加载要输出的Excel文件。只需几行代码。variable csvdata是所有csvdata的字符串值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using( ExcelPackage pck = new ExcelPackage( ) ) { //Create the worksheet ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Sheet1" ); // set the delimiter etf.Delimiter = ','; etf.EOL =" "; etf.TextQualifier ="""; //Load the datatable into the sheet, starting from cell A1. Print the column names on row 1 ws.Cells["A1"].LoadFromText( csvData, etf ); return pck.GetAsByteArray( ); } |
对于传输到Excel,这是我找到的最快的方法(尽管它确实使用Office Interop)。循环遍历DataGridView中的每个单元格,并将其分配给对象数组。然后将整个数组赋给Excel区域。这比单独为每个Excel单元格赋值快得多,因为它只调用一次互操作。原谅VB:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | Sub Export() Dim xlApp As New Excel.Application Dim wb As Excel.Workbook = xlApp.Workbooks.Add Dim ws As Excel.Worksheet = wb.Worksheets(1) Dim dgv as DataGridView = MyDataGridView Dim ExportArray(dgv.Rows.Count, dgv.Columns.Count - 1) As Object Dim j, i As Integer For j = 0 To dgv.Columns.Count - 1 ExportArray(0, j) = dgv.Columns(j).Name For i = 1 To dgv.Rows.Count ExportArray(i, j) = dgv(j, i - 1).Value Next Next Dim col As String = ColNumtoLetter(j) ws.Range("A1:" & col & i).Value = ExportArray End Sub Private Function ColNumtoLetter(ByVal iCol As Integer) As String Dim Result As String ="" Dim iAlpha As Integer = Int(iCol / 26.001) Dim iRemainder As Integer = iCol - (iAlpha * 26) If iAlpha > 0 Then Result = Chr(iAlpha + 64) End If If iRemainder > 0 Then Result = Result & Chr(iRemainder + 64) End If Return Result End Function |
第二个方法只是将最后一个列号转换为相应的Excel列名。
有关详细信息,请参阅"从数据集快速导出到Excel"和"更快地将数据导出到Excel"。
在这里,我使用DataTable将数据写入Excel文件。我认为数据网格视图也与数据表相同。
首先从数据库获取数据:
1 | db.GetData(sqlgetprint); |
方法的调用方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class DataBaseConnection { private OdbcConnection conn1 = new OdbcConnection(@"FILEDSN=C:/OTPub/Ot.dsn;" +"Uid=sa;" +"Pwd=otdata@123;"); //"DSN=Ot_DataODBC;" +"Uid=sa;" + "Pwd=otdata@123;" //select public System.Data.DataTable GetData(string sql) { try { conn1.Open(); OdbcDataAdapter adpt = new OdbcDataAdapter(sql, conn1); DataTable dt = new DataTable(); adpt.Fill(dt); conn1.Close(); return dt; } catch (Exception ex) { conn1.Close(); throw ex; } } } |
之后,在工作窗体中为databaseconcentation类创建对象
1 |
在按钮单击事件中,可以将此代码写入Excel文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | string sqlgetprint ="SELECT Service_No,Full_name, Acc_No, OP_date, On_time, Off_time, OP_hours, Payment FROM Print_Op ORDER BY Service_No , OP_date"; DataTable dtall = db.GetData(sqlgetprint); SaveFileDialog saveFileDialog1 = new SaveFileDialog(); saveFileDialog1.Filter ="Excel Documents (*.xls)|*.xls"; saveFileDialog1.FileName ="Employee Details.xls"; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { string fname = saveFileDialog1.FileName; StreamWriter wr = new StreamWriter(fname); for (int i = 0; i < dtall.Columns.Count; i++) { wr.Write(dtall.Columns[i].ToString().ToUpper() +"\t"); } wr.WriteLine(); //write rows to excel file for (int i = 0; i < (dtall.Rows.Count); i++) { for (int j = 0; j < dtall.Columns.Count; j++) { if (dtall.Rows[i][j] != null) { wr.Write(Convert.ToString(dtall.Rows[i][j]) +"\t"); } else { wr.Write("\t"); } } //go to next line wr.WriteLine(); } //close file wr.Close(); if (File.Exists(fname)) { System.Diagnostics.Process.Start(fname); } } } catch (Exception) { MessageBox.Show("Error Create Excel Sheet!"); } |
一种选择是将数据写入csv文件,而不是Excel文件。Excel在阅读之后不会有问题。
如果您不熟悉,在csv(即逗号分隔)文件中,字段由逗号分隔,行由换行符分隔(
)。
类似(可能无法编译!):
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void WriteData() { using (var file = System.IO.StreamWriter(@"C:\Path\To\File.csv")) { foreach (var row in dataGrid.Rows) { foreach (var cell in row.Cells) { // Note that if some cells contain commas, // you'd need to wrap them in quotes. file.Write(cell.Value).Write(","); } } file.Write(" "); } } |
为了提高性能,最好将几百(或数千)行收集到一个字符串中,然后将其写入一个文件,而不是逐个单元地写入。
这可能更快,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | using Excel = Microsoft.Office.Interop.Excel; public static void SaveGridToExcel(DataGridView DGV) { if (DGV.Rows.Count > 0) { string filename =""; SaveFileDialog SV = new SaveFileDialog(); SV.Filter ="EXCEL FILES|*.xlsx;*.xls"; DialogResult result = SV.ShowDialog(); if (result == DialogResult.OK) { filename = SV.FileName; bool multiselect = DGV.MultiSelect; DGV.MultiSelect = true; DGV.SelectAll(); DGV.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText; Clipboard.SetDataObject(DGV.GetClipboardContent()); var results = System.Convert.ToString(Clipboard.GetData(DataFormats.Text)); DGV.ClearSelection(); DGV.MultiSelect = multiselect; Microsoft.Office.Interop.Excel.Application XCELAPP = null; Microsoft.Office.Interop.Excel.Workbook XWORKBOOK = null; Microsoft.Office.Interop.Excel.Worksheet XSHEET = null; object misValue = System.Reflection.Missing.Value; XCELAPP = new Excel.Application(); XWORKBOOK = XCELAPP.Workbooks.Add(misValue); XCELAPP.DisplayAlerts = false; XCELAPP.Visible = false; XSHEET = XWORKBOOK.ActiveSheet; XSHEET.Paste(); XWORKBOOK.SaveAs(filename, Excel.XlFileFormat.xlOpenXMLWorkbook); XWORKBOOK.Close(false); XCELAPP.Quit(); try { System.Runtime.InteropServices.Marshal.ReleaseComObject(XSHEET); System.Runtime.InteropServices.Marshal.ReleaseComObject(XWORKBOOK); System.Runtime.InteropServices.Marshal.ReleaseComObject(XCELAPP); } catch { } } } } |