演练:更改服务器上的工作簿中的缓存数据

本演练演示如何修改Microsoft 办公室 Excel 工作簿中缓存的数据集,而无需使用ServerDocument类启动 Excel。

适用于: 本主题中的信息适用于 Excel 的文档级项目。 有关详细信息,请参阅办公室应用程序和项目类型提供的功能。

注意

有兴趣开发跨多个平台扩展办公室体验的解决方案? 查看新的办公室外接程序模型。 与 VSTO 外接程序和解决方案相比,办公室外接程序的占用空间较小,可以使用几乎任何 Web 编程技术(如 HTML5、JavaScript、CSS3 和 XML)生成它们。

本演练阐释了以下任务:

  • 定义包含 AdventureWorksLT 数据库中数据的数据集。

  • 在 Excel 工作簿项目和控制台应用程序项目中创建数据集的实例。

  • 创建绑定到工作簿中的数据集的数据集 ListObject ,并在打开工作簿时填充 ListObject 数据。

  • 将工作簿中的数据集添加到数据缓存。

  • 通过在控制台应用程序中运行代码来修改缓存数据集中的数据列,而无需启动 Excel。

    尽管本演练假定你在开发计算机上运行代码,但本演练演示的代码可以在未安装 Excel 的服务器上使用。

注意

以下说明中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 这些元素取决于你所使用的 Visual Studio 版本和你所使用的设置。 有关详细信息,请参阅个性化设置 Visual Studio IDE

先决条件

你需要满足以下条件才能完成本演练:

创建定义数据集的类库项目

若要在 Excel 工作簿项目和控制台应用程序中使用相同的数据集,必须在这两个项目引用的单独程序集中定义数据集。 对于本演练,请在类库项目中定义数据集。

创建类库项目

  1. 启动 Visual Studio。

  2. “文件” 菜单上,指向 “新建” ,然后单击 “项目”

  3. 在模板窗格中,展开 Visual C#Visual Basic,然后单击 Windows

  4. 在项目模板列表中,选择“ 类库”。

  5. “名称 ”框中,键入 AdventureWorksDataSet

  6. 单击“浏览”,导航到 %UserProfile%\My Documents (适用于 Windows XP 及更早版本)或 %UserProfile%\Documents(对于 Windows Vista)文件夹,然后单击“选择文件夹”。

  7. “新建项目”对话框中,确保未选中解决方案检查框的“创建目录”。

  8. 单击“确定”。

    Visual Studio 将 AdventureWorksDataSet 项目添加到解决方案资源管理器,并打开 Class1.csClass1.vb 代码文件。

  9. 解决方案资源管理器中,右键单击 Class1.csClass1.vb,然后单击“删除”。 本演练不需要此文件。

在类库项目中定义数据集

定义一个类型化数据集,其中包含来自适用于 SQL Server 2005 的 AdventureWorksLT 数据库的数据。 在本演练的后面部分,你将从 Excel 工作簿项目和控制台应用程序项目中引用此数据集。

数据集是一个 类型化数据集 ,表示 AdventureWorksLT 数据库的 Product 表中的数据。 有关类型化数据集的详细信息,请参阅 Visual Studio 中的数据集工具。

在类库项目中定义类型化数据集

  1. 解决方案资源管理器中,单击 AdventureWorksDataSet 项目。

  2. 如果“数据源”窗口不可见,请通过菜单栏选择“查看>其他 Windows>数据源”来显示它。

  3. 选择 “添加新数据源” 以启动 “数据源配置向导”

  4. 单击“数据库” ,然后单击“下一步”

  5. 如果已建立到 AdventureWorksLT 数据库的现有连接,请选择此连接,然后单击“ 下一步”。

    否则,单击“新建连接” ,然后使用“添加连接” 对话框创建新连接。 有关详细信息,请参阅添加新连接

  6. 在“将连接字符串保存到应用程序配置文件中” 页中,单击“下一步”

  7. 在“选择数据库对象”页中,展开“表”,然后选择“产品”(SalesLT)。

  8. 单击“完成” 。

    AdventureWorksLTDataSet.xsd 文件将添加到 AdventureWorksDataSet 项目。 此文件定义以下各项:

    • 一个名为 AdventureWorksLTDataSet的类型化数据集。 此数据集表示 AdventureWorksLT 数据库中 Product 表的内容。

    • 名为 ProductTableAdapterTableAdapter 的表。 此 TableAdapter 可用于读取和写入数据 AdventureWorksLTDataSet。 有关详细信息,请参阅 TableAdapter 概述

      在本演练后面的部分中,你将使用这两个对象。

  9. 解决方案资源管理器中,右键单击 AdventureWorksDataSet,然后单击“生成”。

    验证此项目是否已生成且未发生错误。

创建 Excel 工作簿项目

为数据接口创建 Excel 工作簿项目。 在本演练的后面部分,你将创建一个 ListObject 显示数据的实例,并将数据集的实例添加到工作簿中的数据缓存中。

创建 Excel 工作簿项目

  1. 解决方案资源管理器中,右键单击 AdventureWorksDataSet 解决方案,指向“添加”,然后单击“新建项目”。

  2. 在模板窗格中,展开 Visual C#Visual Basic,然后展开办公室

  3. 在展开办公室节点下,选择 2010 节点。

  4. 在项目模板列表中,选择 Excel 工作簿项目。

  5. “名称 ”框中,键入 AdventureWorksReport。 请勿修改位置。

  6. 单击“确定”。

    将打开“Visual Studio Tools for Office 项目向导”

  7. 确保 已选择“创建新文档 ”,然后单击“ 确定”。

    Visual Studio 在设计器中打开 AdventureWorksReport 工作簿,并将 AdventureWorksReport 项目添加到解决方案资源管理器

将数据集添加到 Excel 工作簿项目中的数据源

在 Excel 工作簿中显示数据集之前,必须先将数据集添加到 Excel 工作簿项目中的数据源。

将数据集添加到 Excel 工作簿项目中的数据源

  1. 解决方案资源管理器中,双击 AdventureWorksReport 项目下的 Sheet1.csSheet1.vb

    工作簿将在设计器中打开。

  2. “数据” 菜单上,单击 “添加新数据源”

    “数据源配置”向导随即打开。

  3. 单击“对象”,然后单击“下一步”。

  4. “选择要绑定到 的对象”页中,单击“ 添加引用”。

  5. “项目 ”选项卡上,单击 AdventureWorksDataSet ,然后单击“ 确定”。

  6. AdventureWorksDataSet 程序集的 AdventureWorksDataSet 命名空间下,单击 AdventureWorksLTDataSet,然后单击“完成”。

    数据源” 窗口随即打开, AdventureWorksLTDataSet 将添加到数据源列表。

创建绑定到数据集实例的 ListObject

若要在工作簿中显示数据集,请创建 ListObject 绑定到数据集实例的数据集。 有关将数据绑定控件的详细信息,请参阅将数据绑定到办公室解决方案中的控件。

创建绑定到数据集实例的 ListObject

  1. “数据源”窗口中,展开 AdventureWorksDataSet 下的 AdventureWorksLTDataSet 节点。

  2. 选择“产品”节点,单击显示的下拉箭头,然后在下拉列表中选择 ListObject

    如果未显示下拉箭头,请确认工作簿在设计器中处于打开状态。

  3. Product 表拖到单元格 A1。

    ListObject命名productListObject的控件在工作表上创建,从单元格 A1 开始。 同时,向项目添加了一个名为 adventureWorksLTDataSet 的数据集对象和一个名为 BindingSourceproductBindingSource 。 已将 ListObject 绑定到 BindingSource,而后者又绑定到该数据集对象。

将数据集添加到数据缓存

若要在 Excel 工作簿项目外部启用代码以访问工作簿中的数据集,必须将数据集添加到数据缓存中。 有关数据缓存的详细信息,请参阅 文档级自定义缓存数据中的缓存数据

将数据集添加到数据缓存

  1. 在设计器中,单击 adventureWorksLTDataSet

  2. “属性” 窗口中,将 “修饰符 ”属性设置为 “公共”。

  3. CacheInDocument 属性设置为 True

初始化工作簿中的数据集

必须先使用数据填充缓存数据集,然后才能使用控制台应用程序从缓存数据集中检索数据。

初始化工作簿中的数据集

  1. 解决方案资源管理器中,右键单击 Sheet1.csSheet1.vb 文件,然后单击“查看代码”。

  2. Sheet1_Startup 事件处理程序替换为以下代码。 此代码使用 AdventureWorksDataSet 项目中定义的类实例ProductTableAdapter,以使用数据填充缓存的数据集(如果当前为空)。

    private AdventureWorksDataSet.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter productTableAdapter =
        new AdventureWorksDataSet.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter();
    
    private void Sheet1_Startup(object sender, System.EventArgs e)
    {
        if (this.NeedsFill("adventureWorksLTDataSet"))
        {
            this.productTableAdapter.Fill(this.adventureWorksLTDataSet.Product);
        }
    }
    

检查点

生成并运行 Excel 工作簿项目,以确保它编译并运行,而不会出错。 此操作还会填充缓存的数据集,并将数据保存在工作簿中。

生成并运行此项目

  1. 解决方案资源管理器中,右键单击 AdventureWorksReport 项目,选择“调试”,然后单击“启动新实例”。

    该项目已生成,工作簿将在 Excel 中打开。 检查下列各项:

    • 填充 ListObject 数据。

    • 第一行ListObject的 ListPrice 列中的值为 1431.5。 在本演练的后面部分,你将使用控制台应用程序修改 ListPrice 列中的值

  2. 保存工作簿。 请勿修改工作簿的文件名或位置。

  3. 关闭 Excel。

创建控制台应用程序项目

创建用于修改工作簿中缓存数据集中的数据的控制台应用程序项目。

创建控制台应用程序项目

  1. 解决方案资源管理器中,右键单击 AdventureWorksDataSet 解决方案,指向“添加”,然后单击“新建项目”。

  2. “项目类型 ”窗格中,展开 Visual C#Visual Basic,然后单击“ Windows”。

  3. “模板”窗格中,选择“控制台应用程序”

  4. “名称 ”框中,键入 DataWriter。 请勿修改位置。

  5. 单击“确定”。

    Visual Studio 将 DataWriter 项目添加到解决方案资源管理器并打开 Program.csModule1.vb 代码文件。

使用控制台应用程序更改缓存数据集中的数据

ServerDocument使用控制台应用程序中的类将数据读入本地AdventureWorksLTDataSet对象,修改此数据,然后将其保存回缓存数据集。

更改缓存数据集中的数据

  1. 解决方案资源管理器中,右键单击 DataWriter 项目,然后单击“添加引用”。

  2. .NET 选项卡上,选择 Microsoft.VisualStudio.Tools.Applications

  3. 单击“确定”。

  4. 解决方案资源管理器中,右键单击 DataWriter 项目,然后单击“添加引用”。

  5. “项目 ”选项卡上,选择 AdventureWorksDataSet,然后单击“ 确定”。

  6. 代码编辑器中打开 Program.csModule1.vb 文件。

  7. 将以下 using (for C#) 或 Imports (for Visual Basic) 语句添加到代码文件的顶部。

    using Microsoft.VisualStudio.Tools.Applications;
    
  8. 将以下代码添加到 Main 方法中。 此代码声明以下对象:

    • AdventureWorksDataSet 项目中定义的类型的实例AdventureWorksLTDataSet

    • AdventureWorksReport 项目的生成文件夹中 AdventureWorksReport 工作簿的路径。

    • ServerDocument用于访问工作簿中的数据缓存的对象。

      注意

      以下代码假定你使用的是扩展名 为 .xlsx 的工作簿。 如果项目中的工作簿具有其他文件扩展名,请根据需要修改路径。

      AdventureWorksDataSet.AdventureWorksLTDataSet productDataSet =
          new AdventureWorksDataSet.AdventureWorksLTDataSet();
      string workbookPath = System.Environment.GetFolderPath(
          Environment.SpecialFolder.MyDocuments) +
          @"\AdventureWorksReport\bin\Debug\AdventureWorksReport.xlsx";
      ServerDocument serverDocument1 = null;
      

  9. 在上一步中添加的代码之后,将以下代码添加到 Main 方法。 此代码执行以下任务:

    • 它使用 CachedData 类的属性 ServerDocument 访问工作簿中的缓存数据集。

    • 它将缓存数据集中的数据读取到本地数据集中。

    • 它会更改 ListPrice 数据集的 Product 表中每个产品的值。

    • 它将更改保存到工作簿中的缓存数据集。

      try
      {
          serverDocument1 = new ServerDocument(workbookPath);
          CachedDataHostItem dataHostItem1 =
              serverDocument1.CachedData.HostItems["AdventureWorksReport.Sheet1"];
          CachedDataItem dataItem1 = dataHostItem1.CachedData["adventureWorksLTDataSet"];
      
          if (dataItem1 != null)
          {
              Console.WriteLine("Before reading data from the cache dataset, the local dataset has " +
                  "{0} rows.", productDataSet.Product.Rows.Count.ToString());
      
              // Read the cached data from the worksheet dataset into the local dataset.
              System.IO.StringReader schemaReader = new System.IO.StringReader(dataItem1.Schema);
              System.IO.StringReader xmlReader = new System.IO.StringReader(dataItem1.Xml);
              productDataSet.ReadXmlSchema(schemaReader);
              productDataSet.ReadXml(xmlReader);
      
              Console.WriteLine("After reading data from the cache dataset, the local dataset has " +
                  "{0} rows.", productDataSet.Product.Rows.Count.ToString());
      
              // Modify the prices of each product in the local dataset.
              foreach (AdventureWorksDataSet.AdventureWorksLTDataSet.ProductRow row in 
                       productDataSet.Product.Rows)
              {
                  if (row.ProductCategoryID < 20)
                  {
                      row.ListPrice = row.ListPrice + (row.ListPrice * (Decimal).10);
                  }
                  else
                  {
                      row.ListPrice = row.ListPrice - (row.ListPrice * (Decimal).10);
                  }
              }
      
              // Write the modified local dataset to the worksheet dataset using the DiffGram format.
              System.Text.StringBuilder stringIn = new System.Text.StringBuilder();
              System.IO.StringWriter stringOut = new System.IO.StringWriter(stringIn);
              productDataSet.WriteXml(stringOut, System.Data.XmlWriteMode.DiffGram);
              dataItem1.Xml = stringIn.ToString();
      
              serverDocument1.Save();
              Console.WriteLine("The product prices have been modified.");
          }
          else
          {
              Console.WriteLine("The data object is not found in the data cache.");
          }
      }
      catch (System.IO.FileNotFoundException)
      {
          Console.WriteLine("The specified workbook does not exist.");
      }
      catch (System.Xml.XmlException)
      {
          Console.WriteLine("The data object has invalid XML information.");
      }
      finally
      {
          if (serverDocument1 != null)
          {
              serverDocument1.Close();
          }
      
          Console.WriteLine("\n\nPress Enter to close the application.");
          Console.ReadLine();
      }
      

  10. 解决方案资源管理器中,右键单击 DataWriter 项目,指向“调试”,然后单击“启动新实例”。

    控制台应用程序在将缓存数据集读取到本地数据集时显示消息,修改本地数据集中的产品价格,并将新值保存到缓存的数据集。 按 Enter 关闭应用程序。

测试工作簿

打开工作簿时, ListObject 现在会显示对缓存数据集中的数据列所做的更改 ListPrice

测试工作簿

  1. 关闭 Visual Studio 设计器中的 AdventureWorksReport 工作簿(如果它仍处于打开状态)。

  2. 打开 AdventureWorksReport 项目生成文件夹中的 AdventureWorksReport 工作簿。 默认情况下,生成文件夹位于以下位置之一:

    • %UserProfile%\My Documents\AdventureWorksReport\bin\Debug (适用于 Windows XP 和更早版本)

    • %UserProfile%\Documents\AdventureWorksReport\bin\Debug (适用于 Windows Vista)

  3. 验证 ListPrice 列中的第一行ListObject的值现在是否为 1574.65。

  4. 关闭此工作簿。