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

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

引用—COM—Microsoft Excel 11.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.
            }
        }

3).

不少人在打开Excel应用后,对如何在使用完成后释放它大感头痛,在网上我找到一种方法,经过实验证明是OK的:

        private void ReleaseCOM(object pObj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(pObj);
            }
            catch
            {
                throw new Exception("释放资源时发生错误!");
            }
            finally
            {
                pObj = null;
            }
        }

有了该方法,则只要在步骤2)代码之后添加以下代码,就可以完成对资源的释放:

        private void Operate(string pFileName)
        
……
//释放资源
            ReleaseCOM(sh);
            ReleaseCOM(shs);
            ReleaseCOM(wb);
            ReleaseCOM(wbs);
            app.Quit();
            ReleaseCOM(app);
        }

4).

基于Excel中的函数可以编辑出相当复杂的公式,有时候在处理Excel文档时,希望使用Excel中的公式,以下结合FREQUENCY,MATCH函数对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;
            }
        }

        private string GetExcelSheetName(string pPath)
        {
            //打开一个Excel应用
            Excel.Application app = new Excel.Application();
            if (app == null)
            {
                throw new Exception("打开Excel应用时发生错误!");
            }
            Excel.Workbooks wbs = app.Workbooks;
            //打开一个现有的工作薄
            Excel._Workbook wb = wbs.Add(pPath);
            Excel.Sheets shs = wb.Sheets;
            //选择第一个Sheet页
            Excel._Worksheet sh = (Excel._Worksheet)shs.get_Item(1);
            string sheetName = sh.Name;

            ReleaseCOM(sh);
            ReleaseCOM(shs);
            ReleaseCOM(wb);
            ReleaseCOM(wbs);
            app.Quit();
            ReleaseCOM(app);
            return sheetName;
        }

(“string sql = "select * from [" + sheetName.Replace('.', '#') + "$]";”如果sheet页名称中含有“.”,则要将其替换为“#”,具体原因,没研究出来-_-。另外贴一张界面截图:)

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

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

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

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

.NET基础示例系列之十五:操作Excel相关推荐

  1. .NET基础示例系列之十六:制做进程监视器

    1)可以查看进程的各项基本信息,如cpu,内存,父进程,执行路径,创建者等 2)可以中止进程,创建新进程 3)可以配置目标进程,配置刷新速度 最终效果图: (以下给出部分代码,其余像进程的创建.中止等 ...

  2. [C# 基础知识系列]专题十五:全面解析扩展方法

    引言:  C# 3中所有特性的提出都是更好地为Linq服务的, 充分理解这些基础特性后.对于更深层次地去理解Linq的架构方面会更加简单,从而就可以自己去实现一个简单的ORM框架的,对于Linq的学习 ...

  3. 基础系列【十五】--Pattern

    基础系列[十五]--Pattern Pattern Pattern java.lang.Object java.util.regex.Pattern (public final class Patte ...

  4. 【SQL开发实战技巧】系列(十五):查找最值所在行数据信息及快速计算总和百之max/min() keep() over()、fisrt_value、last_value、ratio_to_report

    系列文章目录 [SQL开发实战技巧]系列(一):关于SQL不得不说的那些事 [SQL开发实战技巧]系列(二):简单单表查询 [SQL开发实战技巧]系列(三):SQL排序的那些事 [SQL开发实战技巧] ...

  5. Reflex WMS入门系列二十五:将叉车纳入系统进行管理

    Reflex WMS入门系列二十五:将叉车纳入系统进行管理 据笔者所知,SAP WM 模块里是不对仓库里常用的叉车等仓库管理工具进行管理的.笔者发现,Reflex WMS系统则会在很多仓库部门日常操作 ...

  6. 5G基础知识学习(十五)—NSA手机的5G信号是怎么显示的?

    5G基础知识学习(十五)-NSA手机的5G信号是怎么显示的? 参考网址:http://www.txrjy.com/thread-1106049-1-1.html 看完了前面的连载,相信大家对NSA也就 ...

  7. SpringCloud技术指南系列(十五)分布式链路跟踪Sleuth与Zipkin实现

    SpringCloud技术指南系列(十五)分布式链路跟踪Sleuth与Zipkin实现 一.概述 分布式链路追踪,是一种用于分析和监控应用程序的方法,尤其是那些使用微服务架构的那些应用.分布式链路跟踪 ...

  8. ASP.NET企业开发框架IsLine FrameWork系列之十五--框架配置信息大全(下)

    ASP.NET企业开发框架IsLine FrameWork系列之十五--框架配置信息大全(下) 接上文   三.IsLine.ExceptionProcess 部分 这部分主要管理异常,对异常的管理分 ...

  9. IT职场人生系列之十五:语言与技术II

    本文是IT职场人生系列的第十五篇 本篇延续了技术与语言I的内容(之十二),搜集了之后大家的一些评论和我的反馈,整理在这里. "新人学老技术有风险"的实质 其实不是说老技术没有学习的 ...

  10. SLAM导航机器人零基础实战系列:(五)树莓派3开发环境搭建——2.安装ros-kinetic

    SLAM导航机器人零基础实战系列:(五)树莓派3开发环境搭建--2.安装ros-kinetic 摘要 通过前面一系列的铺垫,相信大家对整个miiboo机器人的DIY有了一个清晰整体的认识.接下来就正式 ...

最新文章

  1. 操作系统---Systemd
  2. php变量赋值有几种,【后端开辟】php变量赋值体式格局有几种
  3. Oracle中PLSQL中一个例外的写法
  4. JAAS:灵活的Java安全机制[转]
  5. C#打开文件和文件夹
  6. 机器人 铑元素_智能机器人 三十三
  7. python去掉html标签_python 去除html标签的几种方法
  8. 小企业电脑如何组网_(完整版)中小型企业组网方案
  9. SQL Server将一列的多行内容拼接成一行的实现方法
  10. 怎么看mac电脑wifi密码?很简单!
  11. 如何用Primer6批量设计引物(非全cDNA引物)
  12. 白盒测试方法之条件组合覆盖测试
  13. google chrome 同步书签 查看gmail邮箱 谷歌浏览器同步助手
  14. 证券市场的法律法规体系
  15. 计算机计算累计公式,““请问Excel表格求的合计数为什么和用计算器累加出的合计数不一致...
  16. MSP430F415IRTDR
  17. [re入门]IDA和OD的基本使用(持续更新)
  18. 六款强大的开源数据挖掘工具
  19. 软件是怎么开发出来的?怎么进行软件开发流程详解
  20. 服务器自带的防篡改,防篡改系统

热门文章

  1. 吴锦华/明鑫: 用户态文件系统(FUSE)框架分析和实战
  2. session timer(一)
  3. 追加文件内容的三种方法
  4. python 装饰器常见场景与用法
  5. spark MetaException(message:Version information not found in metastore. )
  6. android 输入支付密码错误,Android 支付宝支付密码输入界面
  7. php mysql update 不成功也不提示_php与MySQL(基本操作)
  8. python min函数时间复杂度是指_python中的内置函数max()和min()及mas()函数的高级用法...
  9. apollo 配置中心_Apollo 配置中心:分布式部署
  10. php转java还是python_我是应该继续学习php还是转JAVA Go Python?