在老师的安排下和几个同学出差去公司主要一起开发一个OA系统,从没方案到一步步地细化模块并分工,一段时间后把一个基本的样板做了出来。虽然说这很不符合开发的规范,过程也挺痛苦的,毕竟什么开发需求的文档都没有,都是口述需求而且不断在变,主要的开发时间都在改来改去的,这确实让人感觉超级不爽。
不过还是有收获的,由于我对asp.net的开发不熟,所以大家首先分配了一个报表开发的工作给我,这个工作确实不难,主要是提供Excel报表的导入导出操作,并对其进行相应的格式检查,数据排序还有一些属性的控制,样式的自动匹配还有数据的统计工作。一开始还是先熟悉一下asp.net的开发流程,毕竟还是有一点php和VC++的开发经验,所以这个很快也就上手,接下来就是直奔主题,如何针对Excel编程。网上收集了一些资料,最后决定采用Microsoft Office自带的COM组件来进行开发,因为感觉这个用起来比较简单。
首先当然是引用usingMicrosoft.Office.Interop.Excel;这个组件里面有四个关键的对象,由大到小分便是Application,Workbook,Worksheet和Range。对于Excel的操作基本上是引用这些对象的方法和属性,而且操作起来简单易懂,下面分别介绍一下每一个对象的一些功能和基本用法,涉及得可能不够全面。
Application对象代表 Excel 应用程序本身。主要的属性都是控制一些全局的属性,比如状态(cursor,EditDirectlyInCell),显示(DisplayAlerts,DisplayFullScreen)和Excel里面一些元素(Workbooks,Sheets)的控制等。其中最关键的就是和Workbooks属性的交互,使我们可以打开,新建工作簿并进行一步的操作。
打开一个现有的工作簿,使用Workbooks集合的Open方法,其中Open的方法提供大量的可选参数,一般情况下我们只要都不需要用到。如下面所示:
Excel.Workbook wb = ThisApplication.Workbooks.Open( filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
若要引用制定的工作簿,可以一工作簿名作为索引,或者按序列也可以,譬如:
Excel.Workbook wb = ThisApplication.Workbooks[1]; // 保存前 wb = ThisApplication.Workbooks["Book1"]; // 保存后 wb = ThisApplication.Workbooks["Book1.xls"];
当然打开了就要关闭拉,所以一个重要的方法就是Quit,当我们操作完之后要执行
ThisApplication.Quit();
如果您将 DisplayAlerts属性设置为False,则系统不会提示您保存任何未保存的数据。此外,如果您将Workbook的Saved属性设置为True,则不管您有没有进行更改,Excel 都不会提示您保存它。
Workbook类代表了 Excel 应用程序内的一个单一的工作簿。这里关键的一个用法是Workbook类提供了一个Sheets属性,它返回一个Sheets对象。这个对象包含Sheet对象集合,其中每个对象既可以是Worksheet对象,也可以是Chart对象。
而且通过Workbook类的BuiltInDocumentProperties属性来使用内置属性,并通过CustomDocumentProperties属性来使用自定义属性。这些属性都返回一个DocumentProperties对象,它是DocumentProperty对象的一个集合。通过集合内的名称或者索引可以使用集合的Item属性来检索特定的属性。 另外还可以使用Workbook 对象的 Styles 属性来与工作簿交互,并对工作簿内的范围应用样式,譬如单元格格式等样式修改。Activate方法激活一个工作簿,并且选择工作簿中的第一个工作表:
ThisApplication.Workbooks[1].Activate;
Close方法关闭一个指定的工作簿,并且(可选)指定是否保存修改。如果工作簿从未保存过,则可以指定一个文件名。下面的代码片段关闭工作簿,并且不保存修改:
ThisApplication.Workbooks(1).Close(false,Type.Missing, Type.Missing);
Protect和Unprotect 方法允许您保护一个工作簿,从而不能添加或者删除工作表,以及再次取消保护工作簿。
ThisApplication.Workbooks[1].Protect(GetPasswordFromUser(), Type.Missing, Type.Missing);
Save方法保存工作簿。如果您还未保存过工作簿,则应该调用SaveAs方法,这样您可以指定一个路径(如果还未保存过工作簿,Excel 会将其保存在当前文件夹中,并以创建工作簿时所给的名称命名):
wb.Save();
SaveAs方法要比Save方法复杂的多。这个方法允许您保存指定的工作簿,并且指定名称、文件格式、密码、访问模式和其他更多的选项(可选)。
ThisApplication.ActiveWorkbook.SaveAs("C:\\MyWorkbook.xml",Excel.XlFileFormat.xlXMLSpreadsheet,Type.Missing, Type.Missing, Type.Missing,Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing);
提示由于保存成某些格式需要一些交互,您也许想在调用 SaveAs 方法之前将 Application.DisplayAlerts 属性设置成 False。例如,在将一个工作表保存成 XML 格式时,Excel 会提醒您不能随工作簿保存 VBA 项目。如果将 DisplayAlerts 属性设置成 False,就不会出现这种警告。
SaveCopyAs 方法将工作簿的一个副本保存到文件中,但不会修改在内存中打开的工作簿。当您想创建工作簿的备份,同时不修改工作簿的位置时,这个方法非常有用:
ThisApplication.ActiveWorkbook.SaveCopyAs("C:\\Test.xls");
警告 交互式地取消任何保存或者复制工作簿的方法会在您的代码中触发一个运行时异常。例如,如果您的过程调用 SaveAs 方法,但是没有禁用 Excel 的提示功能,并且您的用户在提示后单击“取消”,则 Excel 会将运行时错误返回给代码。
Worksheet对象就是对一个工作表进行操作的类,也就是对一个sheet进行各种设置,但是这里有很多方法和前面提到的Application或者Workbook相似或者相同。这里有个比较重要的就是对批注的操作,不过这个功能没有怎么用,所以在这里也不作介绍。对于在Worksheet里面用得比较多的其实就是获取我想要操作的范围,然后调用Range类来对工作表的制定范围进行操作。
获取工作表的范围一般有两种方法,一种是Range range = WorkSheet.get_Range("A1","V1");
其中A1就是第A列第1行,这个相信大家都比较熟悉。第一个参数代表起始地址,第二个参数表示结束地址。就像我们画矩形一样,两个对角的坐标确定了就可以确定一个矩形范围。又或者可以是
Range range = WorkSheet.get_Range("A1:V1",Type,Missing);
若然第一个参数只为一个A1,那么就是针对一个单元格进行操作。另外一种方法是
Range range = WorkSheet.Range[WorkSheet.Cells[1, 7], WorkSheet.Cells[1,8]];
Range对象是我们在 Excel 应用程序中最经常使用的对象;在您可以操作 Excel 内的任何区域之前,您需要将其表示为一个Range对象,然后使用该Range对象的方法和属性。Range类是很重要的,目前为止,本篇文章中的每个示例中在某种程度上都使用了一个Range对象。基本上来说,一个Range对象代表一个单元格、一行、一列、包含一个或者更多单元块(可以是连续的单元格,也可以式不连续的单元格)的选定单元格,甚至是多个工作表上的一组单元格。
当我们获得一个制定的范围之后(也就是我们获取到range),那么我们就可以针对这个对象进行操作。这个对象的属性让我们可以设置字体,行高行宽,颜色,背景还有对齐方式等等我们日常的操作,例子如下
range.ColumnWidth= 40; //设置列宽 range.HorizontalAlignment = XlHAlign.xlHAlignCenter;//水平居中 range.VerticalAlignment = XlHAlign.xlHAlignCenter;//垂直居中 range.Borders.LineStyle = 1;//设置边框 range.Font.Size = 10; //设置字体大小 range.RowHeight = 35; //设置行高 range.Font.Bold = true; //设置字体样式 range.Font.Color = 38; //设置字体颜色 range.Interior.ColorIndex =15; //设置背景颜色
其实使用起来很简单,很多属性的字眼都是一看就知道表达的是什么意思,然后按照提示设置就OK了。当然,还有一些自动调整的函数,譬如可以使用range.EntireColumn.AutoFit();让列宽按照内容进行自动调整,或者AutoFill()进行 自动填充,还有其它方法在此就不作介绍了。
本文所提到的都是在开发过程中用到的一些皮毛,主要是希望对之前的工作来一个总结,也是自己进步的一个纪念。具体可以参考Microsoft主页提供的技术文档,里面有更加详细的介绍和例子。下面附上项目开发中封装的Excel操作:
using System; using System.Text; using System.Globalization; using Microsoft.Office.Interop.Excel; using System.Threading; using System.Collections; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Drawing; namespace uiExceller { /// <summary> /// <para>封装对Excel的操作</para> /// </summary> public class ExcelManager : IDisposable { ApplicationClass App; CultureInfo OriginalCulture; private string _OpenFileName; /// <summary> /// 当前打开的文件名 /// </summary> public string OpenFileName { get { return _OpenFileName; } } /// <summary> /// 返回一个bool值确定当前的文件状态 /// </summary> public bool AnyFileOpen { // After opening a file, we assign its name to _OpenedFileName. After closing, // we clear _OpenedFileName by assigning String.Empty to it. // So a String.Empty value shows no file is open get { return !String.IsNullOrEmpty(_OpenFileName); } } private static ExcelManager instance = null; private static readonly object excellock = new object(); public static ExcelManager Instance { get { lock (excellock) { if (instance == null) { instance = new ExcelManager(); } return instance; } } } /// <summary> /// 默认构造函数. /// </summary> /// <remarks> /// <code> /// using(ExcelManager em = new ExcelManager()) /// { /// // codes using excel file go here, for example: /// em.Open(filename); /// } /// </code> /// </example> /// <b>Note:</b> This Constructor changes current thread's culture to "en-US" and returns it to /// previous state after dispose. /// </remarks>
public ExcelManager() { OriginalCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); //Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); App = new ApplicationClass(); App.DisplayAlerts = false; } #region Functions to work with Files (workbooks) /// <summary> ///新建一个Excel文件. /// </summary> /// <param name="fileName">生成的文件名</param> public void Create(string fileName) { try { Close(); App.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); App.ActiveWorkbook.SaveAs(fileName, XlFileFormat.xlWorkbookNormal, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, XlSaveAsAccessMode.xlNoChange, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing); _OpenFileName = fileName; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Error Creating File '{0}'", fileName), err); } } /// <summary> /// 新建一个工作表. /// </summary> /// <param name="NewSheetName"></param> public void CreateSheet(string NewSheetName) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { ((_Worksheet)App.Worksheets.Add(Type.Missing, App.Worksheets[App.Worksheets.Count], Type.Missing, Type.Missing)).Name = NewSheetName; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not activate sheet '{0}'", NewSheetName), err); } } /// <summary> /// 删除一个工作表. /// </summary> /// <param name=SheetName"></param> public void deleteSheet(string SheetName) { try { _Worksheet Sheet = (_Worksheet)App.Worksheets.get_Item(SheetName); App.DisplayAlerts = false; Sheet.Delete(); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not delete sheet '{0}'", SheetName), err); } } /// <summary> ///打开一个Excel文件. /// </summary> /// <param name="fileName">打开的文件名</param> public void Open(string fileName) { try { Close(); Workbook wk = App.Workbooks.Open(fileName, false, false, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, false, System.Type.Missing, System.Type.Missing, false, System.Type.Missing, System.Type.Missing); _OpenFileName = fileName; if (wk.ReadOnly) throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Readonly")); } catch (Exception err) { if (err.Message == "Readonly") throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "'{0}' 文件已经打开,无法操作,请先手工关闭此文件!", fileName), err); else throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Error Opening File '{0}'", fileName), err); } } /// <summary> /// 关闭打开的文件. /// </summary> public void Close() { try { if(App.Workbooks!=null) App.Workbooks.Close(); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Error Closing File '{0}'", _OpenFileName), err); } } /// <summary> ///保存文件 /// </summary> public void Save() { if (!AnyFileOpen) throw new ExcelException("No file is Open"); App.ActiveWorkbook.Save(); } /// <summary> /// 另存文件 /// </summary> /// <param name="newFileName">新的文件名</param> public void SaveAs(string newFileName) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { if (File.Exists(newFileName)) { File.Delete(newFileName); } App.ActiveWorkbook.SaveAs(newFileName, XlFileFormat.xlWorkbookNormal, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, XlSaveAsAccessMode.xlNoChange, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing); _OpenFileName = newFileName; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not save file as '{0}'", newFileName), err); } } #endregion #region Functions to work with Worksheets /// <summary> ///激活指定的工作表. /// </summary> /// <param name="sheetName">已有的工作表名</param> public void ActivateSheet(string sheetName) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { foreach (_Worksheet wsheet in App.ActiveWorkbook.Sheets) if (String.Compare(wsheet.Name, sheetName, true) == 0) { wsheet.Activate(); return; } throw new ExcelException(String.Format("Can not find sheet '{0}'", sheetName)); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not activate sheet '{0}'", sheetName), err); } } public void SetSheetPrntFormat(string SheetName, string PaperSize, double top, double left, double right, double bottom) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { foreach (_Worksheet wsheet in App.Sheets) { if (String.Compare(wsheet.Name, SheetName, true) == 0) { try { switch (PaperSize) { case "A3": wsheet.PageSetup.PaperSize = XlPaperSize.xlPaperA3; break; case "A4": wsheet.PageSetup.PaperSize = XlPaperSize.xlPaperA4; break; } } catch { throw new ExcelException(String.Format("打印机可能不支持 '{0}' 尺寸的纸张。", PaperSize)); } wsheet.PageSetup.TopMargin = App.InchesToPoints(top / 2.54); wsheet.PageSetup.LeftMargin = App.InchesToPoints(left / 2.54); wsheet.PageSetup.RightMargin = App.InchesToPoints(right / 2.54); wsheet.PageSetup.BottomMargin = App.InchesToPoints(bottom / 2.54); wsheet.PageSetup.Orientation = XlPageOrientation.xlLandscape; //wsheet.PageSetup.CenterHorizontally = true; //wsheet.PageSetup.CenterVertically = true; return; } } throw new ExcelException(String.Format("Can not find sheet '{0}'", SheetName)); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not SetSheetPrntFormat sheet '{0}'"+err.Message, SheetName), err); } } /// <summary> /// 重命名一个工作表. /// </summary> /// <param name="oldName">原来的名字</param> /// <param name="newName">新的名字</param> public void RenameSheet(string oldName, string newName) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { foreach (_Worksheet wsheet in App.Sheets) { if (String.Compare(wsheet.Name, oldName, true) == 0) { wsheet.Name = newName; return; } } throw new ExcelException(String.Format("Can not find sheet '{0}'", oldName)); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not rename sheet '{0}' to '{1}'", oldName, newName), err); } } /// <summary> ///重命名当前的工作表. /// </summary> /// <param name="newName"></param> public void RenameCurrentSheet(string newName) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { (App.ActiveSheet as _Worksheet).Name = newName; } catch (Exception err) { throw new ExcelException( "Can not rename current sheet", err); } } #endregion #region Functions to work with cell and range values public object GetValue(string cellAddress, Category category) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = (App.ActiveSheet as _Worksheet).get_Range(cellAddress, System.Type.Missing); if (category == Category.Numeric) return range.Value2; else return range.Text; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not access values at address '{0}'", cellAddress), err); } } public double? GetNumericValue(string cellAddress) { return (double?)GetValue(cellAddress, Category.Numeric); } public object GetFormattedValue(string cellAddress) { return GetValue(cellAddress, Category.Formatted); } private bool IsWasteCellInMergeArea(Range range) { if (!((bool)range.MergeCells)) return false; Range firstCellInMergeArea = range.MergeArea.Cells[1, 1] as Range; return !(range.Column == firstCellInMergeArea.Column && range.Row == firstCellInMergeArea.Row); } public ArrayList GetRangeValues(string startCellAddress, string endCellAddress, Category category) { if (String.IsNullOrEmpty(startCellAddress)) throw new ArgumentNullException("startCellAddress"); if (String.IsNullOrEmpty(endCellAddress)) throw new ArgumentNullException("endCellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = App.get_Range(startCellAddress, endCellAddress); ArrayList arr = new ArrayList(); foreach (Range r in range) { if (IsWasteCellInMergeArea(r)) continue; if (category == Category.Formatted) arr.Add(r.Text); else arr.Add((double?)r.Value2); } return arr; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not get values of range '{0}:{1}'", startCellAddress, endCellAddress), err); } } public ArrayList GetRangeFormattedValues(string startCellAddress, string endCellAddress) { return GetRangeValues(startCellAddress, endCellAddress, Category.Formatted); } public ArrayList GetRangeNumericValues(string startCellAddress, string endCellAddress) { return GetRangeValues(startCellAddress, endCellAddress, Category.Numeric); } public void SetValue(string cellAddress, object value) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress, System.Type.Missing).Value2 = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", cellAddress), err); } } public void SetHyperLinkValue(string cellAddress,string linkAddress,object value) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = App.get_Range(cellAddress, System.Type.Missing); range.Value2 = value; ((_Worksheet)App.ActiveSheet).Hyperlinks.Add(range,linkAddress); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", cellAddress), err); } } public Range GetRange(string cellAccess1, string cellAccess2) { Range range = null; if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { range= App.get_Range(cellAccess1, cellAccess2); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not copy value of cell '{0}'", cellAccess1), err); } return range; } /// <summary> /// 设置行高 /// </summary> /// <param name="cellFrom1"></param> /// <param name="cellTo1"></param> public void SetRangeRowHeight(string cellFrom1, string cellTo1,object value) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { // _Worksheet worksheet = (_Worksheet)App.ActiveWorkbook.Sheets[index]; App.get_Range(cellFrom1, cellTo1).RowHeight = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not copy value of cell '{0}'", cellFrom1), err); } } /// <summary> /// 复制功能 /// </summary> /// <param name="cellFrom1"></param> /// <param name="cellTo1"></param> public void RangeCopy(string cellFrom1, string cellTo1) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { // _Worksheet worksheet = (_Worksheet)App.ActiveWorkbook.Sheets[index]; App.get_Range(cellFrom1).Copy(App.get_Range(cellTo1, cellTo1)); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not copy value of cell '{0}'", cellFrom1), err); } } /// <summary> /// 带sheet激活的复制功能 /// </summary> /// <param name="cellFrom1"></param> /// <param name="cellFrom2"></param> /// <param name="cellTo1"></param> /// <param name="cellTo2"></param> public void RangeCopy(string cellFrom1, string cellFrom2, string cellTo1, string cellTo2, int index) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { _Worksheet worksheet = (_Worksheet)App.ActiveWorkbook.Sheets[index]; App.get_Range(cellFrom1, cellFrom2).Copy(worksheet.get_Range(cellTo1, cellTo2)); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not copy value of cell '{0}'", cellFrom1), err); } } /// <summary> /// 剪切一行 /// </summary> /// <param name="FromRowIndex">被剪切的行</param> /// <param name="ToRowIndex">粘貼到的行</param> public void CutRow(int FromRowIndex,int ToRowIndex) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = (Range)App.Rows[FromRowIndex]; range.Cut((Range)App.Rows[ToRowIndex]); range = null; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", FromRowIndex), err); } } /// <summary> /// 插入一行 /// </summary> /// <param name="RowIndex"></param> public void InsertRow(int RowIndex) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = (Range)App.Rows[RowIndex]; range.Insert(); range = null; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", RowIndex), err); } } /// <summary> /// 刪除一行 /// </summary> /// <param name="RowIndex"></param> public void DeleteRow(int RowIndex) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range =(Range)App.Rows[RowIndex]; range.Delete(); range = null; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", RowIndex), err); } } /// <summary> /// 排序 /// </summary> /// <param name="cellAddress1">Cell's address (for example "A2")</param> /// <param name="cellAddress2">Cell's address (for example "A2")</param> /// <param name="sortCellAddress1">Cell's sort (for example "A2")</param> /// <param name="sortCellAddress2">Cell's sort (for example "A2")</param> /// <param name="value">Any desired value</param> public void SortRange(string cellAddress1, string cellAddress2, string sortCellAddress1,string sortCellAddress2) { if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range rng = App.get_Range(cellAddress1, cellAddress2); Range rng1 = App.get_Range(sortCellAddress1, sortCellAddress2); rng.Sort(rng1, XlSortOrder.xlDescending, Type.Missing, Type.Missing, XlSortOrder.xlAscending, Type.Missing, XlSortOrder.xlDescending, XlYesNoGuess.xlNo, Type.Missing, Type.Missing, XlSortOrientation.xlSortColumns, XlSortMethod.xlPinYin, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", sortCellAddress1), err); } } /// <summary> /// Sets a cell content by use given color /// </summary> /// <param name="cellAddress">Cell's address (for example "A2")</param> /// <param name="value">Any desired value</param> /// <param name="cl">given color value</param> public void SetValue(string cellAddress, object value, int colorIndex) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = null;// 创建一个空的单元格对象 range = App.get_Range(cellAddress, Missing.Value);// 获取单个单元格 range.Font.ColorIndex = colorIndex; // 设置字体颜色 range.Value2 = value;// 设置单元格的值 } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", cellAddress), err); } } public void SetValue(int rowindex,int colindex, object value) { if (rowindex ==null ||colindex ==null) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.Cells[rowindex,colindex] = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set value of cell '{0}'", rowindex.ToString () +colindex.ToString () ), err); } } /// <summary> ///清理rangge. /// </summary> /// <param name="cellAddress1">Cell's address (for example "A2")</param> /// <param name="cellAddress2">Cell's address (for example "A2")</param> public void RangeClear(string cellAddress1, string cellAddress2) { if (String.IsNullOrEmpty(cellAddress1)) throw new ArgumentNullException("cellAddress1"); if (String.IsNullOrEmpty(cellAddress2)) throw new ArgumentNullException("cellAddress2"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress1, cellAddress2).Clear(); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress1), err); } } /// <summary> /// 设置一个cell的边线. /// </summary> /// <param name="cellAddress1">Cell's address (for example "A2")</param> /// <param name="cellAddress2">Cell's address (for example "A2")</param> /// <param name="value">Any desired value</param> public void SetBorderColor(string cellAddress1,string cellAddress2, object value) { if (String.IsNullOrEmpty(cellAddress1)) throw new ArgumentNullException("cellAddress1"); if (String.IsNullOrEmpty(cellAddress2)) throw new ArgumentNullException("cellAddress2"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress1,cellAddress2).Borders.Color = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress1), err); } } public void SetNumberFormat(string cellAddress, object value) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress, System.Type.Missing).NumberFormat = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress), err); } } public void CellMerge(string cellAddress1,string cellAddress2) { if (String.IsNullOrEmpty(cellAddress1)) throw new ArgumentNullException("cellAddress1"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range=App.get_Range(cellAddress1,cellAddress2); range.Merge(range.MergeCells); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress1), err); } } public void SetColumnAutoFit(string cellAddress) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress, System.Type.Missing).EntireColumn.AutoFit(); } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress), err); } } public void SetColumnWidth(string cellAddress, object value) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress).ColumnWidth = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress), err); } } public void SetFontSize(string cellAddress, object value) { if (String.IsNullOrEmpty(cellAddress)) throw new ArgumentNullException("cellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(cellAddress, System.Type.Missing).Font.Size = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set NumberFormat of cell '{0}'", cellAddress), err); } } public void MergeAndWriteValue(string startCellAddress, string endCellAddress, object value, int colorIndex) { if (String.IsNullOrEmpty(startCellAddress)) throw new ArgumentNullException("startCellAddress"); if (String.IsNullOrEmpty(endCellAddress)) throw new ArgumentNullException("endCellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { Range range = null;// 创建一个空的单元格对象 range = App.get_Range(startCellAddress, endCellAddress);// 获取多个单元格 range.Merge(Missing.Value); // 设置单元格左边框加粗 range.Borders[XlBordersIndex.xlEdgeLeft].Weight = XlBorderWeight.xlThick; // 设置单元格右边框加粗 range.Borders[XlBordersIndex.xlEdgeRight].Weight = XlBorderWeight.xlThick; range.HorizontalAlignment = XlHAlign.xlHAlignCenter;// 设置单元格水平居中 range.VerticalAlignment = XlVAlign.xlVAlignCenter;// 设置单元格垂直居中 range.Borders.LineStyle = 1; // 设置单元格边框 range.Font.Bold = true; // 加粗字体 range.Font.Size = 12; // 设置字体大小 range.Font.ColorIndex = colorIndex; // 设置字体颜色 range.Interior.ColorIndex = 33; // 设置单元格背景色 range.Value2 = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set values of range '{0}:{1}'", startCellAddress, endCellAddress), err); } } public void SetRangeValue(string startCellAddress, string endCellAddress, object value) { if (String.IsNullOrEmpty(startCellAddress)) throw new ArgumentNullException("startCellAddress"); if (String.IsNullOrEmpty(endCellAddress)) throw new ArgumentNullException("endCellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { App.get_Range(startCellAddress, endCellAddress).Value2 = value; } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set values of range '{0}:{1}'", startCellAddress, endCellAddress), err); } } public void SetRangeValues(string startCellAddress, string endCellAddress, IList values) { if (values == null) throw new ArgumentNullException("values"); if (String.IsNullOrEmpty(startCellAddress)) throw new ArgumentNullException("startCellAddress"); if (String.IsNullOrEmpty(endCellAddress)) throw new ArgumentNullException("endCellAddress"); if (!AnyFileOpen) throw new ExcelException("No file is Open"); try { int index = 0; Range range = App.get_Range(startCellAddress, endCellAddress); foreach (Range r in range) { if (index >= values.Count) return; if (IsWasteCellInMergeArea(r)) continue; r.Value2 = values[index]; index++; } } catch (Exception err) { throw new ExcelException( String.Format(CultureInfo.InvariantCulture, "Can not set values of range '{0}:{1}'", startCellAddress, endCellAddress), err); } } #endregion #region IDisposable Members private bool _disposedValue; // To detect redundant calls public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); protected virtual void Dispose(bool disposing) { if (!_disposedValue) if (disposing) { if (App != null) { Close(); //App.Quit(); //App = null; //instance = null; //GC.Collect(); IntPtr t = new IntPtr(App.Hwnd); //得到这个句柄,具体作用是得到这块内存入口 int k = 0; GetWindowThreadProcessId(t, out k); //得到本进程唯一标志k System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); //得到对进程k的引用 p.Kill(); //关闭进程k App=null; instance = null; Thread.CurrentThread.CurrentCulture = OriginalCulture; } } _disposedValue = true; } #endregion } }