一.COM interop
首先我们要了解下何为COM Interop,它是一种服务,可以使.NET Framework对象能够与COM对象通信。Visual Studio .NET 通过引入面向公共语言运行时的托管代码概念,改变了开发人员在创建和运行应用程序的方式。但是这也使得它与基于Windows API和COM对象的编程有了本质的去比。Visual Studio .NET让托管对象和非托管对象协同工作的过程能够称为互用性(interoperability),通常简称为interop。
二.Excel COM命名空间
Microsoft.Office.Interop.Excel
关键点:
保存excel的时候,使用SaveAs()或SaveCopyAs(),都是新建一个文件,然后将其保存起来
Application.Quit(),因为是非托管的,未释放对象,不能保证完全退出进程。1)可以使用KillProcess(),但有可能误终止其它excel进程 2)将Application实例设为null。
具体实现过程:
1.这里,把对excel表格的操作封装在一个叫ExcelOperator的类当中,该类主要具有如下方法。当然还有其它辅助方法,会在具体实现的时候展开。
1 class ExcelOperator
2 {
3 //构造函数,列名为输入参数
4 public ExcelOperator(List<string> _columnHeader)
5 {
6 this.ColumnHeader = _columnHeader;
7 }
8 //打开Excel表头
9 public void OpenExcel();
10 //输入一条行记录值
11 public bool ExportToExcel<T>(IEnumerable<T> _records);
12 //保存并关闭
13 public bool SaveAndClose();
14 }
2.在后台打开excel表格:生成一个新excel进程--->取消确认对话框--->给该进程添加一个workbook--->获取该workbook的worksheet(默认情况下一个新建的workbook有一个worksheet)--->格式化表格。具体代码如下:
1 public void OpenExcel()
2 {
3 excelProcess = new ExcelNameSpace.Application();
4 if (excelProcess == null) throw new Exception("Excel Application is NULL");
5 try
6 {
7 excelProcess.Visible = false;
8 //取消提示,可以直接保存修改后的表格,重要
9 excelProcess.DisplayAlerts = false;
10 excelProcess.AlertBeforeOverwriting = false;
11 workbook = excelProcess.Workbooks.Add();
12 worksheet = workbook.Sheets.get_Item(1);
13 worksheet.Name = FileName;
14 if (worksheet == null) throw new Exception("Excel WorkSheet is NULL");
15 //自动填充表头或其它内容操作
16 InitialWorkSheet();
17 //格式化excel表单
18 FormatWorkSheet();
19 this.flagIsOpen = true;
20 }
21 catch (Exception e)
22 {
23 ......
24 }
25 }大家可以注意到,以上方法还有两个子方法,下面把两个子方法的实现过程简单介绍下:
1 /// <summary>
2 /// 填充excel表头名称
3 /// </summary>
4 virtual protected void InitialWorkSheet()
5 {
6 startRow = 1;
7 startColumn = 1;
8 this.worksheet.Cells[startRow, startColumn].Select();
9 foreach (string header in this.ColumnHeader)
10 {
11 this.excelProcess.ActiveCell.Value = header;
12 this.excelProcess.ActiveCell.Offset[0, 1].Select();
13 }
14 startRow++;
15 }
16
17 /// <summary>
18 /// 格式化表格
19 /// </summary>
20 virtual protected void FormatWorkSheet()
21 {
22 //水平居中
23 this.worksheet.Cells.HorizontalAlignment = ExcelNameSpace.XlVAlign.xlVAlignCenter;
24 //设置列名框颜色
25 var hCell = worksheet.Cells[1, this.ColumnHeader.Count];
26 this.excelProcess.Range["A1", hCell].Interior.ColorIndex = 24;
27 this.excelProcess.Range["A1", hCell].Borders.LineStyle = 1;
28 this.excelProcess.Range["A1", hCell].Borders[ExcelNameSpace.XlBordersIndex.xlEdgeLeft].Weight = ExcelNameSpace.XlBorderWeight.xlThin;
29 ......
30 }在InitialWorkSheet()方法中,可以看到有两个全局变量startRow和startColumn,这两个变量就是用来记录下一个有效输入的位置的。
3.插入行记录,我在这里是想实现批量插入记录的功能。为了方便使用,首先编写了一个Record类,含有一个List<string>成员,用来记录单独一行的记录。然后在传入一个List<Record>的参数。其实简单点,直接传输一个List<string>参数,每次单独加一条记录也可以了。不过为了练习。具体代码如下:
1 /// <summary>
2 /// 利用Record集合添加记录
3 /// </summary>
4 virtual public bool ExportToExcel<T>(IEnumerable<T> _records) where T : Record
5 {
6 try
7 {
8 this.worksheet.Cells[startRow, startColumn].Select();
9 foreach (var record in _records)
10 {
11 this.worksheet.Cells[startRow, startColumn].Select();
12 foreach (var item in record)
13 {
14 this.excelProcess.ActiveCell.Value = item;
15 this.excelProcess.ActiveCell.Offset[0, 1].Select();
16 }
17 startRow++;
18 }
19 return true;
20 }
21 catch(Exception e)
22 {
23 ......
24 }
25 }4.保存并关闭:
1 public bool SaveAndClose()
2 {
//用另存为的方式保存共工作簿,利用GenerateFileURL()产生文件存储路径
3 this.workbook.SaveAs(GenerateFileURL());
4 this.workbook.Close();
5 this.flagIsOpen = false;
//关闭进程
6 this.excelProcess.Quit();
//保证释放非托管对象
7 System.Runtime.InteropServices.Marshal.ReleaseComObject(this.excelProcess);
8 this.excelProcess = null;
9 return true;
10 }5.ExcelOperator类还包含了FileName(文件名)、FilePath(文件存储路径)等属性,请自行进行实现。
















