虽然可利用 Open XML 文件格式删除 Microsoft Office PowerPoint 2007 和 Microsoft PowerPoint 2010 文档中的注释,但执行此操作需要做一些工作。Open XML SDK 2.0 for Microsoft Office 添加了可简化对 Open XML 文件格式的访问的强类型类;SDK 将简化检索注释列表并删除注释这一任务。此直观操作方法附带的代码示例介绍如何使用 SDK 来实现这个目标。
此直观操作方法中附带的示例包括从 PowerPoint 2007 或 PowerPoint 2010 文档删除一个作者或所有作者所做的注释所需的代码。以下各节详细讨论了该代码。
设置引用
若要使用 Open XML SDK 2.0 中的代码,您必须向您的项目添加几个引用。示例项目已包含这些引用;但是,您需要在您的代码中显式引用以下程序集:
此外,将以下 using/Imports 语句添加到代码文件的顶部。
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Presentation
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
检查过程
PPTDeleteComments 过程接受两个参数:一个指示要修改的演示文稿的名称的参数(字符串)和(可选)一个指示要删除其所做注释的作者的姓名的参数(字符串)。如果您提供作者姓名,则代码将删除指定作者所做的注释;反之,代码将删除所有注释。
Public Sub PPTDeleteComments(
ByVal fileName As String, Optional ByVal author As String = "")
public static void PPTDeleteComments(
string fileName, string author = "")
此过程将修改您指定的演示文稿,并删除所有注释或由指定作者所做的注释。若要调用此过程,请传递参数值,如示例代码中所示。在运行示例代码之前,请务必提供一个名为 C:\temp\Comments.pptx 的文档 - 该文档(用于演示)包含至少一条注释。如此处所示,代码将删除所有注释。若要将结果限制为特定作者所做的注释,请将该作者的姓名作为第二个参数添加。
PPTDeleteComments("C:\temp\comments.pptx")
PPTDeleteComments(@"C:\temp\comments.pptx");
访问演示文稿
该代码首先会使用 PresentationDocument.Open 方法打开文档,并指示应打开文档以供读写访问(最后的 True 参数)。代码将立即检索对注释作者部分的引用,如果该引用为 null,则将退出此过程。如果没有注释作者,则不存在要删除的注释。
Using doc As PresentationDocument =
PresentationDocument.Open(fileName, True)
Dim authorsPart As CommentAuthorsPart =
doc.PresentationPart.CommentAuthorsPart
If authorsPart Is Nothing Then
Return
End If
' Code removed here…
End Using
using (PresentationDocument doc =
PresentationDocument.Open(fileName, true))
{
CommentAuthorsPart authorsPart =
doc.PresentationPart.CommentAuthorsPart;
if (authorsPart == null)
{
return;
}
// Code removed here…
}
检索作者列表
接下来,代码将从作者部分检索 CommentAuthor 元素的列表。如果您提供了姓名(这样您便能删除由特定作者所做的注释),则代码将进一步限制作者列表,使其只包含您指定的作者。
Dim commentAuthors = authorsPart.
CommentAuthorList.Elements(Of CommentAuthor)()
If (Not String.IsNullOrEmpty(author)) Then
commentAuthors = commentAuthors.
Where(Function(e) e.Name.Value.Equals(author))
End If
var commentAuthors = authorsPart.
CommentAuthorList.Elements<CommentAuthor>();
if (!string.IsNullOrEmpty(author))
{
commentAuthors = commentAuthors.
Where(e => e.Name.Value.Equals(author));
}
循环访问所有作者和幻灯片
下一步是循环访问所有注释作者,并从所有幻灯片中删除特定作者所做的注释。(作者列表将包含您在参数中指定的单个作者或所有作者。)代码将循环访问所有注释作者并存储作者 ID,然后循环访问幻灯片部分的列表。对于每个幻灯片,代码将检索对相应的注释部分的引用,并且该引用可为 null(如果当前幻灯片没有注释)。您在下一节中将看到处理每个注释的代码,并且循环将以从注释作者列表中删除当前注释的作者作为结束。
For Each commentAuthor In commentAuthors
Dim authorId = commentAuthor.Id
' Iterate through all the slides and get the slide parts.
For Each slide In doc.PresentationPart.SlideParts
' Iterate through the slide parts and find the
' slide comment part.
Dim slideCommentsPart = Slide.SlideCommentsPart
If slideCommentsPart IsNot Nothing Then
' Code removed here…
End If
Next slide
commentAuthor.Remove()
Next commentAuthor
foreach (var commentAuthor in commentAuthors)
{
var authorId = commentAuthor.Id;
// Iterate through all the slides and get the slide parts.
foreach (var slide in doc.PresentationPart.SlideParts)
{
// Iterate through the slide parts and find the slide comment part.
var slideCommentsPart = slide.SlideCommentsPart;
if (slideCommentsPart != null)
{
// Code removed here.
}
}
commentAuthor.Remove();
}
处理注释
对于给定的幻灯片及其注释,代码将检索所有注释元素的列表。对于注释列表中由特定作者所做的每个注释(转换为数组,并强制执行 LINQ 查询),代码将删除当前注释。
Dim commentList =
slideCommentsPart.CommentList.Elements(Of Comment)().
Where(Function(e) e.AuthorId.Value = authorId.Value)
For Each comment In commentList.ToArray()
' Delete all the comments by the specified author.
comment.Remove()
Next comment
var commentList = slideCommentsPart.CommentList.
Elements<Comment>().Where(e => e.AuthorId.Value == authorId.Value);
foreach (var comment in commentList.ToArray())
{
// Delete all the comments by the specified author.
comment.Remove();
}
在循环访问所有注释并删除指定作者所做的每个注释后,代码将确定是必须删除注释部分还是保存注释部分。如果未保留任何注释,则代码将删除注释部分;否则,代码将保存注释部分。
If slideCommentsPart.CommentList.Count() = 0 Then
slide.DeletePart(slideCommentsPart)
Else
slideCommentsPart.CommentList.Save()
End If
if (slideCommentsPart.CommentList.Count() == 0)
{
slide.DeletePart(slideCommentsPart);
}
else
{
slideCommentsPart.CommentList.Save();
}
删除或保存注释作者部分
完成所有删除操作后,注释作者列表将包含零个作者(如果您删除了所有注释或删除了最后的作者)或一个或多个作者(如果您指定了要删除的作者,并且演示文稿中包含来自多个作者的注释)。如果再也没有作者,则代码将删除注释作者部分;否则,代码将保存已修改的部分。
If authorsPart.CommentAuthorList.Count = 0 Then
' No authors left, so delete the part.
doc.PresentationPart.DeletePart(authorsPart)
Else
' Save the comment authors part.
authorsPart.CommentAuthorList.Save()
if (authorsPart.CommentAuthorList.Count() == 0)
{
// No authors left, so delete the part.
doc.PresentationPart.DeletePart(authorsPart);
}
else
{
// Save the comment authors part.
authorsPart.CommentAuthorList.Save();
}
示例过程
下面的代码演示了整个示例过程。
Public Sub PPTDeleteComments(ByVal fileName As String,
Optional ByVal author As String = "")
Using doc As PresentationDocument =
PresentationDocument.Open(fileName, True)
' Get the authors part.
Dim authorsPart As CommentAuthorsPart =
doc.PresentationPart.CommentAuthorsPart
If authorsPart Is Nothing Then
' There is no authors part, so just
' fail. If no authors, there cannot be any comments.
Return
End If
' Get the comment authors, or the specified author if supplied:
Dim commentAuthors = authorsPart.
CommentAuthorList.Elements(Of CommentAuthor)()
If (Not String.IsNullOrEmpty(author)) Then
commentAuthors = commentAuthors.
Where(Function(e) e.Name.Value.Equals(author))
End If
Dim changed As Boolean = False
' The commentAuthors list contains either all the authors,
' or one author.
For Each commentAuthor In commentAuthors
Dim authorId = commentAuthor.Id
' Iterate through all the slides and get the slide parts.
For Each slide In doc.PresentationPart.SlideParts
' Iterate through the slide parts and find the
' slide comment part.
Dim slideCommentsPart = slide.SlideCommentsPart
If slideCommentsPart IsNot Nothing Then
' Get the list of comments.
Dim commentList = slideCommentsPart.CommentList.
Elements(Of Comment)().
Where(Function(e) e.AuthorId.Value = authorId.Value)
For Each comment In commentList.ToArray()
' Delete all the comments by the specified author.
comment.Remove()
Next comment
' No comments left? Delete the comments part
' for this slide.
If slideCommentsPart.CommentList.Count() = 0 Then
slide.DeletePart(slideCommentsPart)
Else
' Save the slide comments part.
slideCommentsPart.CommentList.Save()
End If
End If
Next slide
' Delete the comment author from the comment authors part.
commentAuthor.Remove()
Next commentAuthor
If authorsPart.CommentAuthorList.Count = 0 Then
' No authors left, so delete the part.
doc.PresentationPart.DeletePart(authorsPart)
Else
' Save the comment authors part.
authorsPart.CommentAuthorList.Save()
End If
End Using
End Sub
public static void PPTDeleteComments(string fileName, string author = "")
{
using (PresentationDocument doc = PresentationDocument.Open(fileName, true))
{
// Get the authors part.
CommentAuthorsPart authorsPart = doc.PresentationPart.CommentAuthorsPart;
if (authorsPart == null)
{
// There is no authors part, so just
// fail. If no authors, there cannot be any comments.
return;
}
// Get the comment authors, or the specified author if supplied:
var commentAuthors = authorsPart.
CommentAuthorList.Elements<CommentAuthor>();
if (!string.IsNullOrEmpty(author))
{
commentAuthors = commentAuthors.
Where(e => e.Name.Value.Equals(author));
}
foreach (var commentAuthor in commentAuthors)
{
var authorId = commentAuthor.Id;
// Iterate through all the slides and get the slide parts.
foreach (var slide in doc.PresentationPart.SlideParts)
{
// Iterate through the slide parts and find the slide comment part.
var slideCommentsPart = slide.SlideCommentsPart;
if (slideCommentsPart != null)
{
// Get the list of comments.
var commentList = slideCommentsPart.CommentList.
Elements<Comment>().Where(e => e.AuthorId.Value == authorId.Value);
foreach (var comment in commentList.ToArray())
{
// Delete all the comments by the specified author.
comment.Remove();
}
// No comments left? Delete the comments part for this slide.
if (slideCommentsPart.CommentList.Count() == 0)
{
slide.DeletePart(slideCommentsPart);
}
else
{
// Save the slide comments part.
slideCommentsPart.CommentList.Save();
}
}
}
// Delete the comment author from the comment authors part.
commentAuthor.Remove();
}
if (authorsPart.CommentAuthorList.Count() == 0)
{
// No authors left, so delete the part.
doc.PresentationPart.DeletePart(authorsPart);
}
else
{
// Save the comment authors part.
authorsPart.CommentAuthorList.Save();
}
}
}
此直观操作方法附带的示例演示了将删除 PowerPoint 演示文稿中的注释的代码。若要使用该示例,必须安装 Open XML SDK 2.0(可通过"浏览"一节中列出的链接获得)。该示例还将使用作为 Open XML SDK 2.0 代码示例集的一部分包含的修改后的代码。"浏览"一节还包括指向完整代码段集的链接,但您无需下载并安装代码段即可使用该示例。
示例应用程序仅演示了在修改演示文稿的结构时可与之交互的由 Open XML SDK 2.0 提供的几个可用属性和方法。有关详细信息,请参阅 Open XML SDK 2.0 Productivity Tool 附带的文档(单击应用程序窗口左下角的"Open XML SDK 文档"选项卡,并搜索要研究的类)。尽管该文档当前不包含代码示例,但借助此处所示的示例和文档,您应能成功修改示例应用程序。 |