简体   繁体   English

OpenXML 将评论回复插入到 word 文档 C#

[英]OpenXML insert comment reply into word document C#

I am trying to insert a comment as a reply using OpenXml.我正在尝试使用 OpenXml 插入评论作为回复。 If it is not possible, I would like to insert a comment right after a selected comment.如果不可能,我想在选定的评论后立即插入评论。 So far I am able to insert the comment in the place I want but I cannot get the comment to display when I open the document.到目前为止,我可以在我想要的位置插入评论,但是当我打开文档时无法显示评论。

Below is the code to insert the comment.下面是插入注释的代码。

 using (WordprocessingDocument document = WordprocessingDocument.Open(path + fileName + ".docx", true)){

            // Locate the first paragraph in the document.
            //XMLParagraphAlias firstParagraph = document.MainDocumentPart.Document.Descendants<XMLParagraphAlias>().First();

            XMLCommentsAlias comments = document.MainDocumentPart.WordprocessingCommentsPart.Comments;

            string id = comments.Descendants<DocumentFormat.OpenXml.Wordprocessing.Comment>()
                 .Where(i => i.Id.Value == reply.CurrentCommentID.ToString())
                 .Select(e => e.Id.Value)
                 .First();


             // Compose a new Comment and add it to the Comments part.
             XMLParagraphAlias p = new XMLParagraphAlias(new Run(new Text(reply.ReplyText)));

             string newCommentID = comments.Descendants<DocumentFormat.OpenXml.Wordprocessing.Comment>().Select(e => e.Id.Value).Max();

             XMLCommentAlias cmt = new XMLCommentAlias()
                                  {
                                    Id = newCommentID,
                                    Author = reply.CurrentUserName,
                                    Date = DateTime.Now.Date
                                  };

             XMLCommentAlias comment = comments.Elements<XMLCommentAlias>()
                                       .Where(n => n.Id.Value == reply.CurrentCommentID.ToString())
                                       .First();

             XMLParagraphAlias test2 = comment.Descendants<XMLParagraphAlias>().First();

            cmt.AppendChild(p);        
            comments.AppendChild(cmt);
            comments.Save();

            // Specify the text range for the Comment. 
            // Insert the new CommentRangeStart before the first run of paragraph.
            test2.InsertBefore(new CommentRangeStart() { Id = reply.CurrentCommentID.ToString() }, test2.GetFirstChild<Run>());

            // Insert the new CommentRangeEnd after last run of paragraph.
            var cmtEnd = test2.InsertAfter(new CommentRangeEnd() { Id = reply.CurrentCommentID.ToString() }, test2.Elements<Run>().Last());

            // Compose a run with CommentReference and insert it.
            test2.InsertAfter(new Run(new CommentReference() { Id = reply.CurrentCommentID.ToString() }), cmtEnd);
        }

I can see that the comment is put into the document using the debugger in VS, but it is not being displayed when I open the document.可以看到在VS中使用调试器将注释放入文档中,但是打开文档时没有显示。

After the save command is executed the comment is added to the document, but it doesn't display.执行保存命令后,注释会添加到文档中,但不会显示。

The overall goal here is to insert the comment after a specific comment in the list of comments that are contained in the document.此处的总体目标是在文档中包含的注释列表中的特定注释之后插入注释。 Can someone help me find a solution to this?有人可以帮我找到解决方案吗?

I found that the following are needed to create reply comments我发现创建回复评论需要以下内容

  • The CommentsEx Part is added to the document CommentsEx 部分被添加到文档中
  • The reply comment paragraph is linked to its parent回复评论段落链接到其父级
  • The CommentRange and the CommentReference are added in the right order CommentRange 和 CommentReference 以正确的顺序添加
  • The reply comments still have to be added to the comments part回复评论还是要加到评论部分

The example code below will add comments to an existing word in a document下面的示例代码将向文档中的现有单词添加注释

 foreach (var paragraph in document.MainDocumentPart.Document.Descendants<Paragraph>())
 {
      foreach (var run in paragraph.Elements<Run>())
      {
         var item = run.Elements<Text>().FirstOrDefault(b => b.Text.Contains("DTT"));
         if (item != null)
         {

           if (document.MainDocumentPart.GetPartsCountOfType<WordprocessingCommentsPart>() > 0)
           {
              comments = document.MainDocumentPart.WordprocessingCommentsPart.Comments;
              commentsEx = document.MainDocumentPart.WordprocessingCommentsExPart.CommentsEx;
              if (comments.HasChildren)
              {
                   // Obtain an unused ID.
                   id = comments.Descendants<Comment>().Select(e => e.Id.Value).Max();
              }
         }
         else
         {
             // No WordprocessingCommentsPart part exists, so add one to the package.
             WordprocessingCommentsPart commentPart = document.MainDocumentPart.AddNewPart<WordprocessingCommentsPart>();
             commentPart.Comments = new Comments();
             comments = commentPart.Comments;

             WordprocessingCommentsExPart commentsExPart = document.MainDocumentPart.AddNewPart<WordprocessingCommentsExPart>();
             commentsExPart.CommentsEx = new CommentsEx();
             commentsEx = commentsExPart.CommentsEx;
        }

        Comment comment1 = new Comment() { Initials = "GS", Author = "Tony, Stark", Date = System.Xml.XmlConvert.ToDateTime("2018-11-19T14:54:00Z", System.Xml.XmlDateTimeSerializationMode.RoundtripKind), Id = "1" };
        Paragraph paragraph1 = new Paragraph() {  ParagraphId = "68DAFED3", TextId = "77777777" };               
       paragraph1.Append(new Run(new Text("fsdfas")));
       comment1.Append(paragraph1);

       Comment comment2 = new Comment() { Initials = "GS", Author = "Tony, Stark", Date = System.Xml.XmlConvert.ToDateTime("2018-11-19T14:54:00Z", System.Xml.XmlDateTimeSerializationMode.RoundtripKind), Id = "2" };
       Paragraph paragraph2 = new Paragraph() { ParagraphId = "346EE35B", TextId = "77777777" };                          
       paragraph2.Append(new Run(new Text("sadfsad")));
       comment2.Append(paragraph2);

       comments.Append(comment1);
       comments.Append(comment2);
       comments.Save();

       CommentRangeStart commentRangeStart1 = new CommentRangeStart() { Id = "1" };
       CommentRangeStart commentRangeStart2 = new CommentRangeStart() { Id = "2" };
       CommentRangeEnd commentRangeEnd1 = new CommentRangeEnd() { Id = "1" };
       CommentReference commentReference1 = new CommentReference() { Id = "1" };
       CommentRangeEnd commentRangeEnd2 = new CommentRangeEnd() { Id = "2" };
       CommentReference commentReference2 = new CommentReference() { Id = "2" };

       run.InsertBefore(commentRangeStart1, item);
       run.InsertBefore(commentRangeStart2, item);
       var cmtEnd = run.InsertAfter(commentRangeEnd1, item);
       var cmtEnd2 = run.InsertAfter(commentRangeEnd2, cmtEnd);
       run.InsertAfter(new Run(commentReference1), cmtEnd);
       run.InsertAfter(new Run(commentReference2), cmtEnd2);

       CommentEx commentEx1 = new CommentEx() { ParaId = "68DAFED3", Done = false };
       CommentEx commentEx2 = new CommentEx() { ParaId = "346EE35B", ParaIdParent = "68DAFED3", Done = false };
       commentsEx.Append(commentEx1);
       commentsEx.Append(commentEx2);
       commentsEx.Save();

       }
    }
}

After following Meister's advice I was able to solve my problem.在遵循 Meister 的建议后,我能够解决我的问题。 The comments that are marked as replies are located in the commentsExtended.xml file.标记为回复的评论位于commentsExtended.xml 文件中。 To create a relationship with the comment you will need to create a CommentEX object and link the comment reply you are inserting to the comment you are replying to.要创建与评论的关系,您需要创建一个 CommentEX 对象并将您插入的评论回复链接到您正在回复的评论。 The code to implement the comment reply is located below.实现评论回复的代码位于下面。 The ParaIdParent property is the paraId of the comment you are replying to. ParaIdParent 属性是您正在回复的评论的 paraId。

        private void BuildCommentExtendXML(WordprocessingDocument document, string randomHexBinaryValue, HexBinaryValue commentsParagraphDescendantId)
    {
        var commentsEx = document.MainDocumentPart.WordprocessingCommentsExPart.CommentsEx;

        CommentEx commentEx = new CommentEx()
        {
            ParaId = randomHexBinaryValue,
            ParaIdParent = commentsParagraphDescendantId,
            Done = new OnOffValue(false)
        };
        commentsEx.Append(commentEx);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM