Silverlight 4中把DataGrid數據導出Excel—附源碼下載

作者: chenkai  來源: 博客園  發布時間: 2010-10-14 07:14  閱讀: 3589 次  推薦: 0   原文鏈接   [收藏]  

  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 { getset; }
 4         public string CustomerName { getset; }
 5         public string Address { getset; }
 6         public string Telephone { getset; }
 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:源碼下載

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()