zoukankan      html  css  js  c++  java
  • Silverlight实例教程 Out of Browser与Office的互操作

    在本篇开始前,首先感谢每一位留下反馈评论的朋友,在我看来,博客不仅仅是简单的分享,同时也是一个学习和发现的过程。在阅读完一篇文章能对其有所评论和提问,也是一种思考的表现。

    在上篇“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的具体方法,以及常用功能,大家可以在这个基础上进行扩展,将其应用于自己的应用中。

    本篇源代码下载

    欢迎大家加入"专注Silverlight" 技术讨论群:

    32679955(六群)
    23413513(五群)
    32679922(四群)
    100844510(三群)
    37891947(二群)
    22308706(一群)
  • 相关阅读:
    mysql将一个表的数据 重复复制多份到表中
    PHP中将指定文本内容导入到word中
    系统安全-SElinux
    通过身份证号码提取年龄,性别
    MySQL-获取某天的数据
    mysql-介绍、MySQL部署、数据类型、存储引擎
    监控系统-ELK
    监控系统-Grafana
    监控系统-zabbix
    监控系统-openfalcon
  • 原文地址:https://www.cnblogs.com/jv9/p/1784102.html
Copyright © 2011-2022 走看看