一起谈.NET技术,Silverlight 4中把DataGrid数据导出Excel—附源码下载

  Silverlight中常常用到DataGrid来展示密集数据. 而常见应用系统中我们需要把这些数据导入导出到固定Office套件中例如常用的Excel表格. 那么在Silverlight 中如何加以实现?

  在参考大量资料后 提供参考思路如下:

  A:纯客户端导出处理.利用Silverlight 与Javascript 进行交互实现导出Excel。

  B:服务器端导出.获得DataGrid数据源. 传递给WCF Service到服务器端. 然后把传回数据通过Asp.net中通用处理导出Excel方法加以实现。

  方法A实现导入导出核心在JS脚本中. 属于纯客户端交互. 简洁实用. 但问题也正是源自于JS脚本. 如果对Excel数据格式进行变动. 大家都应该知道JS支持的调试时不容易控制的. 所以很容易出现脚本错误. 而且每次修改起来都很麻烦费时。

  方法B也算是各位非常熟悉一种方式. 获得数据把数据传入Asp.net中通用实现导出Excel方法. 加以实现. 大部分编码都在服务器端. 比JS要容易控制. 所以方法B相比方法A而要效率更高, 且更容易移植 修改控制。

  Silverlight中有没有其他方式来实现? 答案是有的.Silverlight当在使用高级权限运行Out-Of-Broswer[OOB]浏览器外应用时. Silverlight 4版本中微软为了支持企业用户提供类似Office自动化功能,引入Com+自动化. COM+自动化仅支持有高级信任许可的OOB Silverlight应用,高级信任许可意味着操作者可以在少许限制的条件下,在Windows计算机上执行几乎所有的命令,这就对Silverlight 实现Excel导出提供了可能。

  注意:当直接点击导出按钮时.会提示异常:"当前上下文不支持此操作."因使用Com+自动化需要在OOB应用模式才具有权限操作.所以右键点击程序选择程序安装:

  安装本地后自动打开:

  点击导出到Excel按钮 导出效果[有点粗糙]:

  A:如何实现

  页面XAML布局:为了演示目的只有个Datagrid和一个Button按钮如下:

 1     < Grid  x:Name ="LayoutRoot"  Background ="White"  Height ="500"  Width ="707" >
 2           < sdk:DataGrid  AutoGenerateColumns ="False"   Margin ="24,61,191,207"  Name ="dataGrid1" >
 3               < sdk:DataGrid.Columns  >
 4                   < sdk:DataGridTextColumn  Header ="编     号"  Binding =" {Binding Id} " ></ sdk:DataGridTextColumn >
 5                   < sdk:DataGridTextColumn  Header ="顾客姓名"  Binding =" {Binding CustomerName} " ></ sdk:DataGridTextColumn >
 6                   < sdk:DataGridTextColumn  Header ="地               址"  Binding =" {Binding Address} " ></ sdk:DataGridTextColumn >
 7                   < sdk:DataGridTextColumn  Header ="电话号码"  Binding =" {Binding Telephone} " ></ sdk:DataGridTextColumn >
 8               </ sdk:DataGrid.Columns >
 9           </ sdk:DataGrid >
10           < Button  Content ="导出到Excel中"    Background ="Red"  Height ="34"   Margin ="24,21,550,445"  Name ="button1"   Width ="133"  Click ="button1_Click"   />
11       </ Grid >

   DataGrid数据绑定,一个Customer类提供一个List集合实现简单数据源:

 1    public   class  Customer
 2      {
 3           public   int  Id {  get set ; }
 4           public   string  CustomerName {  get set ; }
 5           public   string  Address {  get set ; }
 6           public   string  Telephone {  get set ; }
 7 
 8           ///   <summary>
 9           ///  获取一个批量数据用来绑定DataGrid中 演示由DataGrid 导出到数据库中
10           ///  Author:chenkai Date:2010年6月9日16:25:25
11           ///   </summary>
12             public   static  List < Customer >  GetCustomerListBind()
13          {
14              List < Customer >  getcuslist  =   new  List < Customer > ();
15 
16              Random getdom  =   new  Random();
17 
18               for  ( int  count  =   0 ; count  <   12 ; count ++ )
19              {
20                  getcuslist.Add( new  Customer {  Id = count, CustomerName = count.ToString() + " 陈凯 " , Address = getdom.Next( 15 , 200 ).ToString() + " 中国 " , Telephone = getdom.Next( 0 , 230000 ).ToString()});
21              }
22               return  getcuslist;
23          }
24          
25      }

  后台操作演示:

 
  
1 public partial class MainPage : UserControl
2 {
3 public MainPage()
4 {
5 InitializeComponent();
6
7 // 绑定数据
8 List < Customer > getcuslist = Customer.GetCustomerListBind();
9 if (getcuslist.Count > 0 )
10 {
11 this .dataGrid1.ItemsSource = getcuslist;
12 }
13
14 // 绑定Button事件
15 this .button1.Click += new RoutedEventHandler(ExpertDataToExcel);
16 }
17
18 void ExpertDataToExcel( object sender, RoutedEventArgs e)
19 {
20 int rowIndex = 1 ;
21 int coulmnIndex = 1 ;
22
23 try
24 {
25 dynamic excel = AutomationFactory.CreateObject( " Excel.Application " );
26
27 excel.workbooks.Add();
28
29 dynamic sheet = excel.ActiveSheet;
30
31 // 加载Excel表头数据
32 for ( int i = 0 ; i < this .dataGrid1.Columns.Count; ++ i)
33 {
34 dynamic headerCell = sheet.Cells[rowIndex, coulmnIndex + i];
35 // 把当前Grid中表头信息赋值给Excel表头.
36 headerCell.Value = this .dataGrid1.Columns[i].Header;
37 headerCell.Font.Bold = true ; // 加粗
38 headerCell.Interior.Color = 0xFF00 ; // 设置背景颜色
39 }
40
41 // 加载展示数据
42 foreach (Customer customer in this .dataGrid1.ItemsSource)
43 {
44 rowIndex ++ ;
45
46 // column 1
47 dynamic cellFirstName = sheet.Cells[rowIndex, 1 ];
48 cellFirstName.Value = customer.Id;
49 cellFirstName.Font.Color = 003399 ;
50
51 // column 2
52 dynamic cellLastName = sheet.Cells[rowIndex, 2 ];
53 cellLastName.Value = customer.CustomerName;
54 cellLastName.Font.Color = 003399 ;
55
56 // column 3
57 dynamic cellAge = sheet.Cells[rowIndex, 3 ];
58 cellAge.Value = customer.Address;
59 cellAge.Font.Color = 003399 ;
60
61 // column 4
62 dynamic cellSubscribed = sheet.Cells[rowIndex, 4 ];
63 cellSubscribed.Value = customer.Telephone;
64 cellSubscribed.Font.Color = 003399 ;
65 }
66 excel.Visible = true ;
67
68 MessageBox.Show( " 导出成功Excel 中! " );
69 }
70 catch (Exception ex)
71 {
72 MessageBox.Show( " Error generating excel: " + ex.Message);
73 }
74 }
75 }

  如上已经实现导出Excel功能. 但不要忘了设置Silverlight Application 支持OOB.选择Silverlight项目属性. 在属性Silverlight分栏设置:OOB可用。

  右键菜单可见Install Menu选项:

  如上即简单实现Silverlight直接从DataGrid导出Excel表格效果. 仔细分析一下后台代码: 应该发现我使用Silverlight 4和.NET 4版本共有的一个新特性dynamic object。

  在Silverlight 4 和.NEt 4引入Dynamic关键字.让我们可以在不引用MS Office DllS情况下直接操作使用MS Office Com.在.NET 4中创建一个Excel Document如下编码:

1  dynamic excel  =  Microsoft.VisualBasic.Interaction.CreateObject( " Excel.Application " string .Empty);

  在Silverlight 4中:

1  dynamic excel  =  AutomationFactory.CreateObject( " Excel.Application " );

  如上使用Dynamic关键必须引用空间InteropServices: 至于关于空间结构和使用方法可以参见MSDN

1  using  System.Runtime.InteropServices.Automation;
2  using  System.Runtime.InteropServices;

  对于Dynamic关键字现在在.NET去年还是Beta版本很多人对此有些微词,依然还处在一个争论之中。

  Dynamic编码时没有智能提示, 无法再编译时做静态类型检查等.这对于使用惯了.NET 确实让我感到很不舒服. 不过在使用Dynamic时最想让我想到.NET 3.5版本中Var,当var在C#3.0中刚刚出现的时候就引起了一些人的质疑,后来微软解释var只是隐含类型声明符,并且只能用作局部变量,它其实仍然是强类型,只不过是编译器由初始化结果推断而来,所以对这个变量仍然可以可以使用VS的只能提示。现在dynamic则真正往动态特性迈进了一大步,根据Anders的解释,dynamic是指动态的静态类型,也就是说它本质上仍然是静态类型,只不过它告诉编译器忽略对它的静态类型检查,它会在运行时才进行类型检查,它可以应用在基本上所有的C#类型上面,如方法,操作符,索引器,属性,字段,它其实是通过统一的方式来调用方法、属性等操作。

  另外一个很重要地方Anders提到C#的未来时候指出C#4.0的特点是动态编程.在一定程度上Dynamic超越了Var. Var 相当于从3.0 到4.0版本一个过渡品.虽然二者使用方法有很多相似之处. 关于Dynamic更多信息 .Net4.0新特性资料有所说明。

  B:一点疑问

  Silverlight的项目经理Justin Angel详细介绍了如何启动Silverlight应用以使用COM+ 文章中提到Silverlight 4可以通过COM+做的如下事情:

  •   运行命令或者可执行(EXE)文件
  •   读注册表
  •   访问本地ODBC
  •   读/写硬盘(在上文提到的限制条件下)
  •   自动化Office

  因为很多人已经将Silverlight看作另一个Flash播放器,一个可限制访问其运行的计算机上的插件,所以让Silverlight访问COM+引来众多人的关注。一方面它带来了安全问题,另一方面它破坏了对其他平台的可移植性。好几个开发者在WPF Disciples(WPF爱好者)群组中发表评论:

Shawn Wildermuth说:我不想过多地争论。我理解为什么微软这样做,但是我还是认为这样做很不妥。恕我直言,COM只能在Windows下运行对其他平台来说很不爽。

Marlon Grech,微软客户端应用的MVP说:我很赞同Shawn所说的,为SL增加COM+支持违反了跨平台和一次编写处处运行的主张。即使他们为AppleScript增加支持,对我们来说也是噩梦一场。另外……我要说,武器本身没什么问题,关键是使用这些武器的人。对吧?:)

Jeremiah Morrill:在我看来,主要的“概念上”的安全问题是“信任级别”。CoreCLR也还没有授予“完全信任”模式,但这些COM实例,按照定义,是运行在沙箱之外的。我想这会让那些期望或设想得到A,却拿到B的开发者和用户都很迷糊……一般来说,在讨论安全问题时,这是不妥的。

  对于一些人来说,COM+自动化和在高级信任许可下运行Silverlight应用并不是什么安全问题,因为用户需要先安装才能运行OOB应用,他们也被明显警告说应用将会访问他们的硬盘。理论上,这会像其他应用一样,运行一个桌面应用——但是,恐惧恐怕来自于Silverlight被假设成一个运行在沙箱里的绝对安全的浏览器应用,而不是一个桌面应用。

  另外一个问题是移植性。对于缺少COM+的Mac机而言,这个功能有什么用吗?Angel提到说,微软正在调查通过AppleScript在Mac机上支持COM的可能性,并说“如果微软最终没有决定在Mac机上支持Silverlight 4 RTM,那么,并不是因为它不能做到”。对于Moonlight,Angel说:

Moonlight在一开始创建时,就有超级安全的模式。Mono支持在有着完全信任能力的GtkWidget中运行Moonlight。所以,在Silverlight有高级权限模式时,Mono确实完全信任模式。

  同事,系统管理员可以对系统进行配置,以阻止用户安装和运行需要高级信任许可的OOB应用。Group Policy Setting提到了更多关于这方面的信息。

  Silverlight 4增加Com应用 虽然在一定程度满足企业级用户对Silverlight 更为具体需要. 但在一定程度上颠覆Silverlight 在原始设计初衷。

  关于这篇文章请点击这里

  Silverlight 4 从DataGrid导出EXcel演示Demo:源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值