Silverlight實例教程 - Out of Browser與Office的互操作

作者: jv9  來源: 博客園  發布時間: 2010-08-15 10:18  閱讀: 2721 次  推薦: 0   原文鏈接   [收藏]  

  Silverlight 實例教程索引

  在上篇“Silverlight實例教程 - Out of Browser與COM的交互基礎”中,我們討論了Silverlight的OOB應用訪問COM組件基礎知識,在大家的反饋中,有不少朋友提出疑問,Silverlight對于COM的支持,使其失去跨平臺的優越性,另外,Silverlight僅有Out of Browser模式能支持COM,是否仍舊存在較大的局限性? 對此在本篇我們不進行長篇分析和討論,只是簡單的把我的看法說一下。

  Silverlight Out of Browser從Silverlight 3 到現在Silverlight 4,一直遵循跨平臺的原則,在微軟官方有相關的解釋,

Linux,Moonlight從第一個版本發布,就已經有了高級權限模型,在GtkWidget中Moonlight具有full-trust的能力。 也就是說,Silverlight具有信任權限提升,而Mono具有full-trust模式。

  Mac, 由于Mac沒有Com的概念,所以,Silverlight的COM無法在Mac中運行,但是微軟官方也正在尋找一種方式,嘗試使用一種模擬的方式來實現在Mac上運行COM的效果,例如,運行AppleScript:

  在上面的腳本中可以看出,Mac如何通過AppleScript來調用Office Word的,而這樣的方式其實也就是Mac對COM的調用,在以后Silverlight的版本中,如果加入對AppleScripts的支持即可在Mac上支持COM的運行;

  從上面的描述來看,Silverlight的OOB應用跨平臺,并非不能解決,只是時間的問題。作為技術人員,經常對一門技術的前景進行展望,而需要注意的是,盡量不要使用其短處與其他技術的長處進行相比較,這樣的對比結果,只會干擾自己的視線和思路。一門能掙錢的技術,就已經算是一門好技術了。

  Out of Browser與Office的互操作

  言歸正傳,本篇將繼續介紹Silverlight的Out of Browser應用與Office COM組件的交互。相信大家對微軟的Office系列并不陌生了,Office在企業項目中使用頻率較高,例如在日常項目中經常與遇到導出列表到Excel,或者發送郵件等功能需求,所以微軟將其許多功能封裝成COM組件,供開發人員使用,增強其應用的靈活性。本篇,我將演示在Silverlight的OOB應用中,如何使用Office Outlook,Word,Excel組件

  我們仍舊使用上篇的項目代碼,對其進行擴展,大家可以到上篇下載演示項目代碼。在開始功能代碼前,首先需要在UI界面ToolBar中添加三個Button來響應其事件。

 1 <Border BorderBrush="{StaticResource GlossyBlack_StrokeGradient}" BorderThickness="1" CornerRadius="2" Margin="1" Padding="0,1,1,1">
 2       <StackPanel>
 3             <StackPanel Orientation="Horizontal">
 4                  <Button IsTabStop="False" Width="56" Height="80" Style="{StaticResource BlackGlossyButton}" Margin="1,0,0,0" Foreground="White"  x:Name="sendemailBtn" Click="sendemailBtn_Click">
 5                        <StackPanel>
 6                              <Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="/SilverlightOOBDemo;component/Images/SendEmail.png" Margin="0,-5,0,0" Stretch="None" />
 7                              <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,3,0,0" Text="發郵件" TextWrapping="Wrap"/>
 8                         </StackPanel>
 9                   </Button>
10 
11                   <Button IsTabStop="False" Width="56" Height="80" Style="{StaticResource BlackGlossyButton}" Margin="1,0,0,0" Foreground="White"  x:Name="excelBtn" Click="excelBtn_Click">
12                         <StackPanel>
13                             <Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="/SilverlightOOBDemo;component/Images/Excel.png" Margin="0,-5,0,0" Stretch="None" />
14                             <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,3,0,0" Text="Excel" TextWrapping="Wrap"/>
15                         </StackPanel>
16                   </Button>
17 
18                   <Button IsTabStop="False" Width="56" Height="80" Style="{StaticResource BlackGlossyButton}" Margin="1,0,0,0" Foreground="White"  x:Name="wordBtn" Click="wordBtn_Click">
19                         <StackPanel>
20                             <Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="/SilverlightOOBDemo;component/Images/Word.png" Margin="0,-5,0,0" Stretch="None" />
21                             <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,3,0,0" Text="Word" TextWrapping="Wrap"/>
22                         </StackPanel>
23                   </Button>
24      </StackPanel>
25      <TextBlock Foreground="#8FFFFFFF" Text="Office操作" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="2" />
26      </StackPanel>
27  </Border>
  對與三個應用分別添加其Click事件代碼。首先,我們先看看OutLook的COM調用。
 1 private void sendemailBtn_Click(object sender, RoutedEventArgs e)
 2 {
 3             using (dynamic outlook = AutomationFactory.CreateObject("Outlook.Application"))
 4             {
 5                 dynamic mail = outlook.CreateItem(0);
 6                 mail.To = "qq34506@hotmail.com";
 7                 mail.Subject = "來自jv9的問候";
 8                 mail.HTMLBody = "這封郵件是通過Silverlight發送的.";
 9                 mail.Send();
10                 //mail.Display();  這里是顯示出發送郵件的Outlook窗口
11              }
12 }

  在建立Outlook實例后,我們可以使用Outlook.CreateItem來創建新的郵件實例,其中可以簡單的設置發送目的郵箱,標題,內容等。在代碼后面有mail.Send和Display兩個方法。其中如果調用Display,Silverlight會激活Outlook創建郵件窗口,然后用戶確認后發送郵件到目的郵箱。例如:

  而調用mail.Send則會直接發送郵件到目的郵箱。而通常來說,我們建議使用mail.Display,讓用戶確認后再發送。

  Silverlight操作Office Word

Silverlight操作Office Word比較簡單,首先我們添加Word的相應事件:
 1 private void wordBtn_Click(object sender, RoutedEventArgs e)
 2 {
 3             dynamic word = AutomationFactory.CreateObject("Word.Application");
 4             word.Visible = true;
 5             dynamic doc = word.Documents.Add();
 6 
 7             string Insertxt = "這是Silverlight操作Office Word測試。歡迎大家訪問我的博客 http://jv9.cnblogs.com";
 8             dynamic range = doc.Range(00);
 9 
10             range.Text = Insertxt;
11 }

  在創建Word實例后,使用Documents.Add創建一個新的空文檔,然后,添加相關文檔或者圖片到Word中。其運行效果如下:

  Silverlight操作Office Excel

  相對上面兩個Office組件來講,Excel的使用較為復雜一點,這里我們來詳細演示Silverlight導出Excel的實例。操作Excel不可缺少的是數據庫,作為演示實例,我使用Blend 4創建簡單的數據集合,使用Blend創建例程數據集合,我曾經在Blend實例系列中講過,這里我將簡單的演示。首先使用Blend 4打開當前SilverlightOOBDemo項目,然后在右邊屬性欄,選擇Data。

  這時會提示輸入SampleDataSource名稱:

  點擊OK后,Blend 4將自動生成一個數據集合。

  由于是Blend 4自動生成的,其中的String和Number都是隨機生成的,這些對于演示實例已經足夠了。

  當SampleDataSource創建完成后,在SliverlightOOBDemo項目中,會創建一個SampleData目錄,其中包含了我們定義的數據源。

  現在,需要在UI中創建一個Datagrid的控件,然后拖動右邊Data下SampleDataSource1下的Collection到Datagrid,進行數據綁定,這里我仍舊使用了Blend 4,所有控件和數據綁定,都是簡單的拖動即可實現。

1 <sdk:DataGrid x:Name="dgDemo" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding Collection}" DataContext="{Binding Source={StaticResource SampleDataSource1}}" >
2      <sdk:DataGrid.Columns>
3             <sdk:DataGridTextColumn Binding="{Binding Property1}" Header="Property1"/>
4             <sdk:DataGridTextColumn Binding="{Binding Property2}" Header="Property2"/>
5             <sdk:DataGridTextColumn Binding="{Binding Property3}" Header="Property3"/>
6      </sdk:DataGrid.Columns>
7                             
8  </sdk:DataGrid>

  以上設置,我們添加了Sample數據源,并且綁定數據到指定datagrid中,現在,可以設計Excel組件調用代碼。

 1 bool firstTime = true;
 2  public ObservableCollection<Item> itemCollection = new ObservableCollection<Item>();
 3  private void excelBtn_Click(object sender, RoutedEventArgs e)
 4 {
 5             dynamic excel = AutomationFactory.CreateObject("Excel.Application");
 6             excel.Visible = true;  
 7             dynamic workbook = excel.workbooks;
 8             workbook.Add();
 9             dynamic sheet = excel.ActiveSheet; 
10             dynamic cell = null;
11             int i = 1;
12             // 將數據傳輸到Excel
13              foreach (Item item in dgDemo.ItemsSource)
14             {
15                 itemCollection.Add(item);
16                 cell = sheet.Cells[i, 1]; // 列和行
17                  cell.Value = item.Property1;
18                 cell.ColumnWidth = 25;
19 
20                 cell = sheet.Cells[i, 2];
21                 cell.Value = item.Property3;
22                 i++;
23             }
24 
25 }

  在上面代碼中,聲明一個Excel實例,然后通過循環輸入數據源到Excel實例Sheet中,從代碼中我們可以看出,輸出Excel是通過Cell進行操作的。這里,我僅輸出了Property1和Property3兩列。這樣就簡單的實現了輸出Datagrid的數據到Excel了。

  現在我們對當前的輸出Excel進行一些強化,輸入一個圖表功能。對我們當前的代碼進行簡單的修改,添加如下代碼:

 1 bool firstTime = true;
 2  public ObservableCollection<Item> itemCollection = new ObservableCollection<Item>();
 3  private void excelBtn_Click(object sender, RoutedEventArgs e)
 4 {
 5             dynamic excel = AutomationFactory.CreateObject("Excel.Application");
 6             excel.Visible = true;  
 7             dynamic workbook = excel.workbooks;
 8             workbook.Add();
 9             dynamic sheet = excel.ActiveSheet; 
10             dynamic cell = null;
11             int i = 1;
12             // 將數據傳輸到Excel
13              foreach (Item item in dgDemo.ItemsSource)
14             {
15                 itemCollection.Add(item);
16                 cell = sheet.Cells[i, 1]; // 列和行
17                  cell.Value = item.Property1;
18                 cell.ColumnWidth = 25;
19 
20                 cell = sheet.Cells[i, 2];
21                 cell.Value = item.Property3;
22                 i++;
23             }
24 
25             // 創建一個例程圖表
26              dynamic sheetShapes = sheet.Shapes;
27             sheetShapes.AddChart(-41002002400300);
28 
29 }

  sheepShapes.AddChart創建一個新的圖表效果,其數據是綁定的dynamic sheet = excel.ActiveSheet 。這樣當我們再次運行輸出Excel時,即可得到如下結果:

  這些功能的實現,完全是調用了Excel中提供的組件功能。下面我們更進一步的完善Excel輸入功能,添加自動綁定更新事件。其目的是為了實現,當用戶輸出Excel后,修改Excel中數據,Silverlight的OOB應用中Datagrid同時也更新修改對應數據。實現該需求,需要用到Excel的SheetChange事件。當用戶修改Excel中內容時,即激活該事件。首先,我們需要修改以上代碼。

 1 bool firstTime = true;
 2  public ObservableCollection<Item> itemCollection = new ObservableCollection<Item>();
 3  private void excelBtn_Click(object sender, RoutedEventArgs e)
 4 {
 5             dynamic excel = AutomationFactory.CreateObject("Excel.Application");
 6             excel.Visible = true;  
 7             dynamic workbook = excel.workbooks;
 8             workbook.Add();
 9             dynamic sheet = excel.ActiveSheet; 
10             dynamic cell = null;
11             int i = 1;
12             // 將數據傳輸到Excel
13              foreach (Item item in dgDemo.ItemsSource)
14             {
15                 itemCollection.Add(item);
16                 cell = sheet.Cells[i, 1]; // 列和行
17                  cell.Value = item.Property1;
18                 cell.ColumnWidth = 25;
19 
20                 cell = sheet.Cells[i, 2];
21                 cell.Value = item.Property3;
22                 i++;
23             }
24 
25             // 創建一個例程圖表
26              dynamic sheetShapes = sheet.Shapes;
27             sheetShapes.AddChart(-41002002400300);
28 
29             // 更新事件
30              if (firstTime)
31             {
32                 excel.SheetChange += new SheetChangedDelegate(SheetChangedEventHandler);
33                 string sheetName = sheet.Name;
34 
35                 firstTime = false;
36             }
37 
38 }

  為了完成SheetChange,我們需要添加相關事件委托:

1 delegate void SheetChangedDelegate(dynamic excelSheet, dynamic rangeArgs);

  其具體事件響應Handler為:

 1         private void SheetChangedEventHandler(dynamic excelSheet, dynamic rangeArgs)
 2         {
 3             dynamic sheet = excelSheet;
 4             string sheetName = sheet.Name;
 5             dynamic range = rangeArgs;
 6             dynamic rowValue = range.Row;
 7             ObservableCollection<Item> entities = itemCollection;
 8             Item[] newEntities = new Item[10];
 9 
10             dynamic col2range = sheet.Range("B1:B10");
11 
12             for (int i = 0; i < 10; i++)
13             {
14                 Item newEntity = new Item();
15                 newEntity.Property1 = entities[i].Property1;
16                 newEntity.Property2 = entities[i].Property2;
17 
18                 dynamic item = col2range.Item(i + 1);
19                 newEntity.Property3 = Convert.ToInt32(item.Value);
20 
21                 newEntities[i] = newEntity;
22             }
23             dgDemo.ItemsSource = newEntities;
24             dgDemo.SelectedIndex = Convert.ToInt32(rowValue) - 1;
25         }

  這里,我設置操作sheet范圍為B1:B10,僅處理這個區域表格中數據綁定,而當excel中數據變化,則會查找對應表格到Datagrid的表格中進行更新。其運行效果,當用戶修改Excel中的B1-B10中的數據,同時Datagrid會產生更新,并且Excel圖表也會產生更新效果。

  上述介紹了Silverlight 4調用Office COM的具體方法,以及常用功能,大家可以在這個基礎上進行擴展,將其應用于自己的應用中。

0
0
 
標簽:Silverlight
 
 

文章列表

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

    IT工程師數位筆記本

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