0

我有一个小方法,除了单词段落,段落内容和任何评论内容(如果有的话)。作为跟踪文档中哪些段落已被处理的一种方法,我试图在 openxml 注入段落周围添加一个内容控件。它爆炸了,我不确定从哪里开始,因为我对 openxml 还很陌生。我的代码示例如下:

    public void Handle(Paragraph paragraph, string docPartXml, string commentsPartXml)
    {

        var docXml = docPartXml;
        var commentsXml = commentsPartXml;

        using (var res = paragraph.Range.WithComCleanup())
        {
            var range = res.Resource;
            using (var packageStream = range.GetPackageStreamFromRange())
            using (var document = WordprocessingDocument.Open(packageStream, true))
            {
                var pbody = document.MainDocumentPart.Document.Body;
                pbody.InnerXml = docXml + "<w:p></w:p>";  // paragraphs are merged/combined w/o this
                document.MainDocumentPart.Document.Save();

                WordprocessingCommentsPart commentsPart = null;
                if (document.MainDocumentPart.WordprocessingCommentsPart == null)
                {
                    commentsPart = document.MainDocumentPart.AddNewPart<WordprocessingCommentsPart>();
                    document.MainDocumentPart.AddPart(commentsPart);
                    document.MainDocumentPart.Document.Save();
                    commentsPart = document.MainDocumentPart.WordprocessingCommentsPart;
                    commentsPart.Comments = new Comments();
                }
                if (commentsPart == null)
                    commentsPart = document.MainDocumentPart.WordprocessingCommentsPart;

                commentsPart.Comments.InnerXml += commentsXml;
                commentsPart.Comments.Save();

                document.MainDocumentPart.Document.Save();

                document.Package.Flush();
                XDocument xdoc = OpenXmlExtensions.OpcToFlatOpc(document.Package);
                var openxml = xdoc.ToString();

                var validator = new OpenXmlValidator();
                var errors = validator.Validate(document);

                // todo - provide more detailed info for the log
                foreach (var err in errors)
                    _logger.Warn(err.Description, "OpenXml Injection");

                try
                {
                    range.InsertXML(openxml);
                }
                catch (COMException e)
                {
                    _logger.Error("Unable to insert xml into paragraph");
                }
            }
        }
    }
4

1 回答 1

0

用以下代码替换 pbody.InnerXml = ... 行,它工作正常。

pbody.RemoveAllChildren<Paragraph>();
pbody.RemoveAllChildren<SdtBlock>();
pbody.RemoveAllChildren<SdtProperties>();
var sdtBlock1 = new SdtBlock();
var sdtPr = new SdtProperties(
    new SdtAlias {Val = string.Format("{0}-{1}", "CC", hash)},
    new Tag {Val = string.Format("{0}-{1}", hash, "CC")});
                        //new Lock(){ Val = LockingValues.ContentLocked});
sdtBlock1.AppendChild(sdtPr);
var sdtContentBlock1 = new SdtContentBlock {

InnerXml = docXml};
sdtBlock1.AppendChild(sdtContentBlock1);

pbody.AppendChild( sdtBlock1);
于 2014-10-10T15:25:32.853 回答