现在的位置: 首页 > 综合 > 正文

循序渐进,探寻Excel二次开发.NET源码(3)-ExcelBase类

2013年08月16日 ⁄ 综合 ⁄ 共 19869字 ⁄ 字号 评论关闭

循序渐进,探寻Excel二次开发.NET源码(3)-ExcelBase类
--Excel打开关闭打印预览
作者:长江支流

关键字:.NET、Excel、Excel打开、Excel关闭、Excel打印预览、Excel二次开发、面向对象、设计模式

  

通过前面文章,我们已能做基础准备:

1、如何将各版本Excel(COM类型库) 转换生成.Net公共语言运行库程序集如Interop.Excel.dll
2、如何引用Excel库或已生成的程序集

从今天开始,我们将通过源码共享的方式,开发者将会学习到并亲手实现

3、创建Excel实例
4、打开Excel工作薄工作表和模板
5、增、删、改、插入、定位、重命名工作表
6、获取活动工作表指定范围单元格及带区
7、读、写单元格内容
8、向带区中写内容

9、单元格合并
10、字体及颜色
11、边框及网格线
12、保存、另存
13、打印、预览
14、彻底关闭Excel进程
15、综合应用,通打天下报表

        今天提供一个,用于打开关闭Excel、打印预览Excel、用于读写Excel单元格及带区的通用Excel访问 的程序类。

       

        话不多说,直接上代码。

using System;
using System.Drawing;
using GoldPrinter.ExcelExpert.Exceptions;
using GoldPrinter.ExcelExpert.Constants;

namespace GoldPrinter.ExcelExpert
{
	/// <summary>
	/// 该类主要定义Excel的程序对象,启动Excel并打印及保存。可能依赖于Interop.Excel.dll、Interop.VBIDE.dll及Interop.Microsoft.Office.Core.dll,如果需要,请在您工程的引用处加上。
	///
	/// 作 者:长江支流(周方勇)
	/// Email:MisGoldPrinter@163.com  QQ:150439795
    /// http://www.goldprinter.taobao/
	/// 网 址:www.webmis.com.cn
	/// ★★★★★您可以免费使用此程序,但是请您完整保留此说明,以维护知识产权★★★★★
	/// 
	/// </summary>
	public class ExcelBase
	{
		private Excel.Application _xlApp;							//Excel应用程序
		private Excel.Workbook _xlWorkbook;							//获取Excel工作薄,默认为调用Open([Template])时创建

		//注意要在初始工作薄时实例化并作为工作薄的访问者
		private GoldPrinter.ExcelExpert.WorkSheets _workSheets;		//金质打印通定义的Excel工作表集,用于对工作表集增删改拷贝定位等操作,方便扩展。
		
		private Object oMissing = System.Reflection.Missing.Value;  //实例化对象时缺省参数

		/// <summary>
		/// 当Excel窗口关闭无效时发生。
		/// </summary>
		//public event ExcelWindowDeactivateHandler ExcelWindowDeactivate = null;

		#region 字段_xlApp、_xlWorkbook、_workSheets属性

		/// <summary>
		/// 获取Excel应用程序。
		/// </summary>
		public Excel.Application Application
		{
			get
			{
				return _xlApp;
			}
		}

		/// <summary>
		/// 获取Excel工作薄,默认为调用Open([Template])时创建。
		/// </summary>
		public Excel.Workbook Workbook
		{
			get
			{
				return _xlWorkbook;
			}
		}

		/// <summary>
		/// 获取金质打印通定义的Excel工作薄中工作表集。
		/// </summary>
		public GoldPrinter.ExcelExpert.WorkSheets WorkSheets
		{
			get
			{
				return _workSheets;
			}
		}

		#endregion	


		#region 其它属性

		/// <summary>
		/// 获取或设置Excel窗体可见性,默认不可见。
		/// </summary>
		public bool Visible
		{
			get
			{
				return _xlApp.Visible;
			}
			set
			{
				_xlApp.Visible = value;
			}		
		}


		/// <summary>
		/// Excel窗体的标题栏。
		/// </summary>
		public string Caption
		{
			get
			{
				return _xlApp.Caption;
			}
			set
			{
				_xlApp.Caption = value;
			}
		}


		/// <summary>
		/// 默认值为False,以忽略警告,建议仅运行代码而不显示窗口的情况下使用默认值。如果为 True,则当运行代码时,只要有必要(例如在删除一个工作表时),Excel 就会显示警告消息。
		/// </summary>
		public bool DisplayAlerts
		{
			get
			{
				return _xlApp.DisplayAlerts;
			}
			set
			{
				_xlApp.DisplayAlerts = value;
			}
		}


		/// <summary>
		/// 默认为True,在每次修改后更新显示。但在以编程的方式下会严重影响代码的运行效率,特别是在大范围中通过编程方式填写时,为了使它们运行得更快,如果在编程方式下而不是窗口下建议设置为False。
		/// </summary>
		public bool ScreenUpdating
		{
			get
			{
				return _xlApp.ScreenUpdating;
			}
			set
			{
				if (_xlApp.ScreenUpdating != value)
				{
					_xlApp.ScreenUpdating = value;
				}
			}
		}


		/// <summary>
		/// 获取或设置 Excel 自动放置在新的工作簿中的工作表的数目。可能会写注册表,建议使用Sheets中的方法实现。
		/// </summary>
		public int SheetsInNewWorkbook
		{
			get
			{
				return _xlApp.SheetsInNewWorkbook;
			}
			set
			{
				if (_xlApp.SheetsInNewWorkbook != value)
				{
					_xlApp.SheetsInNewWorkbook = value;
				}
			}
		}


		/// <summary>
		/// 获取或设置 Excel 中默认字体的名称;只有在重新启动 Excel 之后才会生效。可能会写注册表,建议使用Sheets中的方法实现。
		/// </summary>
		public string StandardFont
		{
			get
			{
				return _xlApp.StandardFont;
			}
			set
			{
				if (_xlApp.StandardFont != value)
				{
					_xlApp.StandardFont = value;
				}
			}
		}


		/// <summary>
		/// 获取或设置 Excel 中默认字体的大小;只有在重新启动 Excel 之后才会生效。可能会写注册表,建议使用Sheets中的方法实现。
		/// </summary>
		public double StandardFontSize
		{
			get
			{
				return _xlApp.StandardFontSize;
			}
			set
			{
				if (_xlApp.StandardFontSize != value)
				{
					_xlApp.StandardFontSize = value;
				}
			}
		}

		#endregion	
	

		/// <summary>
		/// 创建类的新实体,并创建一个Excel应用,注意在不使用后应调用Close()方法。
		/// </summary>
		public ExcelBase()
		{
			//创建一个Excel应用,注意每次实例化一个,则Excell进程多一个,在Close()里进行垃圾回收。
			_xlApp = CreateExcelApplication();

			if (_xlApp != null)
			{

				//防用户手动关闭Excel窗口,加了这一个后就总是释放不了Excel进程了
				//this._xlApp.WindowDeactivate+=new Excel.AppEvents_WindowDeactivateEventHandler(_xlApp_WindowDeactivate);

				this.Visible = false;			//默认Excel窗口不可见
				this.DisplayAlerts = false;		//默认在任何情况下不让Excel显示提示信息
				this.Caption = "MIS金质打印通--免费源码下载:www.webmis.com.cn";	//Excel窗体的标题栏
				
				//_xlApp.SheetsInNewWorkbook = 3;		//获取或设置 Excel 自动放置在新的工作簿中的工作表的数目

			}
		}

		#region 支持函数CreateExcelApplication()...

		//创建一个Excel应用
		private Excel.Application CreateExcelApplication()
		{
			Excel.Application excelReturn = null;

			try
			{
				excelReturn = new Excel.ApplicationClass();	//创建一个Excel应用
			}
			catch(System.Exception ex)
			{
				throw new CreateExcelInstanceException("创建Excel类实例时错误,详细信息:" + ex.Message);
			}	
	
			return excelReturn;
		}

		#endregion


		/// <summary>
		/// 显示Excel
		/// </summary>
		public void Show()
		{			
			_xlApp.Visible = true;
		}
		
		/// <summary>
		/// 隐藏Excel窗口
		/// </summary>
		public void Hide()
		{
			_xlApp.Visible = false;		
		}

		
		#region 打开关闭

		/// <summary>
		/// 打开Excel,建立默认的Workbooks,如需显示显示Excel,需要指定Visible为true。
		/// </summary>
		/// <returns></returns>
		public void Open()
		{	
			
			//打开并新建立默认的Excel工作薄
			//Workbooks.Add([template]) As Workbooks

			try
			{				
				//创建并返回Excel工作薄
				//_xlWorkbook = _xlApp.Workbooks.Add(oMissing);
				
				//或者
				_xlApp.Application.Workbooks.Add(oMissing);	//创建并返回Excel工作薄
				_xlWorkbook = _xlApp.Workbooks[1];			//注意索引是从1开始

				//_xlWorkbook的访问者,可以对其工作表集进行操作并方便扩展。
				_workSheets = new WorkSheets(_xlWorkbook);

			}
			catch(System.Exception ex)
			{
				throw new OpenExcelException("打开Excel时错误,详细信息:" + ex.Message);
			}
			

			//			_workBooks.Add();
			//			_xlWorkbook = _workBooks[0];			//注意Excel索引是从1开始,而我用C#写的WorkBooks索引是从0开始
			//
			//			_workSheets = new WorkSheets(_xlWorkbook);
		}

		/// <summary>
		/// 根据现有工作薄模板打开,如果指定的模板不存在,则用默认的空模板
		/// </summary>
		/// <param name="templateFileName">用作模板的工作薄文件名</param>
		public void Open(string templateFileName)
		{	
			if (System.IO.File.Exists(templateFileName))
			{
				//用模板打开
				//Workbooks.Add Template:="C:\tpt.xlt"

				try
				{
					_xlWorkbook = _xlApp.Workbooks.Add(templateFileName);	

					//_xlWorkbook的访问者,可以对其工作表集进行操作并方便扩展。
					_workSheets = new WorkSheets(_xlWorkbook);

				}
				catch(System.Exception ex)
				{
					throw new OpenExcelException("打开Excel时错误,详细信息:" + ex.Message);
				}
			}
			else
			{
				Open();
			}
		}

		/// <summary>
		/// 关闭
		/// </summary>
		public void Close()
		{
			if (_xlApp != null)
			{
				//退出Excel,并返回_xlApp带。
				int generation = QuitExcel();

				//虽然用了_xlApp.Quit(),但由于是COM,并不能清除驻留在内存在的进程,每实例一次Excel则Excell进程多一个。
				//因此用垃圾回收,建议不要用进程的KILL()方法,否则可能会错杀无辜啊:)。
				System.GC.Collect(generation);
			}

			oMissing = null;	
		}
			
		
		//退出Excel,并返回_xlApp带。
		private int QuitExcel()
		{
			#region 实现...

			if (_xlApp != null)
			{
				int generation = 0;

				_xlApp.UserControl = false;

				//如果您将 DisplayAlerts 属性设置为 False,则系统不会提示您保存任何未保存的数据。
				//_xlApp.DisplayAlerts = false;

				if (_xlWorkbook != null)
				{
					//如果将 Workbook 的 Saved 属性设置为 True,则不管您有没有进行更改,Excel 都不会提示保存它
					//_xlWorkbook.Saved = true;
					try
					{
						//						//经过实验,这两句写不写都不会影响进程驻留。
						//						//如果注释掉的话,即使用户手动从界面上关闭了本程序的Excel,也不会影响
						//						_xlWorkbook.Close(oMissing,oMissing,oMissing);
						//						_xlWorkbook = null;

					}
					catch
					{
						//用户手动从界面上关闭了本程序的Excel窗口
					}
				}
				
				//即使用户手动从界面上关闭了,但是Excel.Exe进程仍然存在,用_xlApp.Quit()退出也不会出错,用垃圾回收彻底清除

				if (_xlApp != null)
				{
					_xlApp.Quit();

					System.Runtime.InteropServices.Marshal.ReleaseComObject((object)_xlApp);

					generation = System.GC.GetGeneration(_xlApp);
					_xlApp = null;
		
				}
					
				return generation;  	

			}  
  
			return 0;

			#endregion 实现...
		}


		#endregion

		
		#region PrintPreview()、Print()用Excel打印、预览。
		
		/// <summary>
		/// 用Excel打印预览。
		/// </summary>
		public void PrintPreview()
		{			
			bool blnVisibleTmp = _xlApp.Visible;

			//预览时需要可见,否则不行
			_xlApp.Visible = true;

			try
			{	
				_xlApp.ActiveWorkbook.PrintPreview(oMissing);
			}
			catch{}

			//之后还原为指定的状态
			_xlApp.Visible = blnVisibleTmp;		

		}

		/// <summary>
		/// 用Excel打印。 
		/// </summary>
		public void Print()
		{
			try
			{
				_xlApp.ActiveWorkbook.PrintOut(oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing);	
			}
			catch{}
		}

		#endregion


		#region 保存、另存

		/// <summary>
		/// 另存。如果保存成功,则返回true,否则,如果保存不成功或者如果已存在文件但是选择了不替换也返回false
		/// </summary>
		/// <param name="p_fileName">将要保存的文件名</param>
		/// <param name="p_ReplaceExistsFileName">如果文件存在,则替换</param>
		public bool SaveAs(string p_fileName,bool p_ReplaceExistsFileName)
		{
			bool blnReturn = false;
			if (System.IO.File.Exists(p_fileName))
			{
				if (p_ReplaceExistsFileName)
				{
					try
					{
						System.IO.File.Delete(p_fileName);
						blnReturn = true;
					}
					catch(Exception ex)
					{
						//条件编译,处于Debug时输出错误
#if (DEBUG)
						Console.WriteLine(ex.Message);
#endif
					}
				}
			}

			try
			{		
				//直接保存(即使文件存在,Excel保存时直接替换,不再提示。)
				_xlApp.ActiveWorkbook.SaveCopyAs(p_fileName);
				blnReturn = true;
			}
			catch(Exception exx)
			{
				//条件编译,处于Debug时输出错误
#if (DEBUG)
				Console.WriteLine(exx.Message);
#endif

				blnReturn = false;
			}

			return blnReturn;
		}


		/// <summary>
		/// 保存文件,保存成功返回true
		/// </summary>
		public bool Save()
		{
			try
			{		
				//提示保存文件对话框
				_xlApp.Save(oMissing);
				return true;
			}
			catch(Exception ex)
			{
				//条件编译,处于Debug时输出错误
#if (DEBUG)
				Console.WriteLine(ex.Message);
#endif

				return false;
			}
		}

		#endregion


		/// <summary>
		/// 运行宏,成功返回true,否则返回false。
		/// </summary>
		/// <param name="macroName"></param>
		/// <returns></returns>
		public bool RunMacro(string macroName)
		{
			#region 实现...

			try
			{
				_xlApp.Run(macroName,oMissing,oMissing,
					oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing, 
					oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,
					oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,
					oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing);
				return true;
			}
			catch(Exception ex)
			{
				//条件编译,处于Debug时输出错误
#if (DEBUG)
				Console.WriteLine(ex.Message);
#endif

				return false;		
			}

			#endregion 实现...
		}


		/// <summary>
		/// 取消用户在用户界面内进行的最后一次操作。这个方法不会对代码进行的操作产生影响,
		/// 并且只能撤销单个操作。这项功能并不是十分的强大,但是它确实可以使您在执行您的代码之前撤销用户进行的最后一次操作: 
		/// </summary>
		public void UndoUserLastInput()
		{
			#region 实现...

			try
			{
				_xlApp.Undo();
			}
			catch(Exception ex)
			{
				//条件编译,处于Debug时输出错误
#if (DEBUG)
				Console.WriteLine(ex.Message);
#endif
			}

			#endregion 实现...
		}


		/// <summary>
		/// 返回对活动窗口(顶部的窗口)中当前活动单元格的引用。如果没有活动窗口,此属性会产生一个错误。
		/// </summary>
		public Excel.Range ActiveCell
		{
			get
			{
				return _xlApp.ActiveCell;
			}
		}

		/// <summary>
		/// 获取激活Worksheet的使用行数。
		/// </summary>
		public int GetUsedRangeRows
		{
			get
			{
				//_xlApp.WorkSheets[sheetNumber].UsedRange.Rows.Count; 
				return ((_xlApp.ActiveSheet) as Excel.Worksheet).UsedRange.Rows.Count;
			}
		}

		/// <summary>
		/// 获取激活Worksheet的使用列数。
		/// </summary>
		public int GetUsedRangeCols
		{
			get
			{
				//excel.WorkSheets[sheetNumber].UsedRange.Columns.Count; 
				return ((_xlApp.ActiveSheet) as Excel.Worksheet).UsedRange.Columns.Count;
			}
		}

	
		//核心函数,GetRange(),获取活动工作表指定范围内的单元格
		/*
		public Excel.Range GetRange(int p_rowIndex,int p_colIndex)
		public Excel.Range GetRange(int p_rowIndex,string p_colIndex)
		public Excel.Range GetRange(int p_startRowIndex,int p_startColIndex,int p_endRowIndex,int p_endColIndex)
		public Excel.Range GetRange(int p_startRowIndex,string p_startColIndex,int p_endRowIndex,string p_endColIndex)
		*/
		
		#region GetRange,如Range("B10"),Range("C8:F11"),Range(2,10),Range(2,"A"),Range(3,8,6,11),Range(3,"A",6,"F")

		//*******单个单元格*******//

		/// <summary>
		/// 获取指定单元格或指定范围内的单元格带区,行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="cell">单元格由列字符和行序号组成,如"B10"。列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,行序号为1-65536的数字。</param>
		/// <returns></returns>
		public Excel.Range GetRange(string cell)
		{ 
			//单个	Range("C10").Select		//第10行3列			
			Excel.Range range;
			range = _xlApp.get_Range(cell,oMissing);
						
			return range;
		}


		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合。</param>
		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <returns></returns>
		public Excel.Range GetRange(string p_colIndex,int p_rowIndex)
		{
			//调用重载函数
			return GetRange(p_colIndex + p_rowIndex.ToString());
		}


		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合。</param>
		/// <returns></returns>
		public Excel.Range GetRange(int p_rowIndex,string p_colIndex)
		{
			//调用重载函数
			return GetRange(p_colIndex + p_rowIndex.ToString());
		}


		/// <summary>
		/// 获取指定单元格或指定范围内的单元格带区,行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <returns>返回活动工作薄活动工作表当前指定的带区</returns>
		public Excel.Range GetRange(int p_rowIndex,int p_colIndex)
		{ 
			//单个	Range(10,3).Select		//第10行3列
			return GetRange(p_rowIndex,p_colIndex,p_rowIndex,p_colIndex);
			//return _xlApp.get_Range(_xlApp.Cells[p_startRowIndex,p_startColIndex],oMissing);	//不行
		}


		//*******多个单元格(矩形带区)*******//

		/// <param name="cell1">左上角单元格,单元格由列字符和行序号组成,如"B10"。列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,行序号为1-65536的数字。</param>
		/// <param name="cell2">右下角单元格,单元格由列字符和行序号组成,如"B10"。列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,行序号为1-65536的数字。</param>
		public Excel.Range GetRange(string cell1,string cell2)
		{ 
			//单个	Range("C8:F11").Select		//C8到F11矩形带区
			Excel.Range range;
			range = _xlApp.get_Range(cell1,cell2);
						
			return range;
		}

		/// <param name="p_startRowIndex">指定单元范围起始行索引,从1开始,最大65536。</param>
		/// <param name="p_startColIndex">指定单元范围起始列数字索引或字母组合索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_endRowIndex">指定单元范围结束行索引,索引范围同上。</param>
		/// <param name="p_endColIndex">指定单元范围起始列数字索引或字母组合索引,索引范围同上。</param>
		public Excel.Range GetRange(int p_startRowIndex,int p_startColIndex,int p_endRowIndex,int p_endColIndex)
		{
			Excel.Range range;
			range = _xlApp.get_Range(_xlApp.Cells[p_startRowIndex,p_startColIndex],_xlApp.Cells[p_endRowIndex,p_endColIndex]);
						
			return range;
		}


		/// <param name="p_startRowIndex">指定单元范围起始行索引,从1开始,最大65536。</param>
		/// <param name="p_startColIndex">指定单元范围起始列数字索引或字母组合索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_endRowIndex">指定单元范围结束行索引,索引范围同上。</param>
		/// <param name="p_endColIndex">指定单元范围起始列数字索引或字母组合索引,索引范围同上。</param>
		public Excel.Range GetRange(int p_startRowIndex,string p_startColIndex,int p_endRowIndex,string p_endColIndex)
		{
			//矩形	Range("D8:F11").Select
			Excel.Range range;
			
			range = _xlApp.get_Range(_xlApp.Cells[p_startRowIndex,p_startColIndex],_xlApp.Cells[p_endRowIndex,p_endColIndex]);
			//或
			//range = _xlApp.get_Range(p_startColIndex + p_startRowIndex.ToString(),p_endColIndex + p_endRowIndex.ToString());

			return range;
		}

		#endregion

		#region SetCellText(...),参数对应于Range(...),可以一个单元格也可以带区内的单元格一起设置同样的文本。用Range或它的指定范围作为参数


		/// <summary>
		/// 对指定单元格或指定范围内的单元格带区填充文本。行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="cell">单元格由列字符和行序号组成,如"B10"。列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,行序号为1-65536的数字。</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(string cell,string p_text)
		{
			Excel.Range range;	
			range = GetRange(cell);
			range.Cells.FormulaR1C1 = p_text;
			range = null;
		}
		
		
		/// <summary>
		/// 对指定单元格或指定范围内的单元格带区填充文本。行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(int p_rowIndex,int p_colIndex,string p_text)
		{
			//xlApp.Cells[p_rowIndex,p_colIndex] = p_text;			
			Excel.Range range;	
			range = GetRange(p_rowIndex,p_colIndex);
			range.Cells.FormulaR1C1 = p_text;
			range = null;
		}

		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(int p_rowIndex,string p_colIndex,string p_text)
		{
			Excel.Range range;	
			range = GetRange(p_rowIndex,p_colIndex);
			range.Cells.FormulaR1C1 = p_text;
			range = null;
		}		

		/// <param name="p_startRowIndex">指定单元范围起始行索引,从1开始,最大65536。</param>
		/// <param name="p_startColIndex">指定单元范围起始列数字索引或字母组合索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_endRowIndex">指定单元范围结束行索引,索引范围同上。</param>
		/// <param name="p_endColIndex">指定单元范围起始列数字索引或字母组合索引,索引范围同上。</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(int p_startRowIndex,int p_startColIndex,int p_endRowIndex,int p_endColIndex,string p_text)
		{
			Excel.Range range;	
			range = GetRange(p_startRowIndex,p_startColIndex,p_endRowIndex,p_endColIndex);
			range.Cells.FormulaR1C1 = p_text;
			range = null;
		}

		/// <param name="p_startRowIndex">指定单元范围起始行索引,从1开始,最大65536。</param>
		/// <param name="p_startColIndex">指定单元范围起始列数字索引或字母组合索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		/// <param name="p_endRowIndex">指定单元范围结束行索引,索引范围同上。</param>
		/// <param name="p_endColIndex">指定单元范围起始列数字索引或字母组合索引,索引范围同上。</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(int p_startRowIndex,string p_startColIndex,int p_endRowIndex,string p_endColIndex,string p_text)
		{
			Excel.Range range;	
			range = GetRange(p_startRowIndex,p_startColIndex,p_endRowIndex,p_endColIndex);
			range.Cells.FormulaR1C1 = p_text;
			range = null;
		}

		#endregion

		#region SetCellText(Range)

		/// <summary>
		/// 对指定带区填充文本。
		/// </summary>
		/// <param name="p_Range">带区,可以是一个单元格,也可以是多个单元格的组合</param>
		/// <param name="p_text">指定要填充的文本</param>
		public void SetCellText(Excel.Range p_Range,string p_text)
		{
			p_Range.Cells.FormulaR1C1 = p_text;
		}

		#endregion

		#region GetCellText(p_Range])

		/// <summary>
		/// 获取指定带区的文本。
		/// </summary>
		/// <param name="p_Range">带区,可以是一个单元格,也可以是多个单元格的组合</param>
		public string GetCellText(Excel.Range p_Range)
		{
			string strReturn = "";
			strReturn = p_Range.Text.ToString();	
			return strReturn;	
		}

		#endregion

		#region GetCellText(int p_rowIndex,int p_colIndex[/string p_colIndex]),用Range或它的指定范围作为参数

		/// <summary>
		/// 获取指定单元格内文本,行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="cell">单元格由列字符和行序号组成,如"B10"。列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,行序号为1-65536的数字。</param>
		/// <returns></returns>
		public string GetCellText(string cell)
		{
			string strReturn = "";
			Excel.Range range;

			range = GetRange(cell);

			strReturn = range.Text.ToString();	

			range = null;

			return strReturn;	
		}

		
		/// <summary>
		/// 获取指定单元格内文本,行索引为从1开始的数字,最大65536,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。
		/// </summary>
		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		public string GetCellText(int p_rowIndex,int p_colIndex)
		{
			string strReturn = "";
			Excel.Range range;

			range = GetRange(p_rowIndex,p_colIndex);

			strReturn = range.Text.ToString();	

			range = null;

			return strReturn;	
		}


		/// <param name="p_rowIndex">单元格行索引,从1开始,最大65536。</param>
		/// <param name="p_colIndex">单元格列索引,从1开始,列索引为A~Z、AA~AZ、BA~BZ...HA~HZ、IA~IV的字母及组合,也可以是1-65536数字。</param>
		public string GetCellText(int p_rowIndex,string p_colIndex)
		{
			string strReturn = "";
			Excel.Range range;

			range = GetRange(p_rowIndex,p_colIndex);

			strReturn = range.Text.ToString();	

			range = null;

			return strReturn;	
		}


		#endregion


		/// <summary>
		/// 将DataTable数据源的数据写入到Excel,从第一行第一列开始以符合Excel习惯。
		/// </summary>
		/// <param name="dataSourct">DataTable作不数据源</param>
		/// <param name="startExcelRowIndex">起如行,从第一行第一列开始。</param>
		/// <param name="startExcelColIndex">起始列,从第一行第一列开始。</param>
		public void SetCellText(System.Data.DataTable dataSourct,int startExcelRowIndex,int startExcelColIndex)
		{	
			#region 实现...

			bool blnRefresh = _xlApp.ScreenUpdating;

			if (startExcelRowIndex < 1)
			{
				startExcelRowIndex = 1;
			}

			if (startExcelColIndex < 1)
			{
				startExcelColIndex = 1;
			}

			//提交效率
			_xlApp.ScreenUpdating = false;

			for(int i=0; i < dataSourct.Rows.Count; i++)
			{
				for(int j=0; j < dataSourct.Columns.Count; j++)
				{
					SetCellText(startExcelRowIndex + i , startExcelColIndex + j ,dataSourct.Rows[i][j].ToString());
				}			
			}	

			//刷新屏幕并还原为原始值
			_xlApp.ScreenUpdating = true;
			_xlApp.ScreenUpdating = blnRefresh;

			#endregion 实现...

		}

		/// <summary>
		/// 将DataSet导出到Excel文件。
		/// </summary>
		/// <param name="ds">数据集,注意本方法每个表最多导数据不要大于65536,如果要导更大数据和海量数据,请使用另一专用组件可指定每页sheet大小。</param>
		/// <param name="fileName">文件名,如果已存在则替换。</param>
		/// <param name="caption">Excel的窗口标题。</param>
		public static void Export(System.Data.DataSet ds,string fileName,string caption)
		{

			if (ds == null || ds.Tables.Count == 0)
			{
				return;
			}

			GoldPrinter.ExcelExpert.ExcelBase excel = null;
			
			try
			{
				excel = new GoldPrinter.ExcelExpert.ExcelBase();
			
				excel.Open();

				excel.Caption = caption;

				//清空
				excel.WorkSheets.Clear();

				for(int i = 0 ; i < ds.Tables.Count ; i++)
				{
					string[,] arrTable = null;
					
					arrTable = GetArrFromTable(ds.Tables[i]);
					Excel.Range range = excel.GetRange(1,1,ds.Tables[i].Rows.Count,ds.Tables[i].Columns.Count);
					GoldPrinter.ExcelExpert.RangeVisitor rv = new GoldPrinter.ExcelExpert.RangeVisitor(range);
					rv.SetValue(arrTable);
					excel.WorkSheets.ActiveSheet.Name = ds.Tables[i].TableName;

					excel.WorkSheets.Add().Activate();
				}
				excel.WorkSheets[0].Activate();

				if (System.IO.File.Exists(fileName))
				{
					//throw ex;  //改一下名如fileName1
					//excel.SaveAs(fileName,true);		
					//System.IO.FileInfo fi = new System.IO.FileInfo(fileName);				
				}
				else
				{
					excel.SaveAs(fileName,true);
				}
			}
			catch(Exception ex)
			{
				throw ex;
			}
			finally
			{
				excel.Close();
			}
		}


		//不考虑dt删除了行的情况
		private static string[,] GetArrFromTable(System.Data.DataTable dt)
		{
			string[,] arrTable = new string[dt.Rows.Count,dt.Columns.Count];

			for(int i = 0 ; i < dt.Rows.Count ; i++)
			{
				for(int j = 0 ; j < dt.Columns.Count ; j++)
				{
					arrTable[i,j] = dt.Rows[i][j].ToString();
				}
			}

			return arrTable;
		}

		/*
		//防用户手动关闭Excel窗口,所以提供此事件程序
		private void _xlApp_WindowDeactivate(Excel.Workbook Wb, Excel.Window Wn)
		{
			//当Excel窗口关闭无效时发生。
			if (ExcelWindowDeactivate != null)
			{
				if (_xlApp != null && _xlApp.Visible)
				{					
					ExcelWindowDeactivate(this,new System.EventArgs());
				}
			}
		}
		*/

		/// <summary>
		/// 获取本程序的开发者信息。如果您在开发使用过程中遇到什么困难或有新的想法或建议,请您与作者联系。
		/// 我们的宗旨是:普及.NET教育	推广常用技术	分享实用源码
		/// </summary>
		public void PrintDeveloperInfoToConsole()
		{
			string authorInfo = "\n\r" +
				"作 者:长江支流(周方勇)" + "\n\r" +
				"Email:MisGoldPrinter@163.com  QQ:150439795" + "\n\r" +
				"网 址:www.webmis.com.cn";

			Console.WriteLine(authorInfo);
		}

	}//End class
}//End Namespace

相关源码下载信息请访问:
http://blog.csdn.net/flygoldfish

声明:本文版权为周方勇所有,欢迎转载,请保留完整的内容及出处。
flygoldfish@163.com

抱歉!评论已关闭.