C#定制Excel界面并实现与数据库交互的方法

C#定制Excel界面并实现与数据库交互的方法,第1张

概述Excel是微软办公套装软件的一个重要的组成部分,它可以进行各种数据的处理、统计分析和辅助决策 *** 作,广泛地应用于管理、统计财经、金融等众多领域。(另外,Excel还是伦敦一所会展中心的名称)。.NET可以创建ExcelAdd-

Excel是微软办公套装软件的一个重要的组成部分,它可以进行各种数据的处理、统计分析和辅助决策 *** 作,广泛地应用于管理、统计财经、金融等众多领域。(另外,Excel还是伦敦一所会展中心的名称)。.NET可以创建Excel Add-In对Excel进行功能扩展,这些扩展的功能包括自定义用户函数,自定义UI,与数据库进行数据交互等。

一 主要的Excel开发方式

  1 VBA

    VBA是一种Visual Basic的宏语言,它是最早的Office提供定制化的一种解决方案,VBA是VB的一个子集,和Visual Basic不同,VBA是一种宿主型语言,无论是专业的开发人员,还是刚入门的非开发人员,都可以利用VBA完成简单或复杂的需求。

  2 Excel Addin

    Excel Addin,就像Visual Studio外接插件一样,也可以使用一些技术为Office开发一些插件。对VBA的一些问题,一些专业的开发人员,可以使用 VisualBasic或者VisualC++等工具来引用Office的一些dll,来针对Office进行开发。开发的时候将dll注册为com组 件,并在注册表里面进行注册,这样就可以在Excel里直接调用这些插件。

  3 VSTO (Visual Studio Tools for Office)

    VSTO主要是对Office的一些dll进行了.NET封装,使得我们可以使用.NET上的语言来方便的对Office的一些方法进行调用。所 以,Office开发跨入了一个新的时代,开发人员可以使用更加高级的语言和熟悉的技术来更容易的进行Office开发。 对于企业及的应用和开发,VSTO或许是首要选择,他极大地扩展了Office应用程序的能力,使用.NET平台支持的编程语言,能够直接访问.NET上面众多的类库。具有较好的安全机制。简化了Office插件的开发和部署。

  4 XLL

    XLL是Excel的一种外接应用程序,他使用C和C++开发,程序通过调用Excel暴漏的C接口来实现扩展功能。这种方式开发的应用程序效率高,但是难度大,对开发者自身的要求较高。开源项目Excel-DNA就是使用XLL技术开发的,能够帮助.NET 开发人员来极大地简化RTD函数,同步、异步UDF函数的编写和开发。

  5 OpenXML

    如果用户没有安装Excel应用程序,或者在服务器端需要动态生成Excel文件的时候。我们可能需要直接读取或者生成Excel文件,这种情况下,如果要对Excel文件进行各种定制化开发的话,建议使用OpenXML。NPOI开源项目可以直接读写Excel文件,而且兼容多个版本。

二 使用Excel Add-In构建扩展

  开发环境: *** 作系统为windows Server 2008R2 x64;Excel为Excel 2010 x64;开发工具为Visual Studio 2012旗舰版x64;数据库为sql Server 2008R2 x64.

  1 程序结构

  用Visual Studio 2012新建一个ExcelAddindemo的Excel Add-In项目,并添加若干文件,程序结构如下图:

  其中,RibbonAddIn可以定制2010的UI面板,sqlHelper.cs是一个简单的数据库访问帮助类,UClog.cs,UCPaneleft.cs,UCTaskGrID.cs,UCTaskPane.cs都为添加的自定义控件,并通过程序添加到EXCEL界面中.运行起来的界面如下:

  程序可以通过在Excel界面中输入ID,First,Last,Email的值(对应标签的后一个单元格),单击用户列表面板上的保存按钮,将数据保存到数据库中.

  2 RibbonAddIn设计

  我们通过RibbonAddIn.cs给Excel的Ribbon添加了一个名为CUMT的插件.RibbonAddIn面板可以通过工具条控件方便的拖放到设计界面上.RibbonAddIn.cs的属性设置如下图所示:

  后台代码如下:

 using System; using System.Collections.Generic; using System.linq; using System.Text; using Microsoft.Office.Tools.Ribbon; namespace ExcelAddindemo {   public partial class RibbonAddIn   {     private voID RibbonAddIn_Load(object sender,RibbonUIEventArgs e)     {     }     private voID btnAbout_Click(object sender,RibbonControlEventArgs e)     {       System.windows.Forms.MessageBox.Show("JackWangCUMT!");     }     private voID btnShow_Click(object sender,RibbonControlEventArgs e)     {       if (Globals.ThisAddIn._MyCustomTaskPane != null)       {         Globals.ThisAddIn._MyCustomTaskPane.Visible = true;       }     }     private voID btnHIDe_Click(object sender,RibbonControlEventArgs e)     {       if (Globals.ThisAddIn._MyCustomTaskPane != null)       {         Globals.ThisAddIn._MyCustomTaskPane.Visible = false;       }     }   } }

  3 ThisAddIn逻辑编写

using System;  using System.Collections.Generic;  using System.linq;  using System.Text;  using System.Xml.linq;  using Excel = Microsoft.Office.Interop.Excel;  namespace ExcelAddindemo  {    using Microsoft.Office.Tools;   public partial class ThisAddIn   {     public CustomTaskPane _MyCustomTaskPane = null;     private voID ThisAddIn_Startup(object sender,System.EventArgs e)     {       UCTaskPane taskPane = new UCTaskPane();       _MyCustomTaskPane = this.CustomTaskPanes.Add(taskPane,"我的任务面板");       _MyCustomTaskPane.WIDth = ;//height有问题,此处wIDth ==height       _MyCustomTaskPane.Visible = true;       _MyCustomTaskPane.Dockposition = Microsoft.Office.Core.MsoCTPDockposition.msoCTPDockpositiontop;       UCPaneleft panleft = new UCPaneleft();       _MyCustomTaskPane = this.CustomTaskPanes.Add(panleft,"组织");       _MyCustomTaskPane.WIDth = ;       _MyCustomTaskPane.Visible = true;       _MyCustomTaskPane.Dockposition = Microsoft.Office.Core.MsoCTPDockposition.msoCTPDockpositionleft;       UCTaskGrID panRight = new UCTaskGrID();       _MyCustomTaskPane = this.CustomTaskPanes.Add(panRight,"用户列表");       _MyCustomTaskPane.WIDth = ;       _MyCustomTaskPane.Visible = true;       _MyCustomTaskPane.Dockposition = Microsoft.Office.Core.MsoCTPDockposition.msoCTPDockpositionRight;       UCLog panLog = new UCLog();       _MyCustomTaskPane = this.CustomTaskPanes.Add(panLog,"日志列表");       _MyCustomTaskPane.WIDth = ;       _MyCustomTaskPane.Visible = true;       _MyCustomTaskPane.Dockposition = Microsoft.Office.Core.MsoCTPDockposition.msoCTPDockpositionBottom;       //Hook into the workbook open event       //This is because Office doesn't always have a document ready when this method is run        this.Application.WorkbookActivate += Application_WorkbookActivate;       //test        //this.Application.SheetSelectionChange += Application_SheetSelectionChange;     }     voID Application_SheetSelectionChange(object Sh,Excel.Range Target)     {       if (this.Application != null)       {         this.Application.Caption = this.Application.ActiveCell.Address.ToString();//$A$         //+ this.Application.ActiveCell.AddressLocal.ToString();//$A$         //this.Application.ActiveCell.Formula = "=sum(+)";       }     }     voID Application_WorkbookActivate(Excel.Workbook Wb)     {       //using Microsoft.Office.Tools.Excel 和 using Microsoft.Office.Interop.Excel 都有worksheet等,容易混淆       //string path = this.Application.ActiveWorkbook.Fullname;       Excel._Worksheet ws = (Excel._Worksheet)this.Application.ActiveWorkbook.ActiveSheet;       ws.Cells[,] = "ID";       //如何设置只读等有待研究       int r=,c=;       //((Excel.Range)ws.Cells[r,c]).NumberFormat = format;       ((Excel.Range)ws.Cells[r,c]).Value = "ID";       ((Excel.Range)ws.Cells[r,c]).Interior.color =System.Drawing. colorTranslator.Toole(System.Drawing.color.Red);       //((Excel.Range)ws.Cells[r,c]).Style.name = "normal";       ((Excel.Range)ws.Cells[r,c]).Style.Font.Bold = true;       #region format       ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("A","E")).Font.Bold = true;       ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("A","E")).Font.Italic = true;       ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("A","E")).Font.color = System.Drawing.color.FromArgb(,).ToArgb();       ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("A","E")).Font.name = "Calibri";       ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("A","E")).Font.Size = ;       //border       Excel.Range range = ((Microsoft.Office.Interop.Excel.Range)ws.get_Range("B","E"));       Excel. borders border = range.borders;       border[Excel.XlbordersIndex.xlEdgeBottom].linestyle =Excel. Xllinestyle.xlContinuous;       border.Weight = d;       border[Excel.XlbordersIndex.xlEdgetop].linestyle = Excel.Xllinestyle.xlContinuous;       border[Excel.XlbordersIndex.xlEdgeleft].linestyle = Excel.Xllinestyle.xlContinuous;       border[Excel.XlbordersIndex.xlEdgeRight].linestyle = Excel.Xllinestyle.xlContinuous;       #endregion       ws.Cells[,] = "First";       ws.Cells[,] = "Last";       ws.Cells[,] = "Email";     }     private voID ThisAddIn_Shutdown(object sender,System.EventArgs e)     {     }     #region VSTO 生成的代码     /// <summary>     /// 设计器支持所需的方法 - 不要     /// 使用代码编辑器修改此方法的内容。     /// </summary>     private voID InternalStartup()     {       this.Startup += new System.EventHandler(ThisAddIn_Startup);       this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);     }     #endregion   } }

   ThisAddIn_Startup事件中,初始化四个面板,并对其基本属性进行设置,停靠在上的面板我设置其Height无效,改成WIDth后其效果和Height预期的一样(不知道这个底层开发人员是怎么想的,哈哈!)另外 Excel._Worksheet ws = (Excel._Worksheet)this.Application.ActiveWorkbook.ActiveSheet;是非常关键的一句,我这里足足折腾了很久,原因是using Microsoft.Office.Tools.Excel 和 using Microsoft.Office.Interop.Excel 都有worksheet元素,结构混淆了,运行时老是获取不到Excel的ActiveWorkbook.

  4 UCTaskGrID设计

  UCTaskGrID是一个用户控件,包含一个工具条和一个dataGrIDVIEw1控件,其设计界面如下:

  后台代码如下:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.linq; using System.Text; using System.windows.Forms; namespace ExcelAddindemo {   using Excel = Microsoft.Office.Interop.Excel;   public partial class UCTaskGrID : UserControl   {     public UCTaskGrID()     {       InitializeComponent();     }     private voID UCTaskGrID_Load(object sender,EventArgs e)     {       //load data       System.Data.Datatable dt = sqlHelper.getDatetable("select * from ACT_ID_USER",null);       this.dataGrIDVIEw.DataSource = dt;     }     private voID 保存SToolStripbutton_Click(object sender,EventArgs e)     {       //核心代码,获取当前的worksheet       Excel._Worksheet ws = (Excel._Worksheet)Globals.ThisAddIn.Application.ActiveWorkbook.ActiveSheet;       string name = ws.name;       string ID = ((string)(ws.Cells[,] as Excel.Range).Value).ToString();       string First = ((string)(ws.Cells[,] as Excel.Range).Value).ToString();       string Last = ((string)(ws.Cells[,] as Excel.Range).Value).ToString();       string Email = ((string)(ws.Cells[,] as Excel.Range).Value).ToString();       string sql = string.Format("insert into ACT_ID_USER ([ID_],[FirsT_],[LAST_],[EMAIL_]) values('{}','{}','{}')",ID,Email);       int rows= sqlHelper.ExecuteNonquery(sqlHelper.ConnectionStringLocalTransaction,System.Data.CommandType.Text,sql,null);       if (rows == )       {         System.windows.Forms.MessageBox.Show("saved");       }       else       {         System.windows.Forms.MessageBox.Show("error");       }     }     private voID 打开OToolStripbutton_Click(object sender,EventArgs e)     {       //refresh       System.Data.Datatable dt = sqlHelper.getDatetable("select * from ACT_ID_USER",null);       this.dataGrIDVIEw.DataSource = dt;     }   } }

  5 Add-In强签名

  通过设置程序的属性中的签名页,让VS自动生成一个签名即可(需设置密码)

三 最终效果演示

  为了直观的展示,看下面的动画:

四 猜想 Excel Service

  现在功能很强大的Excel服务器,其中一个亮点就是在Excel中进行界面设计和数据 *** 作,然后就数据持久化到数据库中,那么我的猜想是,能不能通过AddIn的方式实现一个excel service功能呢,将界面设计序列化保存到数据库中,并给一个路径(唯一),但用户单击菜单(确定了路径)后将界面设计呈现到excel中,然后用户 *** 作完成后,通过后台程序将数据库保存到数据库中.

总结

以上是内存溢出为你收集整理的C#定制Excel界面并实现与数据库交互的方法全部内容,希望文章能够帮你解决C#定制Excel界面并实现与数据库交互的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1254213.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存