Silverlight實例教程 - Out of Browser與Office的互操作
Silverlight 實例教程索引
- Silverlight 實例教程 - Out of Browser開篇
- Silverlight 實例教程 - Out of Browser配置,安裝和卸載
- Silverlight 實例教程 - Out of Browser的自定義應用
- Silverlight 實例教程 - Out of Browser存取本地文件系統
- Silverlight 實例教程 - Out of Browser與COM的交互基礎
- Silverlight 實例教程 - Out of Browser與Office的互操作
- Silverlight 實例教程 - Out of Browser的Debug和Notifications窗口
- Silverlight 實例教程 - Out of Browser音樂播放器
- Silverlight 實例教程 - Out of Browser與COM互操作實例
- Silverlight 實例教程 - Out of Browser在線更新和Silent安裝
在上篇“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來響應其事件。
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>
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的相應事件: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(0, 0);
9
10 range.Text = Insertxt;
11 }
在創建Word實例后,使用Documents.Add創建一個新的空文檔,然后,添加相關文檔或者圖片到Word中。其運行效果如下:
相對上面兩個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,所有控件和數據綁定,都是簡單的拖動即可實現。
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組件調用代碼。
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進行一些強化,輸入一個圖表功能。對我們當前的代碼進行簡單的修改,添加如下代碼:
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(-4100, 200, 2, 400, 300);
28
29 }
sheepShapes.AddChart創建一個新的圖表效果,其數據是綁定的dynamic sheet = excel.ActiveSheet 。這樣當我們再次運行輸出Excel時,即可得到如下結果:
這些功能的實現,完全是調用了Excel中提供的組件功能。下面我們更進一步的完善Excel輸入功能,添加自動綁定更新事件。其目的是為了實現,當用戶輸出Excel后,修改Excel中數據,Silverlight的OOB應用中Datagrid同時也更新修改對應數據。實現該需求,需要用到Excel的SheetChange事件。當用戶修改Excel中內容時,即激活該事件。首先,我們需要修改以上代碼。
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(-4100, 200, 2, 400, 300);
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,我們需要添加相關事件委托:
其具體事件響應Handler為:
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的具體方法,以及常用功能,大家可以在這個基礎上進行擴展,將其應用于自己的應用中。