C# 将dataGridView行导出到Excel或SQL Server数据库的最快方法是什么
在不使用Microsoft office interop的情况下,将460328-800328范围内的DataGridView行导出到Excel或SQL Server数据库表中的最快方法是什么,因为interop非常缓慢且占用大量系统资源 一个选项是将数据写入CSV文件而不是Excel文件。Excel在事后阅读它不会有问题 如果您不熟悉,在CSV(即逗号分隔)文件中,字段用逗号分隔,行用换行符分隔(C# 将dataGridView行导出到Excel或SQL Server数据库的最快方法是什么,c#,datagridview,streamwriter,C#,Datagridview,Streamwriter,在不使用Microsoft office interop的情况下,将460328-800328范围内的DataGridView行导出到Excel或SQL Server数据库表中的最快方法是什么,因为interop非常缓慢且占用大量系统资源 一个选项是将数据写入CSV文件而不是Excel文件。Excel在事后阅读它不会有问题 如果您不熟悉,在CSV(即逗号分隔)文件中,字段用逗号分隔,行用换行符分隔(\n或\r\n) 例如(可能无法编译!): 为了提高性能,最好将几百(或数千)行收集到一个字符串中
\n
或\r\n
)
例如(可能无法编译!):
为了提高性能,最好将几百(或数千)行收集到一个字符串中,然后将其写入文件,而不是逐个单元格写入。对于导出到Excel,如果您不使用基于XML的2007或2010,Interop几乎是唯一的方法。不过,这并不像它的名声那么糟糕。我将列出一些解决方案 1.出类拔萃 首先将Microsoft.Office.Interop.Excel组件引用添加到项目中。这应该在Project->Add Reference的.NET选项卡下。 将using语句添加到表单中: 使用Excel=Microsoft.Office.Interop.Excel 添加按钮控件,并将此代码添加到其主体:
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();
}
}
如果我需要为你调整,请告诉我。在最初的示例中,我有List rows=new List();以加载方法的形式声明。这对解决方案有效,但它的范围现在太有限了。我已将其向上/向外移动到类中,以便可以在表单上的任何位置调用in(特别是btnToSQL\u单击)。我的评论如下:
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;
}
列表行=新列表();
私有void Form1\u加载(对象发送方、事件参数e)
{
//var rows=new List();//范围有限
var sr=newstreamreader(@“C:\so_test.txt”);
而(!sr.EndOfStream)
{
字符串s=sr.ReadLine();
如果(!String.IsNullOrEmpty(s.Trim()))
{
行。添加(新行);
}
}
高级关闭();
dataGridView1.DataSource=行;
}
对于转换到Excel,这是我发现的最快的方法(尽管它确实使用Office InterOp)。循环遍历DataGridView中的每个单元格,并将其分配给对象数组。然后将整个数组指定给Excel范围。这比单独为每个Excel单元格赋值快得多,因为它只调用一次互操作。请原谅我的错误:
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列名
有关更多信息,请参见“”和“”。签出,因为这指的是使用效果非常好的方法-我能够从数据表中创建我的CSV数据,并在内存中批量加载Excel文件以流式输出。只需几行代码。
Variable csvData是所有csvData的字符串值
using( ExcelPackage pck = new ExcelPackage( ) )
{
//Create the worksheet
ExcelWorksheet ws = pck.Workbook.Worksheets.Add( "Sheet1" );
// set the delimiter
etf.Delimiter = ',';
etf.EOL = "\n";
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( );
}
在这里,我使用DataTable将数据写入excel文件。我认为数据网格视图也与DataTable相同 首先从数据库获取数据:
db.GetData(sqlgetprint);
方法调用的方法是:
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;
}
}
}
之后,在工作表单中为DatabaseConception类创建对象
DataBaseConnection db = new DataBaseConnection();
在按钮单击事件中,您可以编写此代码以写入Excel文件
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!");
}
string sqlgetprint=“选择服务编号、全名、附件编号、操作日期、开启时间、关闭时间、操作时间、按服务编号、操作日期从打印操作订单付款”;
DataTable dtall=db.GetData(sqlgetprint);
SaveFileDialog saveFileDialog1=新建SaveFileDialog();
saveFileDialog1.Filter=“Excel文档(*.xls)|*.xls”;
saveFileDialog1.FileName=“Employee Details.xls”;
if(saveFileDialog1.ShowDialog()==DialogResult.OK)
{
字符串fname=saveFileDialog1.FileName;
StreamWriter wr=新的StreamWriter(fname);
for(int i=0;i
这可能是一种更快的方法
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 { }
}
}
}
最快的方法?或者,第一种方法?Excel和SQL是非常不同的目标,需要不同的解决方案。请您更具体一点,例如,对于Excel,CSV是否足够?然后可以将数据批量导入SQL Server吗?这是一次性练习还是需要重复进行。请参阅此或此sql。对于大型数据集,逐行插入的速度会很慢。我必须承认,我从来没有在中使用过SQLBulkCopy,从性能角度来看,这可能是一个比我在下面发布的更好的解决方案。我想看看这些数字。@GrayFox374它要快得多-没有那么多数字,因为它只是快得多,不需要测量。至少有几个数量级。但是你必须做大量的插入才能需要它。我已将耗时数十分钟的流程减少到几秒钟
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!");
}
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 { }
}
}
}