打开现有文档进行编辑

若要打开现有文档,您可以将 Word类实例化,如以下 using 语句所示。 为此,您可以使用Open(String, Boolean) 方法打开具有指定 fileName 的字处理文件,同时将布尔参数设置为 true 以允许编辑文档。

 using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(fileName, true))
{
// Insert other code here.
}

using 语句提供了典型 .Open、.Save、.Close 序列的建议备选方法。它确保在遇到右大括号时会自动调用 Dispose 方法(Open XML SDK 用来清理资源的内部方法)。跟在 using 语句后面的代码块为 using 语句中创建或指定的对象(在本示例中为 wdDoc)设定范围。由于 Open XML SDK 中的 WordprocessingDocument 类会在其实现 System.IDisposable 的过程中自动保存和关闭对象,并且由于在您退出代码块时会自动调用 Dispose,因此只要您使用 using,就不必明确调用 Save 和 Close。

Word 文档的结构

Word文档的基本结构由 document 和 body 元素组成,后跟一个或多个块级元素,如表示段落的 p。一个段落包含一个或多个 r 元素。 r 代表一段连续文本,它是具有一组共同属性(如格式设置)的文本区域。一段连续文本包含一个或多个 t 元素。 t 元素包含一个文本区域。以下代码示例显示包含文本"Example text."的文档的 Word 标记。

 <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">      
<w:body>
<w:p>
<w:r>
<w:t>Example text.</w:t>
</w:r>
</w:p>
</w:body>
</w:document>

通过使用 Open XML SDK ,您可以利用 WordprocessingML 元素所对应的强类型类创建文档结构和内容。 可以在DocumentFormat.OpenXml.Wordprocessing 命名空间中找到这些类。 下表列出了 document、body、p、r 和 t 元素所对应类的类名称。

Word 元素 Open XML SDK 类 说明
document 文件 主文档部件的根元素
body 主体 块级结构(如段落、表格、批注和 ISO/IEC 29500 规范中指定的其他项)的容器。
p 段落 段落。
r 运行 一段连续文本。
t 文本 文本范围。

ParagraphPropertiesChange 元素

在接受修订标记时,会通过删除现有文本或插入新文本来更改段落的属性。 在以下各节中,您将了解代码中用于更改段落内容的三个元素,即 <w: pPrChange\>(段落属性的修订信息)、<w:del>(删除的段落标记)和<w:ins>(插入的表格行)元素。

ISO/IEC 29500 规范中的以下信息介绍了 ParagraphPropertiesChange 元素 ( pPrChange)。

pPrChange(段落属性的修订信息)

此元素指定 Word 文档中一组段落属性的单处修订的详细信息。

此元素按如下方式存储此修订:

  • 此元素的子元素包含此修订之前应用于此段落的完整段落属性集。

  • 此元素的属性包含有关此修订发生时间(换句话说,这些段落属性何时成为"先前的"段落属性集)的信息。

假设对 Word文档中的一个段落设置了居中格式,并且将此段落属性更改作为修订进行跟踪。那么,将使用以下 Word标记指定此修订。

     <w:pPr>
<w:jc w:val="center"/>
<w:pPrChange w:id="0" w:date="01-01-2006T12:00:00" w:author="Samantha Smith">
<w:pPr/>
</w:pPrChange>
</w:pPr>

该元素表明,Samantha Smith 在 2006 年 1 月 1 日对段落属性进行了修订,并且有关段落的先前段落属性集是空集(即, pPr pPrChange 元素下未明确提供段落属性)。

Deleted 元素

ISO/IEC 29500 规范中的以下信息介绍了 Deleted 元素 ( del)。

del(删除的段落标记)

此元素表明,应将 Word文档中界定段落结束位置的段落标记视为视为已作为跟踪修订的一部分删除(换句话说,此段落的内容不再由此段落标记界定,而是与下一段落合并在一起 — 但是不应将这些内容自动标记为已删除)。

假设存在一个由两个段落组成(每个段落由一个段落标记 ¶ 界定)的文档:

如果删除界定第一个段落结束位置的有形字符并将此更改作为修订进行跟踪,则将产生以下结果:

此修订使用以下 Word表示:

    <w:p>
<w:pPr>
<w:rPr>
<w:del w:id="0" … />
</w:rPr>
</w:pPr>
<w:r>
<w:t>This is paragraph one.</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:t>This is paragraph two.</w:t>
</w:r>
</w:p>

第一个段落标记的连续文本属性的 del 元素指定此段落标记已删除,并且已将此删除作为修订进行跟踪。

Inserted 元素

ISO/IEC 29500 规范中的以下信息介绍了 Inserted 元素 ( ins)。

ins(插入的表格行)

此元素指定应将父表格行视为插入的行,并且已将该插入操作作为修订进行跟踪。此设置不应表示有关此行中的表格单元格或其内容的任何修订状态(它们必须通过单独的修订标记表示),并且应该仅影响表格行本身。

假设存在一个包含两行两列的表格,并且已使用修订将第二行标记为已插入。此要求将使用以下 Word 指定:

    <w:tbl>
<w:tr>
<w:tc>
<w:p/>
</w:tc>
<w:tc>
<w:p/>
</w:tc>
</w:tr>
<w:tr>
<w:trPr>
<w:ins w:id="0" … />
</w:trPr>
<w:tc>
<w:p/>
</w:tc>
<w:tc>
<w:p/>
</w:tc>
</w:tr>
</w:tbl>

第二个表格行的表格行属性的 ins 元素表明,此行是插入行,并且已将此插入操作作为修订进行跟踪。

示例代码

在 using 语句中打开文档后,将 Body 类实例化,然后通过以下方式处理格式更改:创建 changes List 并从 List 中删除每项更改( w:pPrChange 元素),这与接受更改相同。

    Body body = wdDoc.MainDocumentPart.Document.Body;

    // Handle the formatting changes.
List<OpenXmlElement> changes =
body.Descendants<ParagraphPropertiesChange>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); foreach (OpenXmlElement change in changes)
{
change.Remove();
}

然后通过以下方式处理删除:构造 deletions List 并从 List 中删除每个删除元素 (w:del),这与接受删除更改的过程类似。

    // Handle the deletions.
List<OpenXmlElement> deletions =
body.Descendants<Deleted>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); deletions.AddRange(body.Descendants<DeletedRun>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); deletions.AddRange(body.Descendants<DeletedMathControl>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); foreach (OpenXmlElement deletion in deletions)
{
deletion.Remove();
}

最后,通过以下方式处理插入:构造 insertions List 并通过删除插入元素 (w:ins) 来插入新文本,这与接受插入的文本相同。

复制
// Handle the insertions.
List<OpenXmlElement> insertions =
body.Descendants<Inserted>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); insertions.AddRange(body.Descendants<InsertedRun>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); insertions.AddRange(body.Descendants<InsertedMathControl>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); Run lastInsertedRun = null;
foreach (OpenXmlElement insertion in insertions)
{
// Found new content.
// Promote them to the same level as node, and then delete the node.
foreach (var run in insertion.Elements<Run>())
{
if (run == insertion.FirstChild)
{
lastInsertedRun = insertion.InsertAfterSelf(new Run(run.OuterXml));
}
else
{
lastInsertedRun = lastInsertedRun.Insertion.InsertAfterSelf(new Run(run.OuterXml));
}
}
insertion.RemoveAttribute("rsidR",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
insertion.RemoveAttribute("rsidRPr",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
insertion.Remove();
}

以下代码示例演示如何接受字处理文档中的全部修订。若要运行程序,可以调用 AcceptRevisions 方法以接受"word1.docx"文件中的修订,如以下示例所示。

     string docName = @"C:\Users\Public\Documents\word1.docx";
string authorName = "lin";
AcceptRevisions(docName, authorName);

运行程序后,打开字处理文件以确保已接受所有修订标记。

完整示例代码

     public static void AcceptRevisions(string fileName, string authorName)
{
// Given a document name and an author name, accept revisions.
using (WordprocessingDocument wdDoc =
WordprocessingDocument.Open(fileName, true))
{
Body body = wdDoc.MainDocumentPart.Document.Body; // Handle the formatting changes.
List<OpenXmlElement> changes =
body.Descendants<ParagraphPropertiesChange>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); foreach (OpenXmlElement change in changes)
{
change.Remove();
} // Handle the deletions.
List<OpenXmlElement> deletions =
body.Descendants<Deleted>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); deletions.AddRange(body.Descendants<DeletedRun>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); deletions.AddRange(body.Descendants<DeletedMathControl>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); foreach (OpenXmlElement deletion in deletions)
{
deletion.Remove();
} // Handle the insertions.
List<OpenXmlElement> insertions =
body.Descendants<Inserted>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList(); insertions.AddRange(body.Descendants<InsertedRun>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); insertions.AddRange(body.Descendants<InsertedMathControl>()
.Where(c => c.Author.Value == authorName).Cast<OpenXmlElement>().ToList()); foreach (OpenXmlElement insertion in insertions)
{
// Found new content.
// Promote them to the same level as node, and then delete the node.
foreach (var run in insertion.Elements<Run>())
{
if (run == insertion.FirstChild)
{
insertion.InsertAfterSelf(new Run(run.OuterXml));
}
else
{
insertion.NextSibling().InsertAfterSelf(new Run(run.OuterXml));
}
}
insertion.RemoveAttribute("rsidR",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
insertion.RemoveAttribute("rsidRPr",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
insertion.Remove();
}
}
}

处理Word文档中所有修订的更多相关文章

  1. C# 在Word文档中生成条形码

    C# 在Word文档中生成条形码 简介 条形码是由多个不同的空白和黑条按照一定的顺序组成,用于表示各种信息如产品名称.制造商.类别.价格等.目前,条形码在我们的日常生活中有着很广泛的应用,不管是在图书 ...

  2. C# 提取Word文档中的图片

    C# 提取Word文档中的图片 图片和文字是word文档中两种最常见的对象,在微软word中,如果我们想要提取出一个文档内的图片,只需要右击图片选择另存为然后命名保存就可以了,今天这篇文章主要是实现使 ...

  3. 把word文档中的所有图片导出

    把word文档中的所有图片导出 end

  4. aspose.words复制插入同一word文档中的某个页面

    选择word模板 Document doc = new Document(Server.MapPath("~\\templet") + "\\" + name. ...

  5. Aspose.Words:如何添加另一个WORD文档中的Node对象

    原文:Aspose.Words:如何添加另一个WORD文档中的Node对象 首先看一段代码,这段代码意图从docSource中获取第一个表格,并插入docTarget的末尾: , true); doc ...

  6. C# 在word文档中复制表格并粘帖到下一页中

    C# 在word文档中复制表格并粘帖到下一页中 object oMissing = System.Reflection.Missing.Value;            Microsoft.Offi ...

  7. 使用Java POI来选择提取Word文档中的表格信息

    通过使用Java POI来提取Word(1992)文档中的表格信息,其中POI支持不同的ms文档类型,在具体操作中需要注意.本文主要是通过POI来提取微软2003文档中的表格信息,具体code如下(事 ...

  8. C# Word文档中插入、提取图片,文字替换图片

    Download Files:ImageOperationsInWord.zip 简介 在这篇文章中我们可以学到在C#程序中使用一个Word文档对图像的各种操作.图像会比阅读文字更有吸引力,而且图像是 ...

  9. 如何批量删除word文档中的超级链接?

    有时候从网页上copy来的文章中,会带有非常多的链接,这些链接很烦人是吧?如何批量删除(一次性全部删除)word文章中的超链接呢? 有些朋友说,Ctrl+A全选文章,然后点击格式工具栏上的“清除格式” ...

随机推荐

  1. python windows环境响铃

    import winsound winsound.Beep(600,1000) #其中600表示声音大小,1000表示发生时长,1000为1秒

  2. C++ map 使用erase在windows下崩溃,在linux下没有问题的原因

    注意:此程序在win环境下会出现上述描述的问题:在mac环境下第一种方式是正常运行的.Map.erase有3个重载函数: void erase(iterator position); size_typ ...

  3. redis缓存雪崩、穿透、击穿概念及解决办法

    缓存雪崩 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求,但是缓存机器意外发生了全盘宕机.缓存挂了,此时 1 秒 5000 个请求全部落数据库,数据 ...

  4. 处理ajax数据;数据渲染

    当我们用ajax把数据拿到前台,该如何渲染到页面,有以下几种方式: 一:使用字符串拼接的方法 声明一个空变量,然后拼接 var st=""; st+="<div&g ...

  5. .Net 配置的简陋解决方案

    公司是做CS产品的, 最近分配给我一个活, 要求:     1. 公司程序启动时, 检测是否有配置文件, 没有的话则按默认值创建一个     2. 配置文件要加密, 不能让客户随便看到里面的参数   ...

  6. Spring Cloud的小改进(五)

    1.在Eureka中不能看到具体服务的实例信息: 问题点:服务注册到 Eureka 之后,可以看到在 “Status” 显示的服务信息不明确(不知道具体的服务名等信息),如下图所示: 解决方法: 在服 ...

  7. swift两种获取相册资源PHAsset的路径的方法(绝对路径)

    方法中使用到的phasset就是我们取到的PHAsset对象 方法一: let options = PHVideoRequestOptions() options.version = PHVideoR ...

  8. 使用PHP实现手机端APP支付宝的支付功能

    最近应业务需求,做了支付宝支付和微信支付,今天分享一下手机端app支付宝支付对接流程,实际开发过程是前后端分离,前端调用后端API接口,实现功能返回数据,我所用的跨挤啊为TP5,大致可以分为四步: 1 ...

  9. Electorn(桌面应用)自动化测试之Java+selenium实战例子

    基于electorn的桌面应用,网上相关资料较少.所有记录一下.使用java+selenium+testng对该类型应用的自动化测试方法. 代码样例 package com.contract.web. ...

  10. Python脚本字符集问题

    运行脚本的时候,总是报错: SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xb9 in position 0: inval ...