C# 操作excel多个sheet

SK_Aqi 2009-07-27 05:19:20
要写入两个sheet的话,传入参数执行方法:
exportTest(ds.Tables[0].DefaultView, filename, "testsheet1");
exportTest(ds.Tables[0].DefaultView, filename, "testsheet2");
最后相当于只有testsheet2,没有testsheet1了,被覆盖了,
方法如下:
    public void exportTest(DataView dv1, string filename, string sheetname)
{
try
{
Excel.Application appExcel = new Excel.Application();
Excel.Workbook workbookData;
Excel.Worksheet worksheetData;

workbookData = appExcel.Workbooks.Add(Missing.Value);
worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);//添加一个sheet
worksheetData.Name = sheetname;//sheet命名

int rowIndex = 1;
int colIndex = 1;
foreach (DataColumn col in dv1.Table.Columns)
{
worksheetData.get_Range(appExcel.Cells[rowIndex, colIndex], appExcel.Cells[rowIndex, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
worksheetData.get_Range(appExcel.Cells[rowIndex, colIndex], appExcel.Cells[rowIndex, colIndex]).Font.Bold = true;
appExcel.Cells[rowIndex, colIndex++] = col.ColumnName;
}
int drvIndex;
for (drvIndex = 0; drvIndex < dv1.Count; drvIndex++)
{
DataRowView row = dv1[drvIndex];
rowIndex++;
colIndex = 1;
foreach (DataColumn col in dv1.Table.Columns)
{
if (col.DataType == System.Type.GetType("System.DateTime"))
{
if (!"".Equals(row[col.ColumnName].ToString()))
appExcel.Cells[rowIndex, colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("MM/dd/yyyy");
else
appExcel.Cells[rowIndex, colIndex] = "";
}
else if (col.DataType == System.Type.GetType("System.String"))
{
appExcel.Cells[rowIndex, colIndex] = "'" + row[col.ColumnName].ToString();
}
else
{
appExcel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
}
colIndex++;
}
}
Range allDataWithTitleRange = worksheetData.get_Range(appExcel.Cells[1, 1], appExcel.Cells[rowIndex, colIndex - 1]);
allDataWithTitleRange.Select();
allDataWithTitleRange.Columns.AutoFit();
if (true)
{
allDataWithTitleRange.Borders.LineStyle = 1;
}

string absFileName = HttpContext.Current.Server.MapPath(System.IO.Path.Combine("~/Attachment", filename));
workbookData.SaveCopyAs(absFileName);

workbookData.Close(false, null, null);

appExcel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbookData);
System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel);
System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheetData);

workbookData = null;
appExcel = null;
worksheetData = null;
GC.Collect();
}
catch (Exception ex)
{ }
}
...全文
1607 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
dream5788 2009-10-29
  • 打赏
  • 举报
回复
请问不规则EXCEL怎么处理?里面还有图片什么的。可以从表格的单元格颜色上分辨出不同的表格吗?
SK_Aqi 2009-07-28
  • 打赏
  • 举报
回复
大家给个主意啊
SK_Aqi 2009-07-28
  • 打赏
  • 举报
回复
让我哥们解决了,开心散分!
代码如下:
private void DataViewExcelBySheetMultipleDt(DataSet ds, string fileName)
{
try
{
int sheetCount = ds.Tables.Count;
GC.Collect();
Application excel;
_Workbook xBk;
_Worksheet xSt = null;
excel = new ApplicationClass();
xBk = excel.Workbooks.Add(true);

int rowIndex = 0;
int colIndex = 0;
for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++)
{
rowIndex = 1;
colIndex = 1;
xSt = (_Worksheet)xBk.Worksheets.Add(Type.Missing, Type.Missing, 1, Type.Missing);
switch (sheetIndex)
{
case 0:
xSt.Name = "test1";
break;
case 1:
xSt.Name = "test2";
break;
case 2:
xSt.Name = "test3";
break;
case 3:
xSt.Name = "test4";
break;
}
foreach (DataColumn col in ds.Tables[sheetIndex].Columns)
{
xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
xSt.get_Range(excel.Cells[rowIndex, colIndex], excel.Cells[rowIndex, colIndex]).Font.Bold = true;
excel.Cells[rowIndex, colIndex++] = col.ColumnName;
}
foreach (DataRow row in ds.Tables[sheetIndex].Rows)
{
rowIndex++;
colIndex = 1;
foreach (DataColumn col in ds.Tables[sheetIndex].Columns)
{
if (col.DataType == System.Type.GetType("System.DateTime"))
{
if (!"".Equals(row[col.ColumnName].ToString()))
excel.Cells[rowIndex, colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("MM/dd/yyyy");
else
excel.Cells[rowIndex, colIndex] = "";
}
else if (col.DataType == System.Type.GetType("System.String"))
{
excel.Cells[rowIndex, colIndex] = "'" + row[col.ColumnName].ToString();
}
else
{
excel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
}
colIndex++;
}
}
Range allDataWithTitleRange = xSt.get_Range(excel.Cells[1, 1], excel.Cells[rowIndex, colIndex - 1]);
allDataWithTitleRange.Select();
allDataWithTitleRange.Columns.AutoFit();
allDataWithTitleRange.Borders.LineStyle = 1;
}
string exportDir = "~/Attachment/";
string absFileName = HttpContext.Current.Server.MapPath(System.IO.Path.Combine(exportDir, fileName));
xBk.SaveCopyAs(absFileName);
xBk.Close(false, null, null);
excel.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(xBk);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xSt);

xBk = null;
excel = null;
xSt = null;
GC.Collect();
}
catch (Exception ex)
{

}
}

上面方法,首先形成一个多个DataTable的DataSet,
重点还是,1. 生成一个新的xls时,打开方式,总是会提示进程占用,就像楼上说的那样
2. 用不同的sheet时一定要命名
3. 使用传入一个datatable时,总是会重写第一个sheet
谨供大家参考
sknice 2009-07-27
  • 打赏
  • 举报
回复
学习
SK_Aqi 2009-07-27
  • 打赏
  • 举报
回复
好像这个cell不用声明,觉得不是进程的问题,原来导出一个sheet就没有问题,
还有用exportTest(ds.Tables[0].DefaultView, filename, "testsheet2");
再执行也可以重写,不会形成进程未结束的问题,请慕白兄指教啊!
十八道胡同 2009-07-27
  • 打赏
  • 举报
回复
学习,
cpp2017 2009-07-27
  • 打赏
  • 举报
回复
我是举个例子。

如:
appExcel.Cells[rowIndex, colIndex] =

==>

Cell cell = appExcel.Cells[rowIndex, colIndex];
cell==........

cell = null;

检查一下所有代码,否则excel进程无法退出。
my176527627 2009-07-27
  • 打赏
  • 举报
回复
ASP.NET(C#)技术联盟高级群,欢迎工作中的朋友进来一起探讨并解决工作中遇到的问题!一群37078937(已满)二群37078867三群37078820(欢迎上海地区的朋友并爱好Dota的)
严禁加多群,群定期清理长期不发言不讨论的朋友,请多包涵。
SK_Aqi 2009-07-27
  • 打赏
  • 举报
回复
对,我设置了,
你看这里:
workbookData = null;
appExcel = null;
worksheetData = null;
GC.Collect();
cpp2017 2009-07-27
  • 打赏
  • 举报
回复
为有退出。

对于excel的操作,哪怕是一个单元格,也要用变量声明出来,用完后设为null,

如:allDataWithTitleRange 用完后,要设为null
SK_Aqi 2009-07-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cpp2017 的回复:]
对于excel的操作,哪怕是一个单元格,也要用变量声明出来,用完后设为null,
否则进程不能正常退出

[/Quote]
没有退出吗?最后一步还有GC.Collect();垃圾回收呢,
如果真是要退出进程,我应该怎么做?
cpp2017 2009-07-27
  • 打赏
  • 举报
回复
对于excel的操作,哪怕是一个单元格,也要用变量声明出来,用完后设为null,
否则进程不能正常退出
cpp2017 2009-07-27
  • 打赏
  • 举报
回复
你第一次没有完全退出进程。
SK_Aqi 2009-07-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cpp2017 的回复:]
因为你每次new一个excel对象,然后再添加一个表,肯定只有一个了,


先判断一个filename存不存在,如果存在
workbookData    = exce.WorkBooks.Open(.....
这样就可以保存多个sheets了。

[/Quote]

慕白兄,给指教啊!
我现在那部分赋值是这样的,好像还不对
            workbookData = appExcel.Workbooks.Add(Missing.Value);
if ("1".Equals(existfile))
workbookData = appExcel.Workbooks.Open(path, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "t", false, false, 0, true, Type.Missing, Type.Missing);
else
worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);//添加一个sheet
worksheetData.Name = sheetname;//sheet命名

就是打开文件时: 名为"...xls"文档已经打开,不能同时打开同名文件.
SK_Aqi 2009-07-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cpp2017 的回复:]
因为你每次new一个excel对象,然后再添加一个表,肯定只有一个了,


先判断一个filename存不存在,如果存在
workbookData    = exce.WorkBooks.Open(.....
这样就可以保存多个sheets了。

[/Quote]

哦对,我试试
enihs 2009-07-27
  • 打赏
  • 举报
回复
excel在方法体外new出来,你操作的不是同一个excel
cpp2017 2009-07-27
  • 打赏
  • 举报
回复
因为你每次new一个excel对象,然后再添加一个表,肯定只有一个了,


先判断一个filename存不存在,如果存在
workbookData = exce.WorkBooks.Open(.....
这样就可以保存多个sheets了。
十八道胡同 2009-07-27
  • 打赏
  • 举报
回复

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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