Excel 二次开发系列(4): 操作一个已经存在Excel

Excel表格文档由于其简单易用,普遍应用于不少单位或部门,因而在编写应用程序过程中,有时会需要对Excel文档进行操作,最简单的情况通常有两种:(1)需要获取文档中一些单元格的值;(2)将文档导入至数据库。 

1).在操作Excel文档之前,需要添加对Excel对象库的引用:

引用COMMicrosoft Excel 12.0 Object Library(版本号可能不同) 

2).以下代码示意打开一个已有的Excel文档的第一个sheet页,获取单元格B1的内容,并判断其值是否为my

 

复制代码
       private void Operate(string pFileName)
          {
             Excel.Application app 
= new Excel.Application();//打开一个Excel应用
             if (app == null)
             {
                 
return;
             }
 
             Workbooks wbs 
= app.Workbooks;
             _Workbook wb 
= wbs.Add(pFileName);//打开一个现有的工作薄
             Sheets shs = wb.Sheets;
             _Worksheet sh 
= (_Worksheet)shs.get_Item(1);//选择第一个Sheet页
             if (sh == null)
              {
                 
return;
             }
 
             Range r 
= sh.get_Range("B1", Missing.Value);
             
if (System.Convert.ToString(r.Value2).Trim().Equals("my"))
              {
                 
//Do Something.
             }

            
//释放资源 (在第一个系列里面讲到了资源的释放,在这里可以用了) 
               ReleaseCOM(sh);
             ReleaseCOM(shs);
             ReleaseCOM(wb);
             ReleaseCOM(wbs);
             app.Quit();
             ReleaseCOM(app);

         }
复制代码

4)基于Excel中的函数可以编辑出相当复杂的公式,有时候在处理Excel文档时,希望使用Excel中的公式,以下结合FREQUENCYMATCH函数对B列计算distinct count,将其写入B100单元格(假定有数据的行不超过100行):

 string count = sh.UsedRange.Rows.Count.ToString();
            Range r 
= sh.get_Range("B100", Missing.Value);
            r.Formula 
= "=SUM(IF(FREQUENCY(MATCH(B1:B" + count + ",B1:B" + count + ",0),MATCH(B1:B" + count + ",B1:B" + count + ",0))>0,1))";
            Console.WriteLine(System.Convert.ToString(r.Value2));

5).Excel导入数据,可以先使用ODBC,以select查询时使用[sheet页名称$]作为表名,将数据以datatable形式载入到内存中,之后的事就比较简单了,可以根据datatable逐行构造insert语句,然后插入到目标数据库中:

 

复制代码
private DataTable LoadExcel(string pPath)
          {
             
string connString = "Driver={Driver do Microsoft Excel(*.xls)};DriverId=790;SafeTransactions=0;ReadOnly=1;MaxScanRows=16;Threads=3;MaxBufferSize=2048;UserCommitSync=Yes;FIL=excel 8.0;PageTimeout=5;";
             connString 
+= "DBQ=" + pPath;
             OdbcConnection conn 
= new OdbcConnection(connString);
             OdbcCommand cmd 
= new OdbcCommand();
             cmd.Connection 
= conn;
             
//获取Excel中第一个Sheet名称,作为查询时的表名
             string sheetName = this.GetExcelSheetName(pPath);
             
string sql = "select * from [" + sheetName.Replace('.''#'+ "$]";
             cmd.CommandText 
= sql;
             OdbcDataAdapter da 
= new OdbcDataAdapter(cmd);
             DataSet ds 
= new DataSet();
             
try
              {                
                 da.Fill(ds);
                 
return ds.Tables[0];
             }
             
catch (Exception x)
              {
                 ds 
= null;
                 
throw new Exception("从Excel文件中获取数据时发生错误!");
             }
             
finally
              {
                 cmd.Dispose();
                 cmd 
= null;
                 da.Dispose();
                 da 
= null;
                 
if (conn.State == ConnectionState.Open)
                  {
                     conn.Close();
                 }
                 conn 
= null;
             }
         }
复制代码

6).关于从Excel导入数据,网上应该有很多例子,这里补充一个关于数据导入时的效率问题。最初在从Excel导入数据到MySql中时,当文件达到50000行时,逐行导入花了10余分钟的时间。大量执行插入操作,逐条执行很慢原因可能在于:

(1)每执行一条插入语句,客户端需要与服务器交互一次,这要有代价

(2)一些数据库对每一条插入操作都执行事务,这也要有代价

所以在大量执行插入操作时,应该尽量先多个insert语句拼接好,例如每次拼接好200insert语句,然后再一次执行它,这样可以大幅提高效率。

posted @   tomin  阅读(5560)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示