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

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, First, Last, 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中,然后用户操作完成后,通过后台程序将数据库保存到数据库中.

(0)

相关推荐

  • C#实现将数据导出到word或者Excel中的方法

    本文实例讲述了C#实现将数据导出到word或者Excel中的方法.分享给大家供大家参考.具体如下: void OutToWord() { if (dataGridView1.Rows.Count >= 1) { string tempstr =""; Stream myStream; SaveFileDialog dlg =new SaveFileDialog(); dlg.Filter = "(Word文件)*.doc|*.doc"; //dlg.Filte

  • C#实现导入CSV文件到Excel工作簿的方法

    本文实例讲述了C#实现导入CSV文件到Excel工作簿的方法.分享给大家供大家参考.具体如下: 你必须在项目中添加对 Microsoft.Office.Core 的引用:from the .NET tab of the Visual Studio Add Reference dialog box, and the Microsoft Excel 12.0 Object Library (you can use 14.0 if you want, too, but nothing lower).

  • C#读取Excel的三种方式以及比较分析

    (1)OleDB方式 优点:将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快. 缺点:读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Datatable)再在Datatable中根据行列数来获取指定的值. 当Excel数据量很大时.会非常占用内存,当内存不够时会抛出内存溢出的异常. 读取代码如下: public DataTable GetExcelTableByOleDB(string strExcelPath, string tabl

  • C#使用winform简单导出Excel的方法

    本文实例讲述了C#使用winform简单导出Excel的方法.分享给大家供大家参考,具体如下: using Excel; 在项目中引入Excel.dll /// <summary> /// 导出Excel /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnEx

  • C#给Excel添加水印实例详解

    C#中如何给Excel添加水印 我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的方式来解决此问题,如通过添加页眉图片或艺术字的方法来模仿水印的外观.所以在这篇文章中,我将向您演示来如何通过在Excel中创建和插入页眉图片来为excel添加水印.之前我也分享了如何给word文档添加水印和pdf文件添加水印的方法,有需要也可以参考. 这里我下载了一个E-iceblue公司开发的免费版的Excel组件- Free Spire.XLS,这样既

  • C#使用Aspose.Cells控件读取Excel

    Aspose是一个很强大的控件,可以用来操作word,excel,ppt等文件,用这个控件来导入.导出数据非常方便.其中Aspose.Cells就是用来操作Excel的,功能有很多.我所用的是最基本的功能,读取Excel的数据并导入到Dataset或数据库中.读取Excel表格数据的代码如下: 首先要引入命名空间:using Aspose.Cells; 复制代码 代码如下: Workbook workbook = new Workbook(); workbook.Open("C:\\test.x

  • C#实现DataSet内数据转化为Excel和Word文件的通用类完整实例

    本文实例讲述了C#实现DataSet内数据转化为Excel和Word文件的通用类.分享给大家供大家参考,具体如下: 前不久因为项目的需要写的一个C#把DataSet内数据转化为Excel和Word文件的通用类,这些关于Excel.Word的导出方法,基本可以实现日常须要,其中有些方法可以把数据导出后 生成Xml格式,再导入数据库!有些屏蔽内容没有去掉,保留下来方便学习参考用之. 最后请引用Office相应COM组件,导出Excel对象的一个方法要调用其中的一些方法和属性. using Syste

  • C#实现将DataTable内容输出到Excel表格的方法

    本文实例讲述了C#实现将DataTable内容输出到Excel表格的方法.分享给大家供大家参考.具体如下: 1.关于本文 本文描述了一个函数(SaveToExcel),该函数可以将DataTable数据内的数据输出到Excel表格中 2.相关说明 1)本文中使用这个函数将一个DataTable中的内容输出到路径名为addr的目录下: 复制代码 代码如下: public void SaveToExcel(string addr, System.Data.DataTable dt) 2)这个函数需要

  • C#使用oledb导出数据到excel的方法

    本文实例讲述了C#使用oledb导出数据到excel的方法.分享给大家供大家参考,具体如下: 现在做应用的一半都会碰到数据导出的问题,导出到word阿,导出到excel啊,还有其他的什么.当然导出的类型中还是以ms office的居多.最近在做数据的转换,也碰到这个导出的问题,当然幸运的是不用碰word,这样涉及到就只有xml,csv,tsv和最"痛苦"的excel了. 最开始的想法是xml+xslt,搞定全部,但是有一个问题就是excel只有在xp版本之后支持xml,我不能强制的要求

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

    Excel是微软办公套装软件的一个重要的组成部分,它可以进行各种数据的处理.统计分析和辅助决策操作,广泛地应用于管理.统计财经.金融等众多领域.(另外,Excel还是伦敦一所会展中心的名称)..NET可以创建Excel Add-In对Excel进行功能扩展,这些扩展的功能包括自定义用户函数,自定义UI,与数据库进行数据交互等. 一 主要的Excel开发方式 1 VBA VBA是一种Visual Basic的宏语言,它是最早的Office提供定制化的一种解决方案,VBA是VB的一个子集,和Visu

  • Linux下将excel数据导入到mssql数据库中的方法

    先清理一下思路先,~~ 首先:需要把文件上传到服务器上 然后:读取excel数据列显示出来 然后:让用户选择字段的对应关系 然后:提交数据,读取字段的对应关系 最后:批量导入数据,删除临时文件 一共是以上五步骤!我们一步步分析~~~ 第一步:下载附件中的phpexcelparser4.rar ,这个文件是上传excel盗服务器上并以web形式展示出来的!这个一般没有问题的!问题是程序的做法是把表存为临时表而没有真正保存下来,所以首先要更改程序代码为 复制代码 代码如下: if (trim($_P

  • Android开发之ListView的简单用法及定制ListView界面操作示例

    本文实例讲述了Android开发之ListView的简单用法及定制ListView界面操作.分享给大家供大家参考,具体如下: 效果: 如何从获得listview上item的内容 详见:https://www.jb51.net/article/158000.htm 中遇到的问题部分. 布局实现: 有个listview显示 一个edit和button发送 <?xml version="1.0" encoding="utf-8"?> <RelativeL

  • 将Excel中数据导入到Access数据库中的方法

    Default.aspx 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/

  • thinkPHP实现将excel导入到数据库中的方法

    本文实例讲述了thinkPHP实现将excel导入到数据库中的方法.分享给大家供大家参考,具体如下: PHPExcel插件可点击此处本站下载. 这里使用的是thinkphp框架的3.1版本,下载好压缩包,框架中的extend中的vendor文件夹中新建一个名为PHPExcel的文件夹,把classes里面的内容放到里面 下面是前端页面 提示:我在测试的时候遇到报错exception 'PHPExcel_Reader_Exception' with message 'The filename 原因

  • asp实现excel中的数据导入数据库

    asp实现excel中的数据导入数据库 <% Response.CodePage=65001%> <% Response.Charset="UTF-8" %> <% wenjian = request.Form("select") '获取文件扩展名 ext = FileExec(wenjian) '判断文件扩展名 if ext <> "xls" then response.Write("<

  • C#实现Excel表数据导入Sql Server数据库中的方法

    本文实例讲述了C#实现Excel表数据导入Sql Server数据库中的方法.分享给大家供大家参考,具体如下: Excel表数据导入Sql Server数据库的方法很多,这里只是介绍了其中一种: 1.首先,我们要先在test数据库中新建一个my_test表,该表具有三个字段tid int类型, tname nvarchar类型, tt nvarchar类型 (注意:my_test表中的数据类型必须与Excel中相应字段的类型一致) 2. 我们用SELECT * FROM  OPENROWSET(

  • Java实现批量导入excel表格数据到数据库中的方法

    本文实例讲述了Java实现批量导入excel表格数据到数据库中的方法.分享给大家供大家参考,具体如下: 1.创建导入抽象类 package com.gcloud.common.excel; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import java.sql.SQLException;

  • yii2.0框架实现上传excel文件后导入到数据库的方法示例

    本文实例讲述了yii2.0框架实现上传excel文件后导入到数据库的方法.分享给大家供大家参考,具体如下: Model模型 <?php /** * 描述... * @author zcy * @date 2019/8/13 */ namespace app\models; use yii\base\Model; use yii\db\ActiveRecord; use yii\web\UploadedFile; class uploadForm extends ActiveRecord { pu

  • 如何将excel表格数据导入postgresql数据库

    实际的工作中,我们经常会碰到统计数据的工作,有些维度的统计数据因为工作需要我们需要导出为excel作为报表附件供不同的部门审查.为了方便以后的对比工作,领导会让在数据库中创建一张表,用于专门记录这些数据.此时我们DBA需要将这些excel表格导入到数据库中,copy和\copy命令为我们提供了解决办法,本文主要通过copy命令的使用,介绍如何将excel表格导入至数据库中.关于copy及\copy命令的区别,请广大博友通过另一篇文章<如何将postgresql数据库表内数据导出为excel格式>

随机推荐