zoukankan      html  css  js  c++  java
  • 学习之路一:关于使用微软的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表的时候的并发情况等等,这个就需要我们不断的探索和学习!

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

  • 相关阅读:
    ubuntu重复登录问题
    CUDA相关问题
    pytorch安装(使用pip3装到conda环境下)
    ubuntu16.04 anaconda的安装和卸载
    vscode插件安装失败的解决方案
    使用ffmpeg进行视频截图
    Spring加载早期获取BasePackage
    chrome最耐看的主题
    针对MySQL的MVCC多版本并发控制的一些总结
    docker创建mysql容器,并挂载数据+配置
  • 原文地址:https://www.cnblogs.com/yangcaogui/p/2285824.html
Copyright © 2011-2022 走看看