学习之路一:关于使用微软的COM组建操作Excel的那些事

  前一阵子心血来潮,研究了一下微软的Excel的COM组件,也就是项目中经常需要的导入和导出Excel的案例

  本人使用的是微软的Excel COM组件,可能大家都认为使用COM组件性能会变的很差,但这只是记录学习的过程,欢迎拍砖!

  好了,废话不说了,直奔主题,Let's go!

 1.添加引用步骤                            

    引用操作Excel的DLL有两种选择

    ①.NET中的DLL      

      

    ②COM组件的选择      

      

      Note:这边会出现版本的问题,随意选择一个就好了!

      ★ 大家注意了,.NET 和COM里面的引用不要全部选择,不然在编码的过程中会出现引用冲突,切忌!

 2.导入Excel                                  

    上面的引用加好后,那么在Using的时候就会有如下的效果:    

      上面的第一种是:using Microsoft.Office.Interop.Excel

                       第二种是:using Excel

    开始操作了,不过接下来讲的一些术语可能不是很准确,不过大概就是那意思!

    接下来我使用的都是第二种引用!    

       ① 首先要创建Excel一系列的对象

    A) 创建Excel应用对象               

1         Excel.Application excelApplication = new Excel.Application(); 
2
3 object missing = Missing.Value;
4
5 //注意上面这句话,后面的代码中用到的missing就是在这边定义的,通俗的讲这个变量相当于一个二进制值

   

    B) 创建Excel中Workbook工作簿对象

 1       //①第一种写法,通过Excel引用对象来指定工作簿对象   
2       Workbooks workBooks = excelApplication.Workbooks;

3
4      //通过excelApplication对象创建工作簿对象
5

6      Workbook workBook = workBooks.Add(XlWBATemplate.xlWBATWorksheet); //这边要加个模版类型枚举
7
8       //如果需要自己定义一个模版,可以指定它的路径,如下:
9
10      //string path = @"C:\Documents and Settings\Administrator\桌面\EXCEL测试模板ã.xls";
11
12      //Workbook workBook = workBooks.Add(path);
 

 --------------------------------------------------------------

       //②第二种写法
       
//★:在创建工作簿对象时还有另外一种写法

3      Workbook workBookOne = excelApplication.Workbooks.Open(templetFile,issing, missing, missing, missing, missing,missing,missing, missing, missing, missing, missing, missing);
5     //也可以这样写:
7     Workbook workBookOne = excelApplication.Workbooks.Add(XlWBATemplate.xlWBATWorksheet);

 ------------------------------------------------------------------------

 Note:在上面的Add和Open方法中的第一个参数其实是一个模版的指定,你可以写模版的路径,如果没有模版可以通过XlWBATemplate.xlWBATWorksheet指定默认的模版!

 模版的作用其实就是固定你Excel顶部的一些样式,这个也可以通过在Excel中自己指定!

 

C) 创建Workbook工作簿中的Sheet对象   

 1        //创建Sheet对象
2

3    Sheets sheets = workBook.Worksheets;
4
5    //创建Sheet工作对象
6   
7       //后面的get_Item(1),是获取Excel中第几个Sheet对象
8
9       //Note:这边Sheet的数量是根据你模版中Sheet的数量而定的,不使用模版默认的Sheet数量为“1” ,如果你强制使用“2”或“3”的Sheet就会出现“Sheet索引值无效”的异常信息
10

11 Worksheet workSheet = (Worksheet)sheets.get_Item(1);
12
13 //下面的代码效果跟上面一样
14
15       //_Worksheet workSheetOne = (_Worksheet)sheets.get_Item(2);
16

17 //Note:这边的带有“_”的Worksheet跟上面的没有下划线效果是一样的,所以在操作Excel时,带有下划线和没有的都属于同种类型,使用效果是一样的!
18
19 //-----------------------------------------------------------
20
21      //★ :还有一种写法:
22   
23      //也可以这样,那么就可以把上面两句话合为一句了
24     //Worksheet workSheetOne = Excel.Worksheet)workBook.Sheets.get_Item(1);

         Note:一开始在创建Sheet对象时,总想着是不是可以多创建几个,试了好多遍,没效果,一直报错,但是当我在指定的模版中定义了几个Sheet后,结果在操作Excel的时候就可以用了!

 

      D) 一切对象准备之后就是数据的填充了

          现在为止我填充数据的方式有两个:          

          ① 循环数据,然后使用遍历单元格来填充数据
 2          DataSet ds = GetData();  //获取数据源
3   int rowsNumber = ds.Tables[0].Rows.Count; //确定行数
4   int columnNumber = ds.Tables[0].Columns.Count; //列数
5
6          //设置sheet名称
7   workSheet.Name = "Sheet1";

8    //这边是如果模版的Sheet数量为三的时候可以这样指定的,只有当指定的模版中有三个Sheet时,才可以指定!
9          //workSheetOne.Name = "Sheet2";
10 //workSheetTwo.Name = "Sheet3";
11
12          //设置标题
13   for (int i = 0; i < ds.Tables[0].Columns.Count; i++)

14 {
15   workSheet.Cells[1, i + 1] = ds.Tables[0].Columns[i].ColumnName;
16   //Note:这边网上的教程都没有加(object)进行转化,但是我不加就出现错误,所以当这边出现错误时,就加一个(object)的强制转换!
17            //注意这边在填充数据的时候你要指定Cell中的两个参数,第一个是行,第二个是列,当标题设置好了后,那你在添加数据的时候行和列的值都应该“+1”
18   Microsoft.Office.Interop.Excel.Range rang = workSheet.get_Range((object)workSheet.Cells[1, i + 1], (object)workSheet.Cells[1, i + 1]);

19          //设置单元格中的数据水平居中
20   rang.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;

21     //这边使用了Microsoft.Office.Interop.Excel的命名空间,跟上面可能搞混了,这是我一开始经常犯得错误!
22 }

23    //填充数据
24 for (int i = 0; i < rowsNumber; i++)

25  {
26   for (int j = 0; j < columnNumber; j++)
27   {
28   workSheet.Cells[i + 2, j + 1] = ds.Tables[0].Rows[i][j];
29   workSheet.Columns.AutoFit();
30   workSheet.get_Range((object)workSheet.Cells[i + 2, j + 1], (object)workSheet.Cells[i + 2, j + 1]).HorizontalAlignment
31 = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
32   //设置字体的颜色
33   workSheet.get_Range((object)workSheet.Cells[i + 2, j + 1], (object)workSheet.Cells[i + 2, j + 1]).Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);

34   }
35 }

           Note:如果在这句话 Microsoft.Office.Interop.Excel.Range rang = workSheet.get_Range((object)workSheet.Cells[1, i + 1], (object)workSheet.Cells[1, i + 1]); 出现了错误,请使用object进行强制转化!          

          总结:设置表格样式和填充数据的时候都会用到“Worksheet”对象中的get_Range的方法,这个方法很重要,其中里面的两个参数的意思为:第一个为起始单元格的位置,第二个是 以终止的单元格的位置,For example :你设置字体颜色,如果你的两个参数都是为“workSheet.Cells[2, 1]”“ workSheet.Cells[2, 1]”那么说明是只有这个单元格设置字体颜色,在文章的最后面我贴出一些表格样式表!

 

          ② 使用二位数组进行批量添加           

 1            int rowsCount = table.Rows.Count;  //行数
2     int columnCount = table.Columns.Count; //列数
3
4            //创建一个二维数组
5            //当你的数据中有数字和字符串的时候尽量是分开进行导入,因为我试过如果都用string方式的导入,会在Excel中出现如下的样式,我感觉就是int和string类型的转化问题!
6

7    string[,] array = new string[rowsCount, columnCount];
8    for (int i = 0; i < rowsCount; i++)
9    {
10    for (int j = 0; j < columnCount; j++)
11    {
12    //赋值=
13    array[i, j] = table.Rows[i][j].ToString();

14    }
15    }
16
17    //
18    workSheet.Name = "Yang Cao Gui";

19    //指定你Excel填充数据开始的位置
20            Range range = (Excel.Range)workSheet.Cells[1, 1];

21           //指定结束的位置,如果开始的位置为Cell[2,2],那么就要加上行和列都要加上1
22           //如:range.get_Resize(rowsCount+1, columnCount+1)
23            range = range.get_Resize(rowsCount, columnCount);

24    range.Value = array;

             总结:使用二维数组进行数据添加比较简便,代码很简洁! 

       

      E) 保存Excel

        保存代码比较简单        

1         //保存
2  string homePath = @"C:\Documents and Settings\Administrator\桌面\yang.xls";

3 workBook.SaveAs(homePath, missing, missing, missing, missing, missing, XlSaveAsAccessMode.xlNoChange,missing, missing, missing, missing, missing);         
        Note:注意SaveAs的一些参数设置,就是前面定义的missing变量!
 
    F)最后清除所有Excel进程      

      Note:一开始当创建Excel进程时到保存结束后,Excel进程都会存在,不会消失,所以我们在最后应该手动清除它们!,不过当多个用户同时操作时,就会发生并发错误,也就是说我们导出Excel后杀掉进程而其它用户正在导出,那么其它用户就会导出失败的情况!  

 1          //释放进程
2          //主要有三个参数Excel应用进程,Workbook工作簿进程,Worksheet工作表进程
3          //不过就只有Excel应用进程使用了,其它的两个好像没有作用!
4     public void DisposeExcel(Excel.Worksheet workSheet, Excel.Workbook workBook, Excel.Application excelApp)

5     {
6     try
7     {
8     excelApp.Quit();
9     GC.Collect(); //强制进行GC垃圾回收
10     }

11     catch (Exception ex)
12     {
13     //Response.Write(ex.Message);
14     }

15     finally
16     {
17     //杀掉Excel全部进程,说实话不是最好的解决办法,但是我想我会努力找到办法解决它,这步很重要对于使用微软的DLL!
18     foreach (Process process in Process.GetProcessesByName("Excel"))

19     {
20     process.Kill();
21     }
22   } 

  3.导出Excel表                             

    Note:主要的原理就是把Excel看做为OLEDB数据,对它进行连接,查询等处理,不过这里面应该要注意很多细节,下面就来一一细看:    

           ① 连接数据库      

1       //使用命名空间 using System.Data.OleDb
2       // filePathOne为你Excel表的路径,注意一些关键术语,Provider要注意它的单词拼写!
3 string conn = " Provider = Microsoft.Jet.OLEDB.4.0;Data Source =" + filePathOne + ";Extended Properties=Excel 8.0";

4 OleDbConnection objcon = new OleDbConnection(conn);
5 objcon.Open(); 

         Note:filePathOne → 指的是你Excel的路径!

         Note:如果Excel的版本是2007以上的,需要更换连接字符串,切忌,如下: 

1      "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+ path +";Extended Properties=Excel 12.0;"; 

     

    ② 确定Excel中Sheet的架构信息    

      下面就是重点,花了好长时间才搞定的

      一开始是按照网上写的,总是出现“数据库搜索引擎未找到对象,请确认拼写是否正确”这样的错误,真烦人!      

1       // System.Data.DataTable dt =objcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,null);
2       //一开始是这样写,总是报上面的错误,两天时间一直被这个问题困扰着,最后通过MSDN上面的一个列子给解决了!
3 //正确代码:

4 //首要建立一个object数组,这有可能是个规定
5 object[] my = { null, null, null, "TABLE" }; //这句话必须要写,大家如果有其它方案可以告诉我。

6 System.Data.DataTable dt = objcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,my);

      Note:大家有必要通过GridView来查看上面Table中的信息,一看就会知道其中的奥妙了!

 

    ③查找数据      

1     //这是指定我要查询的Excel中Sheet的名称
2     //这个很重要,只有正确指定了才能查询数据
3 string name = dt.Rows[0][2].ToString().Trim();

4 //注意加中括号 → “[]”
5 string Sql = "select * from [" + name + "]";

6 OleDbDataAdapter mycommand = new OleDbDataAdapter(Sql, objcon);
7 DataSet ds = new DataSet();
8 mycommand.Fill(ds);
9 objcon.Close();

      Note:上面变量name就是获取你指定的Excel中的Sheet名称,因为它的名称在表中的位置是固定,所以可以直接查出来!

      最后Excel表中的数据就全部保存到Table中了!

      

    ④全部代码    

 1      public System.Data.DataTable UploadExcel(string filePath)
2 {
3 string filePathOne = @"C:\Documents and Settings\Administrator\桌面\TnT_UserMaintenance_Test-Specifications.xls";
4 string conn = " Provider = Microsoft.Jet.OLEDB.4.0;Data Source =" + filePathOne + ";Extended Properties=Excel 8.0";
5 OleDbConnection objcon = new OleDbConnection(conn);
6 objcon.Open();
7 object[] my = { null, null, null, "TABLE" };
8 System.Data.DataTable dt = objcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, my);
9 string name = dt.Rows[0][2].ToString().Trim();
10 string Sql = "select * from [" + name + "]";
11 OleDbDataAdapter mycommand = new OleDbDataAdapter(Sql, objcon);
12 DataSet ds = new DataSet();
13 mycommand.Fill(ds);
14 objcon.Close();
15 return ds.Tables[0];
16 }

    总结:这种导入Excel的方法比较简单,如果自己手打我相信遇到的问题还真是不少,其中你要对System.Data.DataTable dt = objcon.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, my); 中架构信息的理解,你可以使用GridView来查看架构信息,那么对于理解是很方便的!如下图:    

        

    这样你就能很好的把握Sheet中的表名,其实都是有规律的,基本都可以通过dt.Rows[0][2]这样来读取,因为Sheet名都是在第三列中,也就是索引的“2”,唯一变的就是行数索引的变化,这主要是针对有多个Sheet的时候才有的情况,基本都是dt.Rows[0][2]来读取第一个Sheet名称!

    当然当你想导入的Excel中有多个Sheet对象时,这时查看架构信息是很有帮助的,以免出错!

 

 3.一些对表格样式操作的方法                       

    没有深入研究,想深入了解可以网上找找    

   View Code
 1 1、 显示当前窗口:ExcelApp.Visible := True;
2 2、 更改 Excel 标题栏:ExcelApp.Caption := '标题内容';
3 3、 添加新工作簿:ExcelApp.WorkBooks.Add;
4 4、 设置第2个工作表为活动工作表:ExcelApp.WorkSheets[2].Activate;
5 5、 给单元格赋值:ExcelApp.Cells[1,1].Value := '第一行第一列';
6 6、 设置指定列的宽度(单位:字符个数),以第一列为例:
7 ExcelApp.ActiveSheet.Columns[1].ColumnsWidth := 5;
8 7、 设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例:
9 ExcelApp.ActiveSheet.Rows[2].RowHeight := 1/0.035; // 1厘米
10 8、文字水平居中:Excelid.worksheets[1].Rows[1].HorizontalAlignment := $FFFFEFF4;

11 文字垂直居中:Excelid.worksheets[1].Rows[1].VerticalAlignment := $FFFFEFF4;
12 9、 插入一行或一列:a. ExcelApp.ActiveSheet.Rows[2].Insert;
13 b. ExcelApp.ActiveSheet.Columns[1].Insert;
14 10、 删除一行或一列:a. ExcelApp.ActiveSheet.Rows[2].Delete;
15 b. ExcelApp.ActiveSheet.Columns[1].Delete;
16 11、合并单元格:ExcelApp.worksheets[1].range[A1:F8'].Merge(abc);注:要声明变量abc: Variant;
17 12、竖行显示文字:ExcelApp.worksheets[1].Cells.Item[1,1].Orientation:= xlVertical;

18 13、单元格加边线:ExcelApp.worksheets[1].Range[A1:F8].Borders.LineStyle := 1;
19 14、在第8行之前插入分页符:ExcelApp.WorkSheets[1].Rows[8].PageBreak := 1;
20 15、在第4列之前删除分页符:ExcelApp.ActiveSheet.Columns[4].PageBreak := 0;
21 16、指定边框线宽度:ExcelApp.ActiveSheet.Range[ 'B3:D4' ].Borders[2].Weight := 3;
22 1-左 2-右 3-顶 4-底 5-斜( \ ) 6-斜( / )
23 17、拷贝操作:a.拷贝整个工作表:ExcelApplication1.ActiveSheet.Used.Range.Copy;
24 b.拷贝指定区域:ExcelApplication1.ActiveSheet.Range[ 'A1:E2' ].Copy;
25 c.从A1位置开始粘贴:ExcelApplication1.ActiveSheet.Range.[ 'A1' ].PasteSpecial;
26 d.从文件尾部开始粘贴:ExcelApplication1.ActiveSheet.Range.PasteSpecial;
27 18、清除第一行第四列单元格公式:ExcelApp.ActiveSheet.Cells[1,4].ClearContents;
28 19、工作表保存:if not ExcelApp.ActiveWorkBook.Saved then
29 ExcelApp.ActiveSheet.PrintPreview;
30 20、工作表另存为:ExcelApp.SaveAs( 'C:\Excel\Demo1.xls' );
31 21、放弃存盘:ExcelApp.ActiveWorkBook.Saved := True;
32 22、关闭工作簿:ExcelApp.WorkBooks.Close;
33 23、退出 Excel:ExcelApp.Quit;
34 下面是有关打印页面控制的语句:
35 24、设置第一行字体属性:ExcelApp.ActiveSheet.Rows[1].Font.Name := '隶书';
36 ExcelApp.ActiveSheet.Rows[1].Font.Color := clBlue;
37 ExcelApp.ActiveSheet.Rows[1].Font.Bold := True;
38 ExcelApp.ActiveSheet.Rows[1].Font.UnderLine := True;
39 ExcelApp.ActiveSheet.Rows[1].Font.size:=10;
40 25、进行页面设置:a.页眉:ExcelApp.ActiveSheet.PageSetup.CenterHeader := '报表演示';
41 b.页脚:ExcelApp.ActiveSheet.PageSetup.CenterFooter := '共&N页 第&P页';
42 c.页眉到顶端边距2cm:ExcelApp.ActiveSheet.PageSetup.HeaderMargin := 2/0.035;
43 d.页脚到底端边距3cm:ExcelApp.ActiveSheet.PageSetup.HeaderMargin := 3/0.035;
44 e.顶边距2cm:ExcelApp.ActiveSheet.PageSetup.TopMargin := 2/0.035;
45 f.底边距2cm:ExcelApp.ActiveSheet.PageSetup.BottomMargin := 2/0.035;
46 g.左边距2cm:ExcelApp.ActiveSheet.PageSetup.LeftMargin := 2/0.035;
47 h.右边距2cm:ExcelApp.ActiveSheet.PageSetup.RightMargin := 2/0.035;
48 i.页面水平居中:ExcelApp.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035;
49 j.页面垂直居中:ExcelApp.ActiveSheet.PageSetup.CenterVertically := 2/0.035;
50 k.打印单元格网线:ExcelApp.ActiveSheet.PageSetup.PrintGridLines := True;
51 26、打印预览工作表:ExcelApp.ActiveSheet.PrintPreview;
52 27、打印输出工作表:ExcelApp.ActiveSheet.PrintOut;
53 对Excel的其他控制:
54 28、excel的多单元格合计功能:ExcelApp..Cells[ARow, ACol].Formula
55 := '= SUM($+IntToStr(BeginRow) +:$ + IntToStr(EndRow) +');
56 注:声明变量ARow, ACol: Integer;
57 29、打开已经存在的Excel文件: ExcelApplication1.Workbooks.Open (c:\a.xls
58 EmptyParam,EmptyParam,EmptyParam,EmptyParam,
59 EmptyParam,EmptyParam,EmptyParam,EmptyParam,
60 EmptyParam,EmptyParam,EmptyParam,EmptyParam,0);

 

  好了,基本的Excel操作就这么多了,可能现在很多人都使用那些非常好用的Excel类库,但是了解这个个人觉得还是有必要的! 

  其实讲的这些只是一个很基础的,对于表格样式,多个人同时导出Excel表的时候的并发情况等等,这个就需要我们不断的探索和学习!

  下一篇:关于集合和数组的内在联系  

转载于:https://www.cnblogs.com/yangcaogui/archive/2011/12/17/2285824.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值