C# 通过API和文本操作修改OpenXML Word文档

C# 通过API和文本操作修改OpenXML Word文档,c#,ms-word,openxml-sdk,C#,Ms Word,Openxml Sdk,我正在开发原型,以替换现有的基于word自动化的模板呈现系统,目前正在评估OpenXMLSDK。模板库非常广泛(150-200个模板,由非技术资源维护),因此我希望避免任何模板更改,而不是从1997-2003 word格式升级 当前嵌入的标签有时需要替换为文本,有时需要替换为图像/图表等。。。(目前假设所有图表都将在插入之前渲染为图像) 我能够使用与中描述的技术类似的技术来进行纯文本替换。我的场景稍微复杂一些,但看起来像这样: public void ReplaceFirstOccurr

我正在开发原型,以替换现有的基于word自动化的模板呈现系统,目前正在评估OpenXMLSDK。模板库非常广泛(150-200个模板,由非技术资源维护),因此我希望避免任何模板更改,而不是从1997-2003 word格式升级

当前嵌入的标签有时需要替换为文本,有时需要替换为图像/图表等。。。(目前假设所有图表都将在插入之前渲染为图像)

我能够使用与中描述的技术类似的技术来进行纯文本替换。我的场景稍微复杂一些,但看起来像这样:

    public void ReplaceFirstOccurrenceWithText(string tagBody, string replacement)
    {
        var modifiedText = GetCurrentText();
        modifiedText = modifiedText.ReplaceFirst(tagBody, XmlEncoder.Encode(replacement));
        using (var sw = new StreamWriter(document.MainDocumentPart.GetStream(FileMode.Create)))
        {
            sw.Write(modifiedText);
        }
    }

    public string GetCurrentText()
    {
        using(var reader = new StreamReader(document.MainDocumentPart.GetStream()))
        {
            return reader.ReadToEnd();
        }
    }
我之所以不保存字符串,是因为我希望底层文档保持最新,以便可以通过普通API添加图像。使用中描述的技术:

其中ImageInserter实际上是该文章中代码的复制/粘贴(我意识到这些抽象不是最好的,但我只是尝试在这一点上让任何东西工作)

现在是它变得毛茸茸的地方-文档似乎保持同步。图像是第一个被替换的标记,标记的文本替换也起作用,在文档底部添加图像也是如此。我的问题是,在这一点之后,后续的文本替换似乎根本不起作用——所有其他标记都保留在文档中。但是,如果我在文本替换函数中设置了一个断点,则每次调用.GetCurrentText()都会返回正确的结果(到该点为止带有标记的文本已被替换)。但是当我保存文档时,只保存了第一次替换


有人碰到过这样的事吗?下一步是尝试一种分阶段的方法(解决所有标签,首先运行纯文本替换,然后执行所有图像替换),但我觉得无论顺序如何,当前出现的任何错误都将是一个问题。

如果我想了解您的位置


对于一般的东西来说,这要简单得多。。也许您正在做一些比库可以处理的更复杂的事情,但我会看一看。

谢谢-我怀疑它可能无法处理一些更复杂的场景(我甚至还没有尝试将图片插入文档中的正确位置),但这绝对值得研究。至少,这会让我暂时摆脱对OpenXML API的重击。是的,我注意到-自从我读了你的评论后,我能够在DocX中使用文本替换的东西,而且它似乎对处理图像有一些不错的支持,所以我祈祷这能行得通。由于QA问题,我仍然倾向于aspose(让我们随着时间的推移升级模板),但我很高兴有这样一个像样的包装器!我注意到在上找到的图像替换代码有一个小问题,但我能够解决它。非常感谢你引导我走向DocX——这真是一块隐藏的宝石。
    public void ReplaceFirstOccurrenceWithImage(string tagBody, byte[] replacement)
    {
        ReplaceFirstOccurrenceWithText(tagBody, "IMAGE TAG WAS HERE!");
        var main = document.MainDocumentPart;
        var imagePart = main.AddImagePart(ImagePartType.Gif);//sniff this by loading bytes into a bitmap
        using(var imageStream = new MemoryStream(replacement))
        {
            imagePart.FeedData(imageStream);
        }

        ImageInserter.AddImageToBody(document, main.GetIdOfPart(imagePart));
    }