C#创建、打开、读取、写入、保存Excel,Excel打印输出

摘要:本文介绍了Excel对象、C#中的受管代码和非受管代码,并介绍了COM组件在.NET环境中的使用。
关键词:受管代码;非受管代码;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组件。

参考文献:
[1] 刘洪成 C#高级编程 清华大学出版社 2003.7工作 187~200

 

C#中创建、打开、读取、写入、保存Excel的一般性代码

首先,在引用的COM中找到Microsoft Excel 11.0 Object Library,添加。

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


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;
    }
  }
}

C#如何向EXCEL写入数据

我按着微软技术支持网上的方法写入数据:使用“自动化”功能逐单元格传输数据,代码如下:
// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Add data to cells in the first worksheet in the new workbook.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange.Value = "Last Name";
m_objRange = m_objSheet.get_Range("B1", m_objOpt);
m_objRange.Value = "First Name";
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.Value = "Doe";
m_objRange = m_objSheet.get_Range("B2", m_objOpt);
m_objRange.Value = "John";

// Apply bold to cells A1:B1.
m_objRange = m_objSheet.get_Range("A1", "B1");
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt,
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange,
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

EXCEL表用c#来读

 
 
using System;
using System.IO;
using System.Web;
using System.Web.SessionState;
using NickLee.Common.ExcelLite;


namespace excel1
{
/// <summary>
/// excel 的摘要说明。
/// </summary>
public class excel
{

public excel()
{
//
// TODO: 在此处添加构造函数逻辑
//
fileName = HttpContext.Current.Server.
MapPath( " . " ) + " //temp// " + g + " .xls " ;
}

private Guid g = Guid.NewGuid();
private string fileName;
private ExcelFile ec = new ExcelFile();

/// <summary>
/// 从model中复制模版到temp中
/// </summary>
/// <param name="modelName"> 只需传入模版的名字即可(注意是字符串) </param>
public void copyModel( string modelName)
{
string MName = HttpContext.
Current.Server.MapPath( " . " ) + " //model// " + modelName;
File.Copy(MName,fileName);
}
/// <summary>
/// 设置EXCEL表中的字表个数,字表在这个表中统一命名为“续表”+数字序号
/// </summary>
/// <param name="sheetnum"> 设置字表的个数 </param>
public void setSheets( int sheetnum)
{
ec.LoadXls(fileName);
ExcelWorksheet wsx
= ec.Worksheets[ 0 ];
for ( int y = 0 ;y < sheetnum;y ++ )
{
int num = y + 1 ;
ec.Worksheets.AddCopy(
" 续表 " + num,wsx);
}
}
/// <summary>
/// 给EXCEL表的各个字段设置值
/// </summary>
/// <param name="sheetnum"> 表的序号,注意表是以“0”开始的 </param>
/// <param name="x"> 对应于EXCEL的最左边的数字列 </param>
/// <param name="y"> 对应于EXCEL的最上面的字母列 </param>
/// <param name="values"> 需要写入的值 </param>
public void setValues( int sheetnum, int x, int y, string values)
{
ec.Worksheets[sheetnum].Cells[x,y].Value
= values;;
}
/// <summary>
/// 保存函数,要是文件中有相同的文件就要删除了,
///然后重新写入相同文件名的新EXCEL表
/// </summary>
public void saveFile()
{
if (File.Exists(fileName))
{
File.Delete(fileName);
ec.SaveXls(fileName);
}
else
{
ec.SaveXls(fileName);
}

}
/// <summary>
/// 显示的EXCEL表格
/// </summary>
public void showFile()
{
HttpContext.Current.Response.Charset
=
System.Text.Encoding.Default.WebName;
HttpContext.Current.Response.ContentType
=
" application/vnd.ms-excel " ;
HttpContext.Current.Response.ContentEncoding
=
System.Text.Encoding.UTF8;
HttpContext.Current.Response.WriteFile(fileName);
HttpContext.Current.Response.End();
}


}
}
 
 
小结一些C#读写Excel文件的相关技巧,毕竟Excel打印更为方便和实用,一个是Excel打印输出编码比Word文件打印数据简单些,另一个是Excel本身对数据超强计算处理功能;赶巧最近项目又涉及Excel报表统计打印的问题,所以在把其中的一些技术记录下来与大家一起分析讨论,次篇主要涉及两个方面内容:
1、 读写Excel文件
A、设计Excel模版
B、打开一个目标文件并且读取模版内容
C、目标文件按格式写入需要的数据
D、保存并且输出目标Excel文件
2、 Excel对象资源释放,这个在以前项目没有注意彻底释放使用到Excel对象,对客户计算机资源造成一定浪费,此次得到彻底解决。
 
 
下面是一个Excel打印输出的Demo
1、 创建一个叫DemoExcel的项目
 
2、 引用COM,包括:Microsoft.Excel.x.0.Object.Library,Microsoft.Office.x.0.Object.Library
 
建议安装正版OFFICE,而且版本在11.0以上(Office2003以上),引用以上两个Com后,在项目引用栏发现多了Excel、Microsoft.Office.Core,VBIDE三个 Library.
3、 下面建立一些模拟的数据,此处为街镇信息
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Core;
using System.IO;
using System.Reflection;

namespace DemoExcel
{
    
public partial class Form1 : Form
    
{
        
private  object missing = Missing.Value;
        
private Microsoft.Office.Interop.Excel.Application ExcelRS;
        
private Microsoft.Office.Interop.Excel.Workbook RSbook;
        
private Microsoft.Office.Interop.Excel.Worksheet RSsheet;

        
public Form1()
        
{
            InitializeComponent();
        }


        
private void Form1_Load(object sender, EventArgs e)
        
{
            
// TODO: 这行代码将数据加载到表“dataSet1.STREET”中。您可以根据需要移动或移除它。
            this.sTREETTableAdapter.Fill(this.dataSet1.STREET);

        }


        
private void button1_Click(object sender, EventArgs e)
        
{
            
string OutFilePath = System.Windows.Forms.Application.StartupPath + @" emp.xls";
           
            
string TemplateFilePath = System.Windows.Forms.Application.StartupPath + @"模版.xls";
            PrintInit(TemplateFilePath,OutFilePath);
        }

        //
Excle输出前初始化
        
/// <summary>
        
/// 
        
/// </summary>
        
/// <returns></returns>

        public bool PrintInit(string templetFile, string outputFile)
        
{
            
try
            
{
                
if (templetFile == null)
                
{
                    MessageBox.Show(
"Excel模板文件路径不能为空!");
                    
return false;
                }

                
if (outputFile == null)
                
{
                    MessageBox.Show(
"输出Excel文件路径不能为空!");
                    
return false;
                }

                
//把模版文件templetFile拷贝到目输出文件outputFile中,并且目标文件可以改写
                System.IO.File.Copy(templetFile, outputFile, true);
                
if (this.ExcelRS != null)
                    ExcelRS 
= null;
                
//实例化ExcelRS对象
                ExcelRS = new Microsoft.Office.Interop.Excel.ApplicationClass();
                
//打开目标文件outputFile
                RSbook = ExcelRS.Workbooks.Open(outputFile, missing, missing, missing, missing, missing,
                    missing, missing, missing, missing, missing, missing, missing, missing, missing);
                
//设置第一个工作溥
                RSsheet = (Microsoft.Office.Interop.Excel.Worksheet)RSbook.Sheets.get_Item(1);
                
//激活当前工作溥
                RSsheet.Activate();
                
                
在当前工作溥写入内容
                
for (int i = 0; i < this.dataGridView1.RowCount; i++)
                
{
                    RSsheet.Cells[
3 + i, 1= this.dataGridView1[0, i].Value.ToString();
                    RSsheet.Cells[
3 + i, 2= this.dataGridView1[1, i].Value.ToString();
                    RSsheet.Cells[
3 + i, 3= this.dataGridView1[2, i].Value.ToString();
                }
 
                


                
//保存目标文件
                RSbook.Save();
                
//设置DisplayAlerts
                ExcelRS.DisplayAlerts = false;
                ExcelRS.Visible 
= true;
                
//ExcelRS.DisplayAlerts = true;

                
//释放对象
                RSsheet = null;
                RSbook 
= null;
                ExcelRS 
= null;
                
//释放内存
                GcCollect();
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(ex.ToString());
                
return false;
            }

            
return true;
        }


        
public void GcCollect()
        
{
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

    }

}

特别说明:

a、引用Microsoft.Office.Interop.Excel;using Microsoft.Office.Core;

b、(关键)在程序中特别释放Excel资源的时候既要设置对象为null,又要强制回收内存,这样才能彻底回收资源。

c、引用的Office组建版本是个敏感问题,不同版本之间有细微差别,需要分别处理。

 
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值