循序渐进,探寻Excel二次开发.NET源码(5)-WorkSheets类
--Excel打开关闭打印预览
作者:长江支流
关键字:.NET、Excel、Excel打开、Excel关闭、Excel打印预览、Excel二次开发、面向对象、设计模式
Excel的结构是一个工作薄由多个WorkSheet组成,现在提供WorkSheet的集合类,方便获对Excel工作表的操作,以实现工作表的增删改定位及数据拷贝等操作。
using System;
namespace GoldPrinter.ExcelExpert
{
/// <summary>
/// Excel工作薄的工作表集,作为Workbook的访问者,可以对其工作表集增删改定位等操作,方便扩展。
/// 注意这里索引遵从C#从0开始,而Excel本身是从1开始的。
///
/// 作 者:长江支流(周方勇)
/// Email:MisGoldPrinter@163.com QQ:150439795
/// 网 址:www.webmis.com.cn
/// ★★★★★您可以免费使用此程序,但是请您完整保留此说明,以维护知识产权★★★★★
///
/// </summary>
public class WorkSheets:System.Collections.IEnumerable
{
private Excel.Workbook _xlWorkbook; //Excel工作表集所在的工作薄。
private Object oMissing = System.Reflection.Missing.Value; //实例化对象时缺省参数
#region Application、Workbooks字段属性
/// <summary>
/// 获取Excel应用程序
/// </summary>
public Excel.Application Application
{
get
{
return _xlWorkbook.Application;
}
}
/// <summary>
/// 获取Excel工作表集所在的工作薄。
/// </summary>
public Excel.Workbook Workbook
{
get
{
return _xlWorkbook;
}
}
#endregion
/// <summary>
/// 创建类的新实体,并指定其所依附的工作薄。
/// </summary>
/// <param name="workbook"></param>
public WorkSheets(Excel.Workbook workbook)
{
_xlWorkbook = workbook;
}
/// <summary>
/// 获取工作表数量。
/// </summary>
/// <returns></returns>
public int Count
{
get
{
return GetWorksheetsCount();
}
}
/// <summary>
/// 获取当前激活的工作表
/// </summary>
public Excel.Worksheet ActiveSheet
{
get
{
return (Excel.Worksheet)_xlWorkbook.ActiveSheet;
}
}
/// <summary>
/// 获取集合中指定索引的工作表,没有则返回null。
/// </summary>
public Excel.Worksheet this[string name]
{
get
{
Excel.Worksheet sheetReturn = null;
object obj = null;
try
{
//没有即会出错
obj = _xlWorkbook.Sheets[name];
}
catch{}
if (obj != null)
{
sheetReturn = (Excel.Worksheet)obj;
}
return sheetReturn;
}
}
/// <summary>
/// 获取集合中指定索引的工作表,索引太大会返回最后一个,太小则返回第一个工作表。
/// </summary>
public Excel.Worksheet this[int index]
{
get
{
Excel.Worksheet sheetReturn = null;
int count = GetWorksheetsCount();
int i = index + 1; //注意这里索引从0开始,而Excel本身是从1开始的,所以加1。
if (i < 1)
{
i = 1;
}
else if(i > count)
{
i = count;
}
//取得第i张工作表激活并返回(索引从1开始)
sheetReturn = (Excel.Worksheet)_xlWorkbook.Worksheets[i];
return sheetReturn;
}
}
/// <summary>
/// 强制重新计算所有工作表、特定的范围
/// </summary>
/// <returns></returns>
public void Calculate()
{
foreach(Excel.Worksheet sheet in this)
{
sheet.Calculate();
}
}
/// <summary>
/// 强制重新计算所有工作表、特定的范围
/// </summary>
/// <returns></returns>
public void Calculate(Excel.Worksheet sheet)
{
sheet.Calculate();
}
/// <summary>
/// 强制重新计算所有工作表、特定的范围
/// </summary>
/// <returns></returns>
public void Calculate(Excel.Range range)
{
range.Calculate();
}
/// <summary>
/// 清除工作薄中的工作表,注意因为Excel至少保留一张,所以实际上不是全部清除。
/// </summary>
public void Clear()
{
//工作表数量
int sheetsCount = GetWorksheetsCount();
//删除以往工作表,但是Excel要求至少保留一张,注意Excel索引是从1开始的。
if (sheetsCount > 1)
{
for(int i = 2 ; i <= sheetsCount ; i++)
{
((Excel.Worksheet)_xlWorkbook.Worksheets[2]).Delete();
}
}
}
/// <summary>
/// 激活指定索引的工作表并返回。索引太大会返回最后一个,太小则返回第一个工作表。
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Excel.Worksheet Activate(int index)
{
Excel.Worksheet sheetReturn = null;
sheetReturn = this[index];
sheetReturn.Activate();
return sheetReturn;
}
/// <summary>
/// 激活指定的工作表并返回。不存在指定的表没有则返回null。
/// </summary>
/// <param name="name">工作表名</param>
/// <returns></returns>
public Excel.Worksheet Activate(string name)
{
Excel.Worksheet sheetReturn = null;
sheetReturn = this[name];
if (sheetReturn != null)
{
sheetReturn.Activate();
}
return sheetReturn;
}
/// <summary>
/// 增加并返回一张工作表。
/// </summary>
public Excel.Worksheet Add()
{
return Add(1);
}
/// <summary>
/// 增加指定数量的工作表并返回最后一次增加的工作表。
/// </summary>
/// <param name="count">增加的数量</param>
public Excel.Worksheet Add(int count)
{
return (Excel.Worksheet)_xlWorkbook.Worksheets.Add(oMissing,_xlWorkbook.Worksheets[GetWorksheetsCount()],count,oMissing);
}
/// <summary>
/// 在活动工作薄前面插入并返回一张工作表。
/// </summary>
public Excel.Worksheet Insert()
{
return (Excel.Worksheet)_xlWorkbook.Worksheets.Add(oMissing,oMissing,oMissing,oMissing);
}
/// <summary>
/// 在活动工作薄前面插入并返回一张工作表。
/// </summary>
/// <param name="index">指定要插入的位置</param>
public Excel.Worksheet Insert(int index)
{
return Insert(index,1);
}
/// <summary>
/// 在活动工作薄前面插入指定数量的工作表并返回最后一次插入的工作表。
/// </summary>
/// <param name="index">指定要插入的位置</param>
/// <param name="count">指定要插入的数量</param>
public Excel.Worksheet Insert(int index,int count)
{
int worksheetsCount = GetWorksheetsCount();
if (index >= worksheetsCount)
{
//追加
return Add();
}
else
{
//激活
Activate(index);
return (Excel.Worksheet)_xlWorkbook.Worksheets.Add(oMissing,oMissing,count,oMissing);
}
}
/// <summary>
/// 在指定的工作表前面插入指定数量的工作表并返回最后一次插入的工作表。
/// </summary>
/// <param name="name">指定要插入的位置</param>
/// <param name="count">指定要插入的数量</param>
public Excel.Worksheet Insert(string name,int count)
{
//激活
Activate(name);
return (Excel.Worksheet)_xlWorkbook.Worksheets.Add(oMissing,oMissing,count,oMissing);
}
/// <summary>
/// 删除指定位置的工作表
/// </summary>
/// <param name="index">指定要删除的位置</param>
/// <returns></returns>
public void Remove(int index)
{
int count = GetWorksheetsCount();
int i = index + 1; //注意这里索引从0开始,而Excel本身是从1开始的,所以加1。
//Excel要求至少保留一个工作表
if (count > 1)
{
//在有效范围内
if (i >=1 && i <= count)
{
((Excel.Worksheet)_xlWorkbook.Worksheets[i]).Delete();
}
}
}
/// <summary>
/// 删除指定的工作表
/// </summary>
/// <param name="name">指定要删除的表名</param>
/// <returns></returns>
public void Remove(string name)
{
Excel.Worksheet sheet = null;
sheet = this[name];
if (sheet != null)
{
sheet.Delete();
}
}
/// <summary>
/// 重命名指定的工作表
/// </summary>
/// <param name="oldName">指定要重命名的表名</param>
/// <param name="newName">新的表名</param>
/// <returns></returns>
public Excel.Worksheet Rename(string oldName,string newName)
{
Excel.Worksheet sheet = null;
sheet = this[oldName];
if (sheet != null)
{
sheet.Name = newName;
}
return sheet;
}
/// <summary>
/// 创建一个表的副本,并且将表插入到指定的位置。
/// </summary>
/// <param name="source">原表的位置或名称</param>
/// <param name="dest">目标表插入到的位置或插入到指定名称的表前</param>
public void Copy(int source,int dest)
{
//可以随意指定将新表插入到现有表的前面或者后面。如果不指定位置,Excel 会创建一个新的工作簿来存放这个新表。
//下面的代码片段复制当前工作簿中的第一个表,并且将副本放在第三个表的后面:
//((Excel.Worksheet) ThisWorkbook.Sheets[1]).Copy(Type.Missing, ThisWorkbook.Sheets[3]);.
Excel.Worksheet sheetSource = this[source];
if (sheetSource != null)
{
Excel.Worksheet sheetDesc = this[dest];
int sheetCount = GetWorksheetsCount();
//主要是this[index]取无效的索引为有效的边界值总是返回有效的工作表,所以要判断
if (dest >= sheetCount || sheetDesc == null)
{
//在最后一个工作表后加入
this[source].Copy(Type.Missing,this[GetWorksheetsCount()]);
}
else
{
if (sheetDesc != null)
{
//在指定位置插入
this[source].Copy(this[dest],Type.Missing);
}
}
}
}
/// <summary>
/// 创建一个表的副本,并且将表插入到指定的位置。
/// </summary>
/// <param name="source">原表的位置或名称</param>
/// <param name="dest">目标表插入到的位置或插入到指定名称的表前</param>
public void Copy(string source,string dest)
{
Excel.Worksheet sheetSource = this[source];
if (sheetSource != null)
{
Excel.Worksheet sheetDesc = this[dest];
if (sheetDesc != null)
{
//在指定位置插入
this[source].Copy(this[dest],Type.Missing);
}
else
{
//在最后一个工作表后加入
this[source].Copy(Type.Missing,this[GetWorksheetsCount()]);
}
}
}
/// <summary>
/// 可以用foreach访问每一个工作表。
/// </summary>
/// <returns></returns>
public System.Collections.IEnumerator GetEnumerator()
{
int count = GetWorksheetsCount();
Excel.Worksheet[] arr = new Excel.Worksheet[count];
for(int i = 0 ; i < count ; i++)
{
arr[i] = (Excel.Worksheet)_xlWorkbook.Worksheets[i+1]; //Excel索引从1开始
}
return arr.GetEnumerator();
}
/// <summary>
/// 获取工作表数量
/// </summary>
/// <returns></returns>
private int GetWorksheetsCount()
{
int sheetsCount = _xlWorkbook.Worksheets.Count;
return sheetsCount;
}
/// <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
在接下来的继往篇中,将继续讲RangeVisitor用于读写带区、合并、边框等,而MIS金质打印通专为Excel定义的字体。由于COM组件的Font与.NET的Font有本质不同,我们将在后续提供方法对字体的重要属性外增加下划线样、阴影、背景、上下标等操作。
相关源码下载信息请访问:
http://blog.csdn.net/flygoldfish
声明:本文版权为周方勇所有,欢迎转载,请保留完整的内容及出处。
flygoldfish@163.com