添加第一个评论和 comments.xml 到 word 文档

Add first comment and comments.xml to word doc

我正在编写 RoR 应用程序以向 docx 文件添加评论。 Nokogiri 非常适合将文档中的 XML 评论修改为 add/edit,其中至少有一条评论已经存在。这些文档在 docx 包中有一个按单词插入的 comments.xml 文件。

我卡住的地方是以编程方式添加第一条评论。没有预先存在的评论的文档没有 comments.xml 文件。简单地添加文件是行不通的,它需要定义适当的关系。我正在努力寻找如何添加一个并在 docx 包关系结构中识别它,以便 document.xml(主要内容存在的地方)知道查看 comments.xml 以获得评论。

我会 post post 代码,但我尝试了很多不同的东西,我几乎为零。我主要是在寻找具有 Office Open XML 经验且之前可能做过此操作的任何人。我可以弄清楚 Rails/Nokogiri 的东西,我只是坚持理解 Office Open XML 包中实际需要更改的内容。

以下 C# 示例显示了如何使用 Open XML SDK 执行此操作:

public void CreateComment()
{
    // Let's say we have a document called Comments.docx with a single
    // paragraph saying "Hello World!".
    using WordprocessingDocument wordDocument = WordprocessingDocument.Create(
        "Comments.docx", WordprocessingDocumentType.Document);

    MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
    mainDocumentPart.Document =
        new Document(
            new Body(
                new Paragraph(
                    new Run(
                        new Text("Hello World!")))));

    // Our MainDocumentPart needs to have a related WordprocessingCommentsPart,
    // which you see as the comments.xml file. That file needs to have a
    // w:comments root element.

    // The next line of code is the key step that adds the comments.xml file
    // and the required relationships and content types. To add individual
    // w:comment elements, we need the root w:comments element.
    var commentsPart = mainDocumentPart.AddNewPart<WordprocessingCommentsPart>();
    commentsPart.Comments = new Comments();

    // The rest of the code just shows how you would use the Open XML SDK
    // to add a comment.
    // So say we want to comment on the whole paragraph. As a first step,
    // we create a comment and add it to the w:comments root element. 
    var comment = new Comment(new Paragraph(new Run(new Text("This is my comment."))))
    {
        Id = "1",
        Author = "Thomas Barnekow"
    };

    commentsPart.Comments.AppendChild(comment);

    // Then, we need to add w:commentRangeStart and w:commentRangeEnd
    // elements to the text on which we want to comment. In this example,
    // we are getting "some" w:p element and some first and last w:r
    // elements and insert the w:commentRangeStart before the first and
    // the w:commentRangeEnd after the last w:r.
    Paragraph p = mainDocumentPart.Document.Descendants<Paragraph>().First();
    Run firstRun = p.Elements<Run>().First();
    Run lastRun = p.Elements<Run>().Last();

    firstRun.InsertBeforeSelf(new CommentRangeStart { Id = "1" });
    CommentRangeEnd commentRangeEnd = lastRun.InsertAfterSelf(new CommentRangeEnd { Id = "1" });
    commentRangeEnd.InsertAfterSelf(new Run(new CommentReference { Id = "1" }));
}

因此,如果您可以使用 Open XML SDK,那么添加 comments.xml 部分将非常容易。但是,如果您不能使用 SDK,则必须编写自己的代码来创建相同的效果。为此,您必须了解在何处进行哪些更改。

第一步是在 /word 文件夹中创建 comments.xml 文件。一个空的 comments.xml 应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
</w:comments>

接下来,您需要建立 MainDocumentPart (documents.xml) 和 WordprocessingCommentsPart (comments.xml) 之间的关系。为此,您需要创建或修改 /word/_rels 文件夹中包含的 document.xml.rels 文件。对于上述示例创建的文档,document.xml.rels 具有以下内容(即单个相关子部分):

<?xml version="1.0" encoding="utf-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" Target="/word/comments.xml" Id="Rf416c937546c47ef" />
</Relationships>

最后一个要考虑的文件是包根目录下的 [Content_Types].xml。上面例子中Open XML SDK添加了comments.xml部分,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" />
  <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
  <Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />
</Types>

记下最后一个子元素,它覆盖 /word/comments.xml 部分的内容类型。