Visual C#的Excel编程

0 引言
Excel是微软公司办公自动化套件中的一个软件,他主要是用来处理电子表格。Excel以其功能强大,界面友好等受到了许多用户的欢迎。在设计应用系统时,对于不同的用户,他们对于打印的需求是不一样的,如果要使得程序中的打印功能适用于每一个用户,可以想象程序设计是十分复杂的。由于Excel表格的功能强大,又由于几乎每一台机器都安装了它,如果把程序处理的结果放到Excel表格中,这样每一个用户就可以根据自己的需要在Excel中定制自己的打印。这样不仅使得程序设计简单,而且又满足了诸多用户的要求,更加实用了。那么用Visual C#如何调用Excel,如何又把数据存放到Excel表格中?本文就来探讨上述问题的解决办法。
1  Excel对象
  微软的Excel对象模型包括了128个不同的对象,从矩形,文本框等简单的对象到透视表,图表等复杂的对象.下面我们简单介绍一下其中最重要,也是用得最多的四个对象。
(1) Application对象。Application对象处于Excel对象层次结构的顶层,表示Excel自身的运行环境。  (2) Workbook对象。Workbook对象直接地处于Application对象的下层,表示一个Excel工作薄文件。
   (3) Worksheet对象。Worksheet对象包含于Workbook对象,表示一个Excel工作表。
   (4) Range对象。Range对象包含于Worksheet对象,表示Excel工作表中的一个或多个单元格。
2  C#中的受管代码和非受管代码
   在.NET公用语言框架内运行的程序为受管代码。受管代码在程序中所有类型都受到严格检查,没有指针,对内存的管理完全由运行系统控制。受控状态下,编写程序更为容易,且更少出错,我们可以花更多的时间在解决实际问题上而不是在计算机语言问题上。相对而言,那些在.NET框架外运行的程序为非受管代码。比如:COM组件、ActiveX组件、Win32 API函数、指针运算等。C#编程中在某些特定情况下,需要运用非受管代码,例如,要利用一个成熟的COM组件,或者调用一个API函数,或者用指针去编写实时/高效程序等。
3  Visual C#中调用Excel的COM组件
   一个.NET组件事实上是一个.NET下的DLL,它包含的不仅是运行程序本身,更重要的是包含这个DLL的描述信息(Meta Data,即元数据),而一个COM组件是用其类库(TLB)储存其描述信息。这些COM组件都是非受管代码,要在Visual C#中使用这些非受管代码的COM组件,就必须把他们转换成受管代码的.NET组件。所以在用Visual C#调用Excel表格之前,必须完成从COM组件的非受管代码到受管代码的类库的转换。
3.1 将Excel的COM组件转换为.NET组件
在项目中打开Add  Reference对话框,选择COM栏,之后在COM列表中找到“Microsoft Excel 9.0 Object Library”(Office 2000),然后将其加入到项目的References中即可。Visual C#.NET会自动产生相应的.NET组件文件,以后即可正常使用。
这个转换形成.NET组件不能单独使用,它不过是以前的COM组件的一个外层包装,在.NET中可以通过这个外层包装去发现原来的COM组件并调用其相应的界面函数。所以它必须与原来的COM组件一起起作用。
3.2 Visual C#打开Excel表格
事实上,在C#中使用一个经转换的COM组件和使用任何一个其它.NET组件完全一样。可以用new关键字创建一个经转换的COM组件,然后再像使用任何一个其它C#对象一样使用这个组件对象。
在转换后的.NET组件中定义了一个命名空间Excel,在此命名空间中封装了一个类Application,这个类和启动Excel表格有非常重要的关系,在Visual C#中,只需要下列三行代码就可以完成打开Excel表格的工作,具体如下:

Excel.Application excel = new Excel.Application ();//引用Excel对象
excel.Application.Workbooks.Add ( true );//引用Excel工作簿
excel.Visible = true ;//使Excel可视

  但此时的Excel表格是一个空的表格,没有任何内容,下面就来介绍如何往Excel表格中输入数据。
3.3 往Excel表格中输入数据
  在命名空间"Excel"中,还定义了一个类"Cell",这个类所代表的就是Excel表格中的一个单元格。通过给"Cell"赋值,从而实现往Excel表格中输入相应的数据,下列代码功能是打开Excel表格,并且往表格输入一些数据。
Excel.Application excel = new Excel.Application () ;
excel.Application.Workbooks.Add ( true ) ;
excel.Cells[ 1 , 1 ] = "First Row First Column" ;
excel.Cells[ 1 , 2 ] = "First Row Second Column" ;
excel.Cells[ 2 , 1 ] = "Second Row First Column" ;
excel.Cells[ 2 , 2 ] = "Second Row Second Column" ;
excel.Visible = true ;
3.4 实例
下面实例在C#中连接Oracle数据库(Name),从表(TableName)中读取数据,并写入Excel.
string cnString="Provider=msdaora.1;Data source=Name; ";
cnString=cnString+"user id=UserName;password=Password";
try
{
OleDbConnection cn=new OleDbConnection (cnString);
cn.Open ();
try
{
string s="select * from Name.TableName";
OleDbCommand cmd=new OleDbCommand (s,cn);
OleDbDataReader dr=cmd.ExecuteReader ();
Excel.Application xlApp = new Excel.Application();
if(xlApp==null){MessageBox.Show ("Can’t open Excel!");return;}
xlApp.Application .Workbooks .Add (true);
int row=2,fieldcount;
fieldcount=dr.FieldCount ;
for(int col=0;col<fieldcount;col++) xlApp.Cells [1,col+1]=dr.GetName(col);
while (dr.Read ())
{
for(int      col=0;col<fieldcount;col++)
xlApp.Cells [row,col+1]=dr.GetValue(col).ToString();
row++;
  }
xlApp.Visible =true;
xlApp=null;
}
catch(Exception ex ){MessageBox.Show (ex.Message );}
finally      {cn.Close();}
}
catch(Exception ex){MessageBox.Show (ex.Message );}
}
}
3.5安装一个使用COM组件的.NET程序
如果要将这样的程序安装运行在另一台机器上,那么除了安装运行程序外,还做三件事。
首先,是安装.NET运行系统。因为任何一个.NET程序都不能离开.NET运行系统去独立运行。
其次,所调用的COM组件必须要安装在目标机器上。本例中大多数目标机器上都装有Microsoft Office的Excel,一般不会有这个问题。但如果是另一个用户自定义的COM组件,那么这个COM组件在运行.NET程序之前必须先安装好。
最后,转换后的.NET组件DLL文件要安装在目标机器上。因为.NET组件不需要在Windows Registry中注册,所以最简单的方法是将.NET组件DLL文件拷贝到运行程序目录下。如果此.NET组件被多个.NET程序共享,可以将其安装在.NET公用组件区中,从而可被任何一个.NET组件使用。只有当一个.NET组件参与了事务处理时,才需要将它注册为一个COM+组件。因为.NET仍然用传统的COM+机制来处理事务的提交、回滚等。

4 小结
   通过以上讨论,我们知道了在C#中,如何使用Excel的COM组件。需要注意的是,Excel对象包含的许多内容我们没有介绍,在使用过程中需要我们不断学习。也使我们了解了在C#中如何使用COM组件。


创建、打开、读取、写入、保存的一般性代码:


using System;
using System.Reflection; // 引用这个才能使用Missing字段

namespace CExcel1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
//创建Application对象
Excel.Application xApp=new Excel.ApplicationClass();

xApp.Visible=true;
//得到WorkBook对象, 可以用两种方式之一: 下面的是打开已有的文件
Excel.Workbook xBook=xApp.Workbooks._Open(@"D:\Sample.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value
,Missing.Value,Missing.Value,Missing.Value,Missing.Value
,Missing.Value,Missing.Value,Missing.Value,Missing.Value);
//xBook=xApp.Workbooks.Add(Missing.Value);//新建文件的代码
//指定要操作的Sheet,两种方式:

Excel.Worksheet xSheet=(Excel.Worksheet)xBook.Sheets[1];
//Excel.Worksheet xSheet=(Excel.Worksheet)xApp.ActiveSheet;

//读取数据,通过Range对象
Excel.Range rng1=xSheet.get_Range("A1",Type.Missing);
Console.WriteLine(rng1.Value2);

//读取,通过Range对象,但使用不同的接口得到Range
Excel.Range rng2=(Excel.Range)xSheet.Cells[3,1];
Console.WriteLine(rng2.Value2);

//写入数据
Excel.Range rng3=xSheet.get_Range("C6",Missing.Value);
rng3.Value2="Hello";
rng3.Interior.ColorIndex=6; //设置Range的背景色

//保存方式一:保存WorkBook
xBook.SaveAs(@"D:\CData.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,
Excel.XlSaveAsAccessMode.xlNoChange,Missing.Value,Missing.Value,Missing.Value,
Missing.Value,Missing.Value);

//保存方式二:保存WorkSheet
xSheet.SaveAs(@"D:\CData2.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value,
Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value);


//保存方式三
xBook.Save();

xSheet=null;
xBook=null;
xApp.Quit(); //这一句是非常重要的,否则Excel对象不能从内存中退出
xApp=null;
}
}
}


创建excel

引入命名空间

using System.Reflection;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;

创建代码:

private void button1_Click(object sender, System.EventArgs e)
        
{
            
object missing = System.Reflection.Missing.Value;             
            Excel.ApplicationClass myExcel 
= new Excel.ApplicationClass();   
  
            Excel._Workbook xBk ;                
//工作薄 
            Excel._Worksheet xSt;      //工作Sheet    
   
            xBk 
= myExcel.Workbooks.Add(true); 

            
for (int  i = 0; i < 5; i ++)
            
{     
                xSt 
= (Excel._Worksheet)xBk.ActiveSheet;   
                xSt.Name 
="chenms_" + i ;   
                myExcel.Cells[
2,2]="chenms";
                
if(i < 4)
                
{
                    myExcel.Sheets.Add(missing,missing,
1,Excel.XlSheetType.xlWorksheet);
                }

            }

            myExcel.Visible 
= true;
            xBk.SaveAs(
@"d:cms.xls",missing,missing, 
                missing,missing,missing,Excel.XlSaveAsAccessMode.xlShared, 
                missing,missing,missing,missing,missing); 
            myExcel.Quit();



        }

第一步:添加引用-->Com-->Microsoft Excel 11.0 Object Library

第二步:在文件最上方加:
using Excel = Microsoft.Office.Interop.Excel;

第三步:编辑下面两个方法

/// <summary>
/// 执行完Excel操作方法后执行资源回收操作,必须与Excel操作的方法分开
/// </summary>
private void ExcelWrite()
{
     try
     {
         ExcelOperation();
     }
     finally
     {
         System.GC.Collect();
     }        
}

/// <summary>
/// Excel操作,只是例子
/// </summary>
private void ExcelOperation()
{
     //
     //定义一个缺少的object对象            
     object oMis = System.Reflection.Missing.Value;

     //
     //定义一个Excel程序对象            
     Excel.ApplicationClass excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();

     //
     //由Execl程序创建一个工作薄对象            
     Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);

     //
     //由工作薄对象创建一个工作表            
     Excel.Worksheet excelWorkSheet = (Excel.Worksheet)excelWorkBook.Worksheets.Add(oMis, oMis, 1, oMis);

     //
     //设置工作的表的名字            
     excelWorkSheet.Name = "测试项目";

     //
     //定义一个Excel区域对象,用于保存选择的区域
     Excel.Range selectRange;

     //
     //设置第1行第1列的值
     ((Excel.Range)excelWorkSheet.Cells[1, 1]).set_Item(1, 1, "日期");

     //
     //设置第1行第2列的值
     ((Excel.Range)excelWorkSheet.Cells[1, 1]).set_Item(1, 2, "时间");

     //
     //选择第2行第2列至第2行第2列,设置值与格式
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[2, 2], excelWorkSheet.Cells[2, 2]);
     selectRange.set_Item(1, 1, "11:30");
     selectRange.NumberFormatLocal = @"h:mm;@";
    
     //
     //选择第3行第2列至第2行第2列,设置值与格式
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[3, 2], excelWorkSheet.Cells[3, 2]);
     selectRange.set_Item(1, 1, "12:30");
     selectRange.NumberFormatLocal = @"h:mm;@";

     //
     //选择第4行第2列至第2行第2列,设置值与格式
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[4, 2], excelWorkSheet.Cells[4, 2]);
     selectRange.set_Item(1, 1, "13:30");
     selectRange.NumberFormatLocal = @"h:mm;@";

     //
     //选择第5行第2列至第2行第2列,设置值与格式
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[5, 2], excelWorkSheet.Cells[5, 2]);
     selectRange.set_Item(1, 1, "14:30");
     selectRange.NumberFormatLocal = @"h:mm;@";

     //
     //选择第6行第2列至第2行第2列,设置值与格式
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[6, 2], excelWorkSheet.Cells[6, 2]);
     selectRange.set_Item(1, 1, "15:30");
     selectRange.NumberFormatLocal = @"h:mm;@";

     //
     //选择第2行第1列至第2行第1列,
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[2, 1], excelWorkSheet.Cells[2, 1]);
     //
     //选择是必须的,因设置了选择区域后并未选中此区域
     selectRange.Select();
    
     //
     //冻结窗体
     excelApp.ActiveWindow.FreezePanes = true;

     //
     //选择第2行第1列至第6行第1列,
     selectRange = excelWorkSheet.get_Range(excelWorkSheet.Cells[2, 1], excelWorkSheet.Cells[6, 1]);            
    
     //
     //合并单元格
     selectRange.Merge(oMis);

     selectRange.EntireColumn.AutoFit(); //全部列自适应宽度
     selectRange.EntireRow.AutoFit();     //全部行自适应高度

     selectRange.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;//水平居中
     selectRange.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; //垂直居中

     //
     //设置单元格的格式
     selectRange.NumberFormatLocal = @"yyyy-m-d;@";
     /*
         NumberFormatLocal = "¥#,##0.00_);[红色](¥#,##0.00)"    //货币       
         NumberFormatLocal = "0.00%"                              //百分比
         NumberFormatLocal = "# ??/??"                            //分数
      * */

     //
     //设置单元格的值
     selectRange.set_Item(1, 1, "2007-02-27");

     //selectRange.ColumnWidth = 50;    //固定宽度
     selectRange.Columns.AutoFit();     //自适应宽度

     selectRange.Borders.LineStyle = BorderStyle.FixedSingle;       //设置边框样式
     selectRange.Borders.Weight = Excel.XlBorderWeight.xlThin;      //边框粗细
     selectRange.Borders.ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic;     //颜色            

     excelWorkBook.Saved = true;      //将工作薄的保存标志置为True

     //捕捉异常,以防止文件为只读或已打开,保存时会出错
     try
     {
         excelWorkBook.SaveCopyAs(@"d:\aa.xls");
     }
     catch(Exception exp)
     {
         MessageBox.Show(exp.Message);
     }

     //Excel程序退出,注意:要在外面释放内存资源
     excelApp.Quit();
}

原文地址:https://www.cnblogs.com/zengwei/p/822590.html