C# 导出Excel速度慢的问题

GentleCat 2009-03-31 11:12:08
用的是Excel.dll 11.0 com组件

导到自定义的Excel格式,其中会有插入图片之类的操作,

统计了一下,导出一条记录需要1-2秒之间的时间,速度太慢了,

照这速度导一个几千几万条的记录就可以来几局MS了.

不知道是不是用这个组件慢的原因还是我的方法不对,有没有人有比较快速的方法啊?



...全文
2009 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
kid10001 2011-11-21
  • 打赏
  • 举报
回复
public void FilltoExcel(System.Data.DataTable deTemp, string strTitle)
{

GC.Collect();
Random rand = new Random();
Microsoft.Office.Interop.Excel.ApplicationClass oexcel = new ApplicationClass();
if (oexcel == null)
{

// 无法创建Excel对象,可能您的计算机上未安装Excel软件。

MessageBox.Show("无法创建Excel对象,可能您的计算机上未安装Excel软件。");

return;

}

object omissing = System.Reflection.Missing.Value;
oexcel.Workbooks.Add(omissing);
Microsoft.Office.Interop.Excel.Workbook obook = oexcel.Workbooks[1];
Microsoft.Office.Interop.Excel.Worksheet osheet = (Microsoft.Office.Interop.Excel.Worksheet)obook.Sheets[1];
//osheet.Name = "TEST1";
//osheet.Name = strTitle;
Microsoft.Office.Interop.Excel.Range rg;
int i = deTemp.Columns.Count;
long j = deTemp.Rows.Count;
if (j < 65534)
{
#region
char c = 'A';
string[,] datas = new string[j + 1, i];
for (int it = 0; it < i - 1; it++)
{
c++;
}
for (int ig = 0; ig < i; ig++) //写入标题
{

datas[0, ig] = deTemp.Columns[ig].ColumnName;

}
for (int p = 0; p < i; p++)//写入内容
{
for (int q = 0; q < j; q++)
{
datas[q + 1, p] = deTemp.Rows[q][p].ToString();
}
}
string rc = Convert.ToString(c) + Convert.ToString(j + 1);


rg = (Microsoft.Office.Interop.Excel.Range)osheet.get_Range("A1", rc);
rg.Value2 = datas;
#endregion
}
else
{
long pageRows = 60000;//定义每页显示的行数,行数必须小于

int scount = (int)(j / pageRows);

if (scount * pageRows < j)//当总行数不被pageRows整除时,经过四舍五入可能页数不准
{

scount = scount + 1;

}

for (int sc = 1; sc <= scount; sc++)
{

if (sc > 3)
{

object missing = System.Reflection.Missing.Value;

osheet = (Microsoft.Office.Interop.Excel.Worksheet)obook.Sheets.Add(

missing, missing, missing, missing);//添加一个sheet

}

else
{

osheet = (Worksheet)obook.Sheets[sc];//取得sheet1
//osheet.Name = "Test" + (sc+1).ToString();//测试

}

string[,] datas = new string[pageRows + 1, i];



for (int ig = 0; ig < i; ig++) //写入标题
{

datas[0, ig] = deTemp.Columns[ig].ColumnName;

}



int init = int.Parse(((sc - 1) * pageRows).ToString());

int r = 0;

int index = 0;

long result;

if (pageRows * sc >= j)
{

result = j;

}

else
{

result = long.Parse((pageRows * sc).ToString());

}



for (r = init; r < result; r++)
{

index = index + 1;

for (int it = 0; it < i; it++)
{

deTemp.Rows[r][it].ToString();

object obj = deTemp.Rows[r][it];

datas[index, it] = obj == null ? "" : "'" + obj.ToString().Trim();//在obj.ToString()前加单引号是为了防止自动转化格式


}

System.Windows.Forms.Application.DoEvents();

}



Range fchR = osheet.get_Range(osheet.Cells[1, 1], osheet.Cells[index + 1, i]);

fchR.Value2 = datas;



//osheet.Columns.EntireColumn.AutoFit();//列宽自适应。
}
}

obook.SaveAs("C:/" + strTitle + DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + rand.Next(9999) + ".xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlExcel9795, omissing, omissing, omissing, omissing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, omissing, omissing, omissing, omissing, omissing);
oexcel.Workbooks.Close();
oexcel.Quit();
osheet = null;
obook = null;
oexcel = null;
GC.Collect();
hqsss123 2010-08-15
  • 打赏
  • 举报
回复
回复看看。。。。。
swalp 2009-04-01
  • 打赏
  • 举报
回复
你的MSN怎么不上线啊?
ximi82878 2009-04-01
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 tianke3477 的回复:]
一个excel最多也就装几万条记录,多了不行

建议导出csv格式的
[/Quote]

您说的那是2003,存65536行记录,而2007则能存1048576行
zzxap 2009-03-31
  • 打赏
  • 举报
回复
[CODE=C#]

把dataset数据保存到excel
public void CreateExcel(DataSet ds, string FileName)
{
HttpResponse resp;
resp = Page.Response;
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
string colHeaders = "", ls_item = "";
//定义表对象与行对象,同时用DataSet对其值进行初始化
DataTable dt = ds.Tables[0];
DataRow[] myRow = dt.Select();//可以类似dt.Select("id>10")之形式达到数据筛选目的
int i = 0;
int cl = dt.Columns.Count;
//取得数据表各列标题,各标题之间以t分割,最后一个列标题后加回车符
for (i = 0; i < cl; i++)
{
if (i == (cl - 1))//最后一列,加n
{
colHeaders += dt.Columns[i].Caption.ToString() + "\n";
}
else
{
colHeaders += dt.Columns[i].Caption.ToString() + "\t";
}
}
resp.Write(colHeaders);
//向HTTP输出流中写入取得的数据信息
//逐行处理数据 
foreach (DataRow row in myRow)
{
//当前行数据写入HTTP输出流,并且置空ls_item以便下行数据  
for (i = 0; i < cl; i++)
{
if (i == (cl - 1))//最后一列,加n
{
ls_item += row[i].ToString() + "\n";
}
else
{
ls_item += row[i].ToString() + "\t";
}
}
resp.Write(ls_item);
ls_item = "";
}
resp.End();
}



[/CODE]
ximi82878 2009-03-31
  • 打赏
  • 举报
回复
不好意思,没瞧见你要插入图片,如果你用的是b/s的话,可以用MyXLS,很好用,如果是C/S的,那我就不知道了,而且我也很想解决这个问题,如果LZ有了答案,请分享下,谢谢了
v_oneforever 2009-03-31
  • 打赏
  • 举报
回复
二维数组不错。。。不过要这么多条数据的话。可以考虑xml或csv
cpio 2009-03-31
  • 打赏
  • 举报
回复

使用二维数组方式很快

直接把二维数组的值赋给一个Rang

千万不要一个Cell一个Cell的设置值,那会慢死的
wjhgzx 2009-03-31
  • 打赏
  • 举报
回复
你可以试试导出xml或csv格式,会快很多
cpio 2009-03-31
  • 打赏
  • 举报
回复 1

使用二维数组方式很快

直接把二维数组的值赋给一个Rang

千万不要一个Cell一个Cell的设置值,那会慢死的
ximi82878 2009-03-31
  • 打赏
  • 举报
回复
或者你看看这个文章:http://ximi82878.blog.hexun.com/27907174_d.html
我转载的,不过忘了从哪转的了
ximi82878 2009-03-31
  • 打赏
  • 举报
回复
private void SaveAs() //另存新档按钮   导出成Excel
{
DataTable dt = dc.getTable("select * from table");
if (dt.Rows.Count == 0)
{
MessageBox.Show("没有要输出为excel的数据!");
return;
}
SaveFileDialog saveFileDialog = new SaveFileDialog();

saveFileDialog.Filter = "Execl files (*.xls)|*.xls";

saveFileDialog.FilterIndex = 0;

saveFileDialog.RestoreDirectory = true;

saveFileDialog.CreatePrompt = true;

saveFileDialog.Title = "生成Excel";
saveFileDialog.ShowDialog();

Stream myStream;
try
{
myStream = saveFileDialog.OpenFile();
//StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding("gb2312"));

StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));
try
{
string str = "字段1\t字段2\t字段3\t";//表头
sw.WriteLine(str);

for (int i = 0; i < dt.Rows.Count; i++)
{
string tempStr = string.Empty;
tempStr += dt.Rows[i]["a"].ToString() + "\t";
tempStr += dt.Rows[i]["b"].ToString() + "\t";
tempStr += dt.Rows[i]["c"].ToString() + "\t";
sw.WriteLine(tempStr);
}
//MessageBox.Show("导出成功!");
}
catch (Exception e)
{
sw.Close();
MessageBox.Show(e.ToString());
}

finally
{
sw.Close();
myStream.Close();
}
sw.Close();

myStream.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
}


这个速度快,但是缺点是数字的可能会编程科学计数法
booker 2009-03-31
  • 打赏
  • 举报
回复
为什么一定要excel格式呢?lz可以试试导出xml或csv格式,会快很多
老潇 2009-03-31
  • 打赏
  • 举报
回复
怎么会要导这么多数据到EXCEL中,导EXCEL速度本来就不快
wesleyluo 2009-03-31
  • 打赏
  • 举报
回复
这么多记录怎么导入到EXCEL中呢?
难道你导入EXCEL中还有人去看?
记录不多 可以开个线程去做导出动作。可能快点。
jietuan 2009-03-31
  • 打赏
  • 举报
回复
导出excel 是比较慢的,如果你有几千万条记录的excel,你打开都非常慢了,当然excel不可能存储这么多记录。
tianke3477 2009-03-31
  • 打赏
  • 举报
回复
一个excel最多也就装几万条记录,多了不行

建议导出csv格式的
hhlys 2009-03-31
  • 打赏
  • 举报
回复
我公司的系统也是这样,向导出每年的订单记录到Excel时,都要等好久。
如果楼主有了好的解决办法,请分享。
Myth_NiuNiu 2009-03-31
  • 打赏
  • 举报
回复
你要设置的表格如果是固定的话,建议你用word画出格式,让后在程序中作为背景插入好了,然后直接检索数据,就不用考虑格式了
wangchao813 2009-03-31
  • 打赏
  • 举报
回复
up
加载更多回复(6)

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧