1

我正在尝试使用 c# 和 openxml 编辑一些 word 文件。我需要用某些短语来控制替换数字。每个单词文件包含不同数量的信息。我想为此目的使用 OPENXML powertools。

我使用普通的 openxml 方法进行替换,但它非常不可靠并且会出现随机错误,例如零长度错误。我使用了正则表达式替换,这似乎有效,但它在整个文档中替换它,这是非常不受欢迎的。

这是代码的一些片段:

private void redact_Replaceall(string wfile)
        {
            try
            {
                using (WordprocessingDocument doc = WordprocessingDocument.Open(wfile, true))
                {
                    var ydoc = doc.MainDocumentPart.GetXDocument();
                    IEnumerable<XElement> content = ydoc.Descendants(W.body);



                    Regex regex = new Regex(@"\d+\.\d{2,3}");
                    int count1 = OpenXmlPowerTools.OpenXmlRegex.Match(content, regex);


                    int count2 = OpenXmlPowerTools.OpenXmlRegex.Replace(content, regex, replace_text, null);

                    statusBar1.Text = "Try 1: Found: " + count1 + ", Replaced: " + count2;


                    doc.MainDocumentPart.PutXDocument();

                }
            }
            catch(Exception e)
            {
                MessageBox.Show("Replace all exprienced error: " + e.Message);
            }

        }

基本上,我想根据段落的内容进行编辑。我可以使用但不是 id 来获取段落

IEnumerable<XElement> content = ydoc.Descendants(W.p);

这是我使用普通 openxml 方法的方法,但根据文件的不同,我会遇到很多错误。

  foreach (DocumentFormat.OpenXml.Wordprocessing.Paragraph para in bod.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>())
                                    {

                                        foreach (var run in para.Elements<Run>())
                                        {
                                            foreach (var text in run.Elements<Text>())
                                            {
                                                string temp = text.Text;
                                                int firstlength = first.Length + 1;
                                                int secondlength = second.Length + 1;
                                                if (text.Text.Contains(first) && !(temp.Length > firstlength))
                                                {
                                                    text.Text = text.Text.Replace(first, "DELETED");

                                                }

                                                if (text.Text.Contains(second) && !(temp.Length > secondlength))
                                                {
                                                    text.Text = text.Text.Replace(second, "DELETED");

                                                }
                                            }
                                        }
                                    }

这是最后一种新方法,但我坚持下去

   private void redact_Replacebadones(string wfile)
        {
            try
            {
                using (WordprocessingDocument doc = WordprocessingDocument.Open(wfile, true))
                {
                    var ydoc = doc.MainDocumentPart.GetXDocument();
                  /*  from XElement xele in ydoc.Root.Elements();
                    List<string> lhsElements = xele.Elements("lhs")
                               .Select(el => el.Attribute("id").Value)
                               .ToList();
                               */
                    /// XElement
                    IEnumerable<XElement> content = ydoc.Descendants(W.p);

                   foreach (var p in content )

                    {
                        if (p.Value.Contains("each") && !p.Value.Contains("DELETED"))
                        {

                            string to_overwrite = p.Value;
                            Regex regexop = new Regex(@"\d+\.\d{2,3}");

                            regexop.Replace(to_overwrite, "Deleted");

                            p.SetValue(to_overwrite);

                            MessageBox.Show("NAME :" + p.GetParagraphInfo() +" VValue:"+to_overwrite);
                        }

                    }


                    doc.MainDocumentPart.PutXDocument();

                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Replace each exprienced error: " + e.Message);
            }

        } 
4

1 回答 1

0

可能有点晚了。Eric white 的 OpenXML Power 工具有一个函数 SearchAndReplace,您可以在其中替换文本内容,因此您不必使用 RegEx 处理它。此函数还处理拆分为运行的文本。(如果你编辑一个词,一个词可以在运行中被拆分,所以你直接找到搜索短语。)这可能对某人有帮助。

于 2020-11-24T11:16:17.503 回答