多年来 COM 对象一直是 Windows 编程的基础,然而随着技术的进步和发展,微软推出了更佳出色的.NET。.NET Framework 提供了一个称为公共语言运行库的运行时环境(CLR),它的托管执行过程,自动的内存管理,以及在版本的控制上都较COM技术有很大的提高。可以预见的是,.NET 平台应用程序将最终取代那些用 COM 开发的应用程序。但不可避免的是,在向.NET过渡时,我们还是需要继续使用现有的COM对象的。CLR不管所用的编程语言是什么,所有.NET 应用程序都共享一组公共类型,这些公共类型允许对象互操作。COM 对象的参数和返回值使用的数据类型有时会与托管代码中的有所不同。“互操作性封送处理”是一个打包过程,在将参数和返回值移动到 COM 对象或从 COM 对象移出时,此过程将这些参数和返回值打包为等价的数据类型。
公共语言运行库通过名为运行库可调用包装 (Runtime Callable Wrapper,RCW) 的代理来公开 COM 对象,如图所示。虽然 RCW 在 .NET 客户端看来是普通的对象,但它的主要功能是封送在 .NET 客户端和 COM 对象之间传递的调用。同时.NET提供Interop 程序集,它用作托管和非托管代码之间的桥梁,将 COM 对象成员映射为等价的 .NET 托管成员。
比如操作Excel,我们最直接的方法就是利用Excel提供的Excel Object Library COM组件,并将包装后的程序集叫做“互操作程序集” (Primary Interop Assembly, PIA)。
l .NET中如何引用COM组件?
方法一,通过IDE来生成PIA:
首先,工程添加引用,选择 COM 选项卡,选择 Excel Object Library xx.0(xx 为版本号,不同版本的 Office ,生成的 PIA 的版本也不同 ) 。如下图所示:
这个引用过程就是RCW的打包过程,.NET自动创建 PIA。当然,你也可以通过.NET提供的工具Tlbimp.exe手动创建PIA。
方法二,手动生成PIA:
首先,启动.NET Framework 2003工具中的控制台:
然后找到当前操作系统 中安装的EXCEL.EXE的位置,输 入:
结果就会在指定目录里生成Excel.dll。当然,你还可以指定生成PIA的命名空间名称和程序集名。
生成之后的dll是经过包装后的.NET的程序集,可以直接引用。(很明显,是使用IDE来得方便,但有当要使用一个未在Windows上注册的COM组件时,就要使用到这个手动工具)。
引用之后就可以通过IDE的Object Browser来查看COM组件里提供的对象和方法了:
using System.IO;
using System.Text;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Excel;
private string SaveExcelChart(string[] data, string filename)
{
Microsoft.Office.Interop.Excel.Application excelapp = null;
Microsoft.Office.Interop.Excel.Workbook wkbook = null;
Microsoft.Office.Interop.Excel.Worksheet wksheet = null;
Microsoft.Office.Interop.Excel.Range r;
Microsoft.Office.Interop.Excel.Chart c;
Microsoft.Office.Interop.Excel.Chart c1;
try
{
object oMissing = System.Reflection.Missing.Value;
excelapp = new Microsoft.Office.Interop.Excel.ApplicationClass();
excelapp.Visible = true;
wkbook = excelapp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
wksheet = (Microsoft.Office.Interop.Excel.Worksheet)wkbook.ActiveSheet;
char[] split = new char[2];
split[0] = ','; split[1] = ';';
string[] type = new string[data.Length];
for (int i = 0; i < data.Length; i++)
{
string[] ss = data[i].Split(split, 256);
type[i] = ss[0];
for (int j = 1; j < ss.Length; j++)
wksheet.Cells[i + 1, j] = ss[j];
}
c = (Microsoft.Office.Interop.Excel.Chart)wkbook.Charts.Add(oMissing, oMissing, oMissing, oMissing);
c.SetSourceData(wksheet.get_Range(wksheet.Cells[1, 1], wksheet.Cells[5, 4]), oMissing);
c.HasDataTable = true;
c.DataTable.ShowLegendKey = true;
for (int i = 0; i < type.Length; i++)
{
//((ChartGroup) c.SeriesCollection(i+1)).ChartType = Excel.XlChartType.xlColumnClustered;
//c.SeriesCollection(i+1).ChartType = Excel.XlChartType.xlColumnClustered;
}
string path = "f:";
try { File.Delete(path + "//新建文件夹" + "//" + filename); }
catch { }
wkbook.SaveAs(path + "//新建文件夹" + "//" + filename, oMissing, "", "", false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 1, false, oMissing, oMissing, true);
try { wkbook.Close(false, null, null); }
catch { }
try { excelapp.Quit(); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(wksheet); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(wkbook); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(excelapp); }
catch { }
c = null;
r = null;
wksheet = null;
wkbook = null;
excelapp = null;
GC.Collect();
FileStream fs = new FileStream(path + "//新建文件夹" + "//" + filename, FileMode.Open);
int count = (int)fs.Length;
byte[] bytesStr1 = new byte[count];
Stream filestream = fs;
filestream.Read(bytesStr1, 0, count);
Response.Clear();
Response.AddHeader("Content-Disposition",
"attachment; filename=" + HttpUtility.UrlEncode(Request.ContentEncoding.GetBytes(filename)));
//Response.AddHeader("Content-Disposition",
// "attachment; filename=" + this.ListBox1.SelectedItem.Text);
Response.AddHeader("Content-Length", bytesStr1.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(bytesStr1);
filestream.Close();
try { File.Delete(path + "//新建文件夹" + "//" + filename); }
catch { }
return path + "//新建文件夹" + "//" + filename;
Response.End();
}
catch (Exception e)
{
try
{
//m_Last_error = e.ToString();
try { wkbook.Close(false, null, null); }
catch { }
try { excelapp.Quit(); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(wksheet); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(wkbook); }
catch { }
try { System.Runtime.InteropServices.Marshal.ReleaseComObject(excelapp); }
catch { }
r = null;
wksheet = null;
wkbook = null;
excelapp = null;
GC.Collect();
}
catch { }
return null;
}
}
protected void Button2_Click(object sender, EventArgs e)
{
string[] graph = new string[6];
graph[0] = "51;季度//部门;一季度,二季度,三季度,四季度";
graph[1] = "4;A部门;2,3,4,4";
graph[2] = "51;B部门;4,6,8,2";
graph[3] = "51;C部门;5,6,7,9";
graph[4] = "51;D部门;4,4,8,8";
graph[5] = "511;E部门;sd,sd,8,8";
SaveExcelChart(graph, "nihao.xls");
}