怎么实现大批量数据的datatable导出CSV? 直接在stream里写好,然后直接保存文件,这应该是最好的选择了,当然可以结合线程,提高体验 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 嗯 直接stream保存就OK了 一直这么用 我目标是要导出100W以上的数据,至于导出的时间是跟机器性能相关的,我的电脑10W的数据导出都不行,服务器上到了50W左右的时候就会超时。我的代码如下:private void ExportTxt(System.Data.DataTable dbTab,string FilePath){ int RowCount = dbTab.Rows.Count; int ColCount = dbTab.Columns.Count; string strOut = ""; for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { strOut += dbTab.Rows[i][j].ToString(); strOut += (j < ColCount - 1) ? ",": ""; } strOut += "\n"; } strOut += "\n"; dbTab.TableName = "output"; System.IO.StreamWriter s = System.IO.File.CreateText(FilePath); s.Write(strOut); s.Close();} 多个线程,写多个文件,都完事以后,copy a.csv+b.csv+c.csv r.csv 这里存在一个非常严重的问题:应该使用StringBuffer,而不是string。这个错误的选择,将会导致效率降低几十倍甚至更多!!! public static void Export2Xls(DataTable data, string filename, bool exportHeader = true) { if (System.IO.File.Exists(filename)) System.IO.File.Delete(filename); Excel._Application xlsApp = null; Excel._Workbook xlsBook = null; Excel._Worksheet xstSheet = null; try { xlsApp = new Excel.ApplicationClass(); xlsBook = xlsApp.Workbooks.Add(); xstSheet = (Excel._Worksheet)xlsBook.Worksheets[1]; var buffer = new StringBuilder(); if (exportHeader) { // Excel中列与列之间按照Tab隔开 foreach (DataColumn col in data.Columns) buffer.Append(col.ColumnName + "\t"); buffer.AppendLine(); } foreach (DataRow row in data.Rows) { foreach (DataColumn col in data.Columns) buffer.Append(row[col].ToString() + "\t"); buffer.AppendLine(); } System.Windows.Forms.Clipboard.SetDataObject(""); // 放入剪切板 System.Windows.Forms.Clipboard.SetDataObject(buffer.ToString()); var range = (Excel.Range)xstSheet.Cells[1, 1]; range.Select(); xstSheet.Paste(); // 清空剪切板 System.Windows.Forms.Clipboard.SetDataObject(""); xlsBook.SaveAs(filename); } finally { if (xlsBook != null) xlsBook.Close(); if (xlsApp != null) xlsApp.Quit(); // finally里清空Com对象 Marshal.ReleaseComObject(xlsApp); Marshal.ReleaseComObject(xlsBook); Marshal.ReleaseComObject(xstSheet); xstSheet = null; xlsBook = null; xlsApp = null; } } public static void Export2CSV(DataTable data, string filename, bool exportHeader = true) { if (File.Exists(filename)) File.Delete(filename); var buffer = new StringBuilder(); if (exportHeader) { for (var i = 0; i < data.Columns.Count; i++) { buffer.AppendFormat("\"{0}\"", data.Columns[i].ColumnName); if (i < data.Columns.Count - 1) buffer.Append(","); } buffer.AppendLine(); } for (var i = 0; i < data.Rows.Count; i++) { for (var j = 0; j < data.Columns.Count; j++) { buffer.AppendFormat("\"{0}\"", data.Rows[i][j].ToString()); if (j < data.Columns.Count - 1) buffer.Append(","); } buffer.AppendLine(); } File.WriteAllText(filename, buffer.ToString(), Encoding.Default); }这是我在用的导出Excel和导出CSV函数,测试了Export2Xls,效率:导出17个字段1W~6W条记录,从远程查询数据库、返回结果、创建Excel实例、写入Excel、保存为磁盘文件,整个过程大概要15S,生成的Excel文件(xlsx格式)大小平均2M。这是在自己的笔记本(主频2.5G双核,CPU使用了20%)上测试的。之前使用的方法:1.逐个单元格赋值:呵呵,导出一个文件都要十几分钟,果断抛弃之2.使用粘贴板,直接复制、粘贴到Excel实例,如上。3.有直接写文件流Stream的,理论上应该比方法2更快。 DataTable导出到Excel(.NET 4.0) 问题已解决,最后还是直接循环写入stream private static void ExportCSV(DataTable table, string path) { StreamWriter writer; bool comma = false; int columns = table.Columns.Count; using (writer = new StreamWriter(path, false)) { foreach (DataColumn col in table.Columns) { if (!comma) comma = true; else writer.Write(','); writer.Write(col.ColumnName); } writer.WriteLine(); foreach (DataRow row in table.Rows) { comma = false; for (int c = 0; c < columns; c++) { if (!comma) comma = true; else writer.Write(','); writer.Write(row[c].ToString()); } writer.WriteLine(); } } }100万条数据,每行30列,导出8秒左右;110万条,每行35列,导出9秒左右。有一点我不明白,LZ为什么要把这么大的数据量弄到DataTable里再导出,上面测试的数据所有列都是int类型,生成DataTable后前者占300多M内存,后者500多M,你就不担心把服务器整跨?我想数据应该不会一开始就在DataTable里的吧,这样的话简直就是脱裤子放P。另外再加上字符串拼接,简直就是雪上加霜。 comboBox1_SelectedIndexChanged事件问题 CuteEditor控件放到DetailsView中后有一些按键不能用 c#怎么关闭IE7 如何通过查询在数据绑定时去除重复项? 请问:我要计算学生的成绩,有的是80,有的是80.5分,均分要83.24,小数位不定,怎么办啊? datalist页眉和页脚 CSDN怎么了,连续N天也不加分 关于LISTVIEW中的分页问题 c#里面连接数据库有几种方式?他们有怎样的优缺点 高手请进,如何根据条件改变datagrid中的某行某列的字体严色 如何解析复杂的XML 有什么方法让BindingSource.Filter暂停过滤
private void ExportTxt(System.Data.DataTable dbTab,string FilePath)
{
int RowCount = dbTab.Rows.Count;
int ColCount = dbTab.Columns.Count; string strOut = "";
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColCount; j++)
{
strOut += dbTab.Rows[i][j].ToString();
strOut += (j < ColCount - 1) ? ",": "";
}
strOut += "\n";
}
strOut += "\n";
dbTab.TableName = "output";
System.IO.StreamWriter s = System.IO.File.CreateText(FilePath);
s.Write(strOut);
s.Close();
}
这里存在一个非常严重的问题:
应该使用StringBuffer,而不是string。
这个错误的选择,将会导致效率降低几十倍甚至更多!!! public static void Export2Xls(DataTable data, string filename, bool exportHeader = true)
{
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename); Excel._Application xlsApp = null;
Excel._Workbook xlsBook = null;
Excel._Worksheet xstSheet = null;
try
{
xlsApp = new Excel.ApplicationClass(); xlsBook = xlsApp.Workbooks.Add();
xstSheet = (Excel._Worksheet)xlsBook.Worksheets[1]; var buffer = new StringBuilder();
if (exportHeader)
{
// Excel中列与列之间按照Tab隔开
foreach (DataColumn col in data.Columns)
buffer.Append(col.ColumnName + "\t"); buffer.AppendLine();
}
foreach (DataRow row in data.Rows)
{
foreach (DataColumn col in data.Columns)
buffer.Append(row[col].ToString() + "\t"); buffer.AppendLine();
}
System.Windows.Forms.Clipboard.SetDataObject("");
// 放入剪切板
System.Windows.Forms.Clipboard.SetDataObject(buffer.ToString());
var range = (Excel.Range)xstSheet.Cells[1, 1];
range.Select();
xstSheet.Paste();
// 清空剪切板
System.Windows.Forms.Clipboard.SetDataObject(""); xlsBook.SaveAs(filename);
}
finally
{
if (xlsBook != null)
xlsBook.Close(); if (xlsApp != null)
xlsApp.Quit(); // finally里清空Com对象
Marshal.ReleaseComObject(xlsApp);
Marshal.ReleaseComObject(xlsBook);
Marshal.ReleaseComObject(xstSheet); xstSheet = null;
xlsBook = null;
xlsApp = null;
}
} public static void Export2CSV(DataTable data, string filename, bool exportHeader = true)
{
if (File.Exists(filename))
File.Delete(filename); var buffer = new StringBuilder();
if (exportHeader)
{
for (var i = 0; i < data.Columns.Count; i++)
{
buffer.AppendFormat("\"{0}\"", data.Columns[i].ColumnName);
if (i < data.Columns.Count - 1)
buffer.Append(",");
}
buffer.AppendLine();
} for (var i = 0; i < data.Rows.Count; i++)
{
for (var j = 0; j < data.Columns.Count; j++)
{
buffer.AppendFormat("\"{0}\"", data.Rows[i][j].ToString());
if (j < data.Columns.Count - 1)
buffer.Append(",");
}
buffer.AppendLine();
} File.WriteAllText(filename, buffer.ToString(), Encoding.Default);
}这是我在用的导出Excel和导出CSV函数,测试了Export2Xls,效率:
导出17个字段1W~6W条记录,从远程查询数据库、返回结果、创建Excel实例、写入Excel、保存为磁盘文件,整个过程大概要15S,生成的Excel文件(xlsx格式)大小平均2M。
这是在自己的笔记本(主频2.5G双核,CPU使用了20%)上测试的。之前使用的方法:
1.逐个单元格赋值:呵呵,导出一个文件都要十几分钟,果断抛弃之
2.使用粘贴板,直接复制、粘贴到Excel实例,如上。
3.有直接写文件流Stream的,理论上应该比方法2更快。
private static void ExportCSV(DataTable table, string path)
{
StreamWriter writer;
bool comma = false;
int columns = table.Columns.Count; using (writer = new StreamWriter(path, false))
{
foreach (DataColumn col in table.Columns)
{
if (!comma) comma = true;
else writer.Write(','); writer.Write(col.ColumnName);
}
writer.WriteLine(); foreach (DataRow row in table.Rows)
{
comma = false;
for (int c = 0; c < columns; c++)
{
if (!comma) comma = true;
else writer.Write(','); writer.Write(row[c].ToString());
}
writer.WriteLine();
}
}
}
100万条数据,每行30列,导出8秒左右;110万条,每行35列,导出9秒左右。
有一点我不明白,LZ为什么要把这么大的数据量弄到DataTable里再导出,上面测试的数据所有列都是int类型,生成DataTable后前者占300多M内存,后者500多M,你就不担心把服务器整跨?我想数据应该不会一开始就在DataTable里的吧,这样的话简直就是脱裤子放P。另外再加上字符串拼接,简直就是雪上加霜。