使用OpenXML更新Word文档中的表格

【网通】点击此处下载源程序                 【电信、网通】点击此处下载源程序
【网通】点击此处下载演示工程             【电信、网通】点击此处下载演示程序

【下载说明】
1、单击上面这个地址,打开下载页面。
2、点普通下载--等待30秒--点“下载”按钮--保存

点击此处查看原文

介绍
这篇文章包含了怎么样使用OpenXML 2.0去更新Word文档中的图表的方法。


背景
假设你有一个Word文档,并且你想要更新其中一个图表的一些值。当我使用谷歌搜索怎么做的时候,我看过了不少的例子。但是那些文章通常遗忘了一个事实,那就是你需要再次打开Word文档,在图表上点击右键,打开“编辑数据”,然后为了让这些值得到更新而要关闭电子表格。这个程序将会告诉你怎么样自动完成这些。


使用代码
在一个Word文档中添加一个图表

启动Microsoft Word 2007(或后续版本)
导航到“插入”页
在图表窗口中,选择一个图表的图标
在这里例子中,添加一个3D的列图表,通过在列模板上选择它
这将会打开一个具有默认值得电子表格,关闭窗口。
之后图表会出现在Word文档中
保存文档并退出。
实现细节
为了更新Word文档中的图表,你需要像下面这么做:
更新电子表格的单元格
获取docx文件中的图表部分
通过电子表格的单元格找到要更新的元素
更新所要更新的元素
保存文档

在UpdateChart和InsertCellInWorksheet方法中的代码,我仅仅是找到某个地方然后使用了它。
这些方法通过在谷歌上搜索更新图表,你就能找到它们。
然后,我创建了ModifyChartSimplified和ModifyChartDetailed方法来实际上更新Word文档。
ModifyChartSimplified和ModifyChartDetailed方法实际上做的是同样的事情,但是他们阐述了寻找到Word文档中的XML元素的方法。
如果你使用Deflector工具来打开Word文档,并点击了Chart元素下面的/word/document.xml的话,你需要在很下方才能看到存储图表数据的XML数据。
下面我仅仅是演示将“Series 1”XML数据存储到文档中:
<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"  
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"  
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <c:date1904 val="1" />
  <c:lang val="en-US" />
  <c:chart>
    <c:view3D>
      <c:perspective val="30"  />
    </c:view3D>
    <c:plotArea>
      <c:layout />
      <c:bar3DChart>
        <c:barDir val="col" />
        <c:grouping  val="clustered" />
        <c:ser>
           <c:idx val="0" />
           <c:order val="0" />
           <c:tx>
            <c:strRef>
              <c:f>Sheet1!$B$1</c:f>
              <c:strCache>
                 <c:ptCount val="1"  />
                 <c:pt idx="0">
                    <c:v>Series  1</c:v>
                 </c:pt>
              </c:strCache>
            </c:strRef>
           </c:tx>
           <c:cat>
             <c:strRef>
               <c:f>Sheet1!$A$2:$A$5</c:f>
               <c:strCache>
                 <c:ptCount val="4"  />
                 <c:pt idx="0">
                    <c:v>Category  1</c:v>
                 </c:pt>
                 <c:pt idx="1">
                     <c:v>Category  2</c:v>
                 </c:pt>
                 <c:pt idx="2">
                    <c:v>Category  3</c:v>
                 </c:pt>
                 <c:pt idx="3">
                    <c:v>Category  4</c:v>
                 </c:pt>
               </c:strCache>
             </c:strRef>
            </c:cat>
            <c:val>
              <c:numRef>
                <c:f>Sheet1!$B$2:$B$5</c:f>
                <c:numCache>
                   <c:formatCode>General</c:formatCode>
                   <c:ptCount val="4"  />
                   <c:pt idx="0">
                     <c:v>4.3</c:v>
                   </c:pt>
                   <c:pt idx="1">
                      <c:v>2.5</c:v>
                   </c:pt>
                   <c:pt idx="2">
                      <c:v>3.5</c:v>
                   </c:pt>
                   <c:pt idx="3">
                      <c:v>4.5</c:v>
                   </c:pt>
                </c:numCache>
              </c:numRef>
            </c:val>
        </c:ser>

如果你看过了我写的ModifiedDetailed方法,你会看到我基本上一个一个元素来获取的。对于学习OpenXML格式,这将是一个很棒的练习。
private void ModifyChartDetailed
(string  cellColumn, uint intRow, string cellValue, bool  axisValue)
{
  try
  {
    ChartPart  c_p = this.mainDocPart.ChartParts.FirstOrDefault();
    Chart  chart = c_p.ChartSpace.Descendants<Chart>().FirstOrDefault();
    PlotArea  p_c = chart.PlotArea;
    Bar3DChart  b3d = p_c.Descendants<Bar3DChart>().FirstOrDefault();
    BarChartSeries  bs1 = b3d.Descendants<BarChartSeries>().Where(s  => 
    string.Compare(s.InnerText, "Sheet1!$" + cellColumn + "$1", true)  > 0).First();
    if  (axisValue)
    {
      CategoryAxisData  v1 = bs1.Descendants<CategoryAxisData>().FirstOrDefault();
      StringReference  sr = v1.Descendants<StringReference>().First();
      StringCache  sc = sr.Descendants<StringCache>().First();
      StringPoint  sp = sc.Descendants<StringPoint>().First();
      NumericValue  nv = sp.Descendants<NumericValue>().First();
      nv.Text = cellValue;
    }
    else
    {
      DocumentFormat.OpenXml.Drawing.Charts.Values v1 =  bs1.Descendants;
      DocumentFormat.OpenXml.Drawing.Charts.Values>().FirstOrDefault();
      NumberReference  nr = v1.Descendants<NumberReference>().First();
      NumberingCache  nc = nr.Descendants<NumberingCache>().First();
      NumericPoint  np = nc.Descendants<NumericPoint>().ElementAt((int)intRow - 2);
      NumericValue  nv = np.Descendants<NumericValue>().First();
      nv.Text = cellValue;
     }
  }
  catch
  {
    // Chart Element is not in a recognizable format. 
    // Most likely the defined Chart is  incorrect. Ignore the chart creation.
    return;
   }
  }

在ModifyChartSimplified方法中,我仅仅是直接找到我要更新的元素,然后直接更新的。
private void ModifyChartSimplified
(string  cellColumn, uint intRow, string cellValue, bool  axisValue)
{
  try
  {
    ChartPart  c_p = this.mainDocPart.ChartParts.FirstOrDefault();
    BarChartSeries  bs1 = c_p.ChartSpace.Descendants<BarChartSeries>().Where
    (s  => string.Compare(s.InnerText, "Sheet1!$" + 
		cellColumn + "$1", true)  > 0).First();
    if  (axisValue)
    {
       NumericValue  nv1 = bs1.Descendants<NumericValue>().First();
       nv1.Text = cellValue;
     }
     else
     {
       DocumentFormat.OpenXml.Drawing.Charts.Values  v1 = 
       bs1.Descendants<DocumentFormat.OpenXml.Drawing.Charts.Values>().FirstOrDefault();
       NumericPoint  np = v1.Descendants<NumericPoint>().ElementAt((int)intRow - 2);
       NumericValue  nv = np.Descendants<NumericValue>().First();
       nv.Text = cellValue;
     }
  }
  catch
  {
     // Chart Element is not in a recognizable format. 
     // Most likely the defined Chart is  incorrect. Ignore the chart creation.
     return;
  }
}

感兴趣的地方
使用Deflector工具真的帮助了我很多,让我更好的理解OpenXML SDK是怎么工作的。刚开始看的时候,可能会感觉很难,但是值得深入的去了解的。
请自由的发布对于这篇文章的改进或批评。当我通过谷歌搜索怎么样在一个图像放置狂里面插入图像时,我发现了有不少的文章直接使用XML去查找更新的位置。我意识到肯定有一个更简单的方法来使用OpenXML,我相信肯定有。

修订历史

V1 - April 28, 2011 - 创建了应用程序并发布

【更多阅读】

  1. [译]在C#中使用J#运行时来压缩与解压缩
  2. [原]Hotkey.cs:为应用程序添加热键
  3. [原]《The C Programming Language》电子书下载
  4. [原]SeeFiles:C#查看和修改文件或目录所有属性的工具
  5. [原]ManageApps:C#读取Windows系统中的已经安装的程序并卸载软件
  6. [原]WMICodeCreator:C#产生WMI代码的工具
  7. [原]PjConvertImageFormat:用FreeImage.NET写的一个35种图像格式转换程序
  8. [原]GetAlpha:C#实现获取网页验证码图片,并识别出其中的字母
  9. [译]在C# .NET2.0实现单实例应用程序
  10. [原]C#读取CSDN博客的文章名称及地址

你可能感兴趣的:(c,String,C#,Microsoft,文档,OpenXml)