微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Office Open XML SDK替换

为了基于来自sql数据库的数据创建word文档,我使用Office Open XML SDK来避免使用互操作.这加快了流程,并且消除了对客户端系统上安装的Microsoft Office套件的要求.

虽然这非常有效,但在替换文档中的某些文本时我遇到了一个问题.为了保持最终文档的自定义选项,我创建了一个文档,其中包含一些标记作为模板.此模板包含[TagHere]等标签.由于标签名称应该易于阅读,因此可以在整个文档中使用它们,这就是我用大括号[]包围标签的原因.

这很有效,但有时会出现问题.当您输入docx文档时,即使在同一个单词中,也可以将文本拆分为多个标记.像[TagHere]这样的标签可以拆分成

<tag>[</tag><tag>TagHere</tag><tag>]</tag>

发生这种情况时,更换将无法正常工作.

现在,docx格式有一些替代选项来执行此类操作,例如内容控件,但这些使得创建模板的过程更加复杂.此外,在这些文档中,使用标记获取一行表并多次复制它并不罕见,这可能会破坏内容标记原则.因此我选择不使用此选项.

如果有人能解决这个问题,那就太棒了.

解决方法

而不是键入纯文本“taghere”,插入合并字段. (单击插入>快速部分>字段.选择“mergefield”并在“字段名称”字段中键入“TagHere”.)

然后,不是进行文本查找 – 替换,而是扫描文档以查找合并字段并设置内部文本.

class Program
{
    static void Main(string[] args)
    {
        string document = args[0];
        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document,true))
        {
            Dictionary<string,string> replaceOperations = new Dictionary<string,string>();

            replaceOperations.Add("company","alex's applications");
            replaceOperations.Add("first_name","alexander");
            replaceOperations.Add("last_name","taylor");
            //etc

            Replace(wordDoc,replaceOperations);
        }
    }

    public static char[] splitChar = new char[] {' '};
    public static void Replace(WordprocessingDocument document,Dictionary<string,string> replaceOperations)
    {
        //find all the fields
        foreach (var field in document.MainDocumentPart.Document.Body.Descendants<SimpleField>())
        {
            //parse the instruction
            string[] instruction = field.Instruction.Value.Split(splitChar,StringSplitOptions.RemoveEmptyEntries);

            //check if it's a merge field,and if so...
            if (instruction[0].ToLower().Equals("mergefield"))
            {
                //get the field name
                string fieldname = instruction[1];

                //find the text inside (there will only be one)
                foreach (var fieldtext in field.Descendants<Text>())
                {
                    //see if we kNow what to set this value to
                    string value = replaceOperations.ContainsKey(fieldname) ? replaceOperations[fieldname] : null;

                    //if we found the replace value,set the text to this value
                    if (value != null)
                        fieldtext.Text = value;

                    //should only be one text inside
                    break;
                }
            }
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。