C# 如何使用OpenXML突出显示句子中的文本?
我使用下面的代码搜索并突出显示MS Word文档中的文本,它适用于第1点,但不适用于第2点:C# 如何使用OpenXML突出显示句子中的文本?,c#,openxml,wordprocessingml,C#,Openxml,Wordprocessingml,我使用下面的代码搜索并突出显示MS Word文档中的文本,它适用于第1点,但不适用于第2点: 1. John Alter 我搜索Alter或John,它突出显示John/Alter-工作 2. I am going to school 我搜索去,它会突出显示去,但它会更改其顺序,因为我要去上学-不起作用 如何修复点2?下面是我的代码 private void HighLightText(Paragraph paragraph, string text) { string textO
1. John Alter
我搜索Alter
或John
,它突出显示John
/Alter
-工作
2. I am going to school
我搜索去
,它会突出显示去
,但它会更改其顺序,因为我要去上学
-不起作用
如何修复点2?下面是我的代码
private void HighLightText(Paragraph paragraph, string text)
{
string textOfRun = string.Empty;
var runCollection = paragraph.Descendants<DocumentFormat.OpenXml.Wordprocessing.Run>();
DocumentFormat.OpenXml.Wordprocessing.Run runAfter = null;
//find the run part which contains the characters
foreach (DocumentFormat.OpenXml.Wordprocessing.Run run in runCollection)
{
if (!string.IsNullOrWhiteSpace(paragraph.InnerText) && paragraph.InnerText != "\\s")
textOfRun = run.GetFirstChild<DocumentFormat.OpenXml.Wordprocessing.Text>().Text;
if (textOfRun.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
{
//remove the character from this run part
run.GetFirstChild<DocumentFormat.OpenXml.Wordprocessing.Text>().Text = Regex.Replace(textOfRun, text, string.Empty, RegexOptions.IgnoreCase);//textOfRun.Replace(text, string.Empty);
runAfter = run;
break;
}
}
//create a new run with your customization font and the character as its text
DocumentFormat.OpenXml.Wordprocessing.Run HighLightRun = new DocumentFormat.OpenXml.Wordprocessing.Run();
DocumentFormat.OpenXml.Wordprocessing.RunProperties runPro = new DocumentFormat.OpenXml.Wordprocessing.RunProperties();
Highlight highlight = new Highlight() { Val = HighlightColorValues.Yellow };
DocumentFormat.OpenXml.Wordprocessing.Text runText = new DocumentFormat.OpenXml.Wordprocessing.Text() { Text = text };
runPro.Append(highlight);
HighLightRun.Append(runPro);
HighLightRun.Append(runText);
//insert the new created run part
paragraph.InsertAfter(HighLightRun, runAfter);
}
private void HighLightText(段落,字符串文本)
{
string textOfRun=string.Empty;
var runCollection=段落.子体();
DocumentFormat.OpenXml.Wordprocessing.Run runAfter=null;
//查找包含字符的运行部件
foreach(DocumentFormat.OpenXml.Wordprocessing.Run在runCollection中运行)
{
如果(!string.IsNullOrWhiteSpace(段落.InnerText)&¶tion.InnerText!=“\\s”)
textOfRun=run.GetFirstChild().Text;
if(textOfRun.IndexOf(text,StringComparison.OrdinalIgnoreCase)>=0)
{
//从此运行部件中删除角色
run.GetFirstChild().Text=Regex.Replace(textOfRun,Text,string.Empty,RegexOptions.IgnoreCase);//textOfRun.Replace(Text,string.Empty);
runAfter=运行;
打破
}
}
//使用自定义字体和字符作为文本创建新的跑步记录
DocumentFormat.OpenXml.Wordprocessing.Run HighLightRun=new DocumentFormat.OpenXml.Wordprocessing.Run();
DocumentFormat.OpenXml.Wordprocessing.RunProperties runPro=新的DocumentFormat.OpenXml.Wordprocessing.RunProperties();
Highlight Highlight=new Highlight(){Val=HighlightColorValues.Yellow};
DocumentFormat.OpenXml.Wordprocessing.Text runText=newdocumentformat.OpenXml.Wordprocessing.Text(){Text=Text};
runPro.Append(突出显示);
HighLightRun.Append(runPro);
HighLightRun.Append(runText);
//插入新创建的管路零件
段落.插入后面(突出显示,突出显示);
}
< /代码> 如果您想在该代码的中间突出某些文本>运行< /代码>,则需要拆分<代码>运行<代码>。因此,用空字符串替换搜索文本将不起作用
您的原始文本结构如下所示:
<Run>
<Text>
I am going to school
</Text>
</Run>
然后,可以在中间设置<代码>运行<代码>,以突出显示。
下面是一个工作代码示例。请注意,提交此代码时没有错误!它会让你知道如何解决你的任务。为生产使用实施适当的异常处理
还请注意,此示例仅搜索第一个匹配项,因为它在代码中。如果需要突出显示多个搜索匹配项,则必须改进此代码
void HighLightText(Paragraph paragraph, string text)
{
// Search for a first occurrence of the text in the text runs
var found = paragraph
.Descendants<Run>()
.Where(r => !string.IsNullOrEmpty(r.InnerText) && r.InnerText != "\\s")
.Select(r =>
{
var runText = r.GetFirstChild<Text>();
int index = runText.Text.IndexOf(text, StringComparison.OrdinalIgnoreCase);
// 'Run' is a reference to the text run we found,
// TextNode is a reference to the run's Text object,
// 'TokenIndex` is the index of the search string in run's text
return new { Run = r, TextNode = runText, TokenIndex = index };
})
.FirstOrDefault(o => o.TokenIndex >= 0);
// Nothing found -- escape
if (found == null)
{
return;
}
// Create a node for highlighted text as a clone (to preserve formatting etc)
var highlightRun = found.Run.CloneNode(true);
// Add the highlight node after the found text run and set up the highlighting
paragraph.InsertAfter(highlightRun, found.Run);
highlightRun.GetFirstChild<Text>().Text = text;
RunProperties runPro = new RunProperties();
Highlight highlight = new Highlight { Val = HighlightColorValues.Yellow };
runPro.AppendChild(highlight);
highlightRun.InsertAt(runPro, 0);
// Check if there's some text in the text run *after* the found text
int remainderLength = found.TextNode.Text.Length - found.TokenIndex - text.Length;
if (remainderLength > 0)
{
// There is some text after the highlighted section --
// insert it in a separate text run after the highlighted text run
var remainderRun = found.Run.CloneNode(true);
paragraph.InsertAfter(remainderRun, highlightRun);
var textNode = remainderRun.GetFirstChild<Text>();
textNode.Text = found.TextNode.Text.Substring(found.TokenIndex + text.Length);
// We need to set up this to preserve the spaces between text runs
textNode.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Preserve);
}
// Check if there's some text *before* the found text
if (found.TokenIndex > 0)
{
// Something is left before the highlighted text,
// so make the original text run contain only that portion
found.TextNode.Text = found.TextNode.Text.Remove(found.TokenIndex);
// We need to set up this to preserve the spaces between text runs
found.TextNode.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Preserve);
}
else
{
// There's nothing before the highlighted text -- remove the unneeded text run
paragraph.RemoveChild(found.Run);
}
}
void HighLightText(段落、字符串文本)
{
//搜索文本运行中第一次出现的文本
var=段落
.后代()
.Where(r=>!string.IsNullOrEmpty(r.InnerText)&&r.InnerText!=“\\s”)
.选择(r=>
{
var runText=r.GetFirstChild();
int index=runText.Text.IndexOf(Text,StringComparison.OrdinalIgnoreCase);
//“Run”是对我们找到的文本Run的引用,
//TextNode是对运行的文本对象的引用,
//'TokenIndex'是run文本中搜索字符串的索引
返回新的{Run=r,TextNode=runText,TokenIndex=index};
})
.FirstOrDefault(o=>o.TokenIndex>=0);
//什么也没找到——逃跑
if(found==null)
{
返回;
}
//为高亮显示的文本创建一个节点作为克隆(以保留格式等)
var highlightRun=found.Run.CloneNode(true);
//在找到的文本运行后添加突出显示节点,并设置突出显示
段落.InsertAfter(highlightRun,find.Run);
highlightRun.GetFirstChild().Text=Text;
RunProperties runPro=新的RunProperties();
Highlight Highlight=newhighlight{Val=HighlightColorValues.Yellow};
runPro.AppendChild(高亮显示);
highlightRun.InsertAt(runPro,0);
//检查在找到的文本*之后*运行的文本中是否有一些文本
int remainderLength=found.TextNode.Text.Length-found.TokenIndex-Text.Length;
如果(剩余长度>0)
{
//突出显示的部分后面有一些文本--
//在高亮显示的文本运行后,将其插入单独的文本运行中
var remainderRun=found.Run.CloneNode(true);
段落.插入符(余数段、高亮段);
var textNode=remainderRun.GetFirstChild();
textNode.Text=found.textNode.Text.Substring(found.TokenIndex+Text.Length);
//我们需要设置此选项以保留文本运行之间的空格
textNode.Space=新的枚举值(SpaceProcessingModeValues.Preserve);
}
//检查在*找到的文本之前*是否有一些文本
如果(find.TokenIndex>0)
{
//在突出显示的文本之前留下了一些内容,
//因此,使原始文本只包含该部分
found.TextNode.Text=found.TextNode.Text.Remove(found.TokenIndex);
//我们需要设置此选项以保留文本运行之间的空格
found.TextNode.Space=新的枚举值(SpaceProcessingModeValues.Preserve);
}
其他的
{
//突出显示的文本之前没有任何内容--请删除不需要的文本
段落.RemoveChild(found.Run);
}
}
此代码用于突出显示I
,前进
,或者学校
我要上学
句子中的单词。@pfx:你能检查一下吗?你能添加文档以及任何其他代码让用户轻松重现你的问题吗?我已经在我的帖子中添加了代码,如果你需要文档,只需将我的第2点添加到代码-添加中,我就去sc
void HighLightText(Paragraph paragraph, string text)
{
// Search for a first occurrence of the text in the text runs
var found = paragraph
.Descendants<Run>()
.Where(r => !string.IsNullOrEmpty(r.InnerText) && r.InnerText != "\\s")
.Select(r =>
{
var runText = r.GetFirstChild<Text>();
int index = runText.Text.IndexOf(text, StringComparison.OrdinalIgnoreCase);
// 'Run' is a reference to the text run we found,
// TextNode is a reference to the run's Text object,
// 'TokenIndex` is the index of the search string in run's text
return new { Run = r, TextNode = runText, TokenIndex = index };
})
.FirstOrDefault(o => o.TokenIndex >= 0);
// Nothing found -- escape
if (found == null)
{
return;
}
// Create a node for highlighted text as a clone (to preserve formatting etc)
var highlightRun = found.Run.CloneNode(true);
// Add the highlight node after the found text run and set up the highlighting
paragraph.InsertAfter(highlightRun, found.Run);
highlightRun.GetFirstChild<Text>().Text = text;
RunProperties runPro = new RunProperties();
Highlight highlight = new Highlight { Val = HighlightColorValues.Yellow };
runPro.AppendChild(highlight);
highlightRun.InsertAt(runPro, 0);
// Check if there's some text in the text run *after* the found text
int remainderLength = found.TextNode.Text.Length - found.TokenIndex - text.Length;
if (remainderLength > 0)
{
// There is some text after the highlighted section --
// insert it in a separate text run after the highlighted text run
var remainderRun = found.Run.CloneNode(true);
paragraph.InsertAfter(remainderRun, highlightRun);
var textNode = remainderRun.GetFirstChild<Text>();
textNode.Text = found.TextNode.Text.Substring(found.TokenIndex + text.Length);
// We need to set up this to preserve the spaces between text runs
textNode.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Preserve);
}
// Check if there's some text *before* the found text
if (found.TokenIndex > 0)
{
// Something is left before the highlighted text,
// so make the original text run contain only that portion
found.TextNode.Text = found.TextNode.Text.Remove(found.TokenIndex);
// We need to set up this to preserve the spaces between text runs
found.TextNode.Space = new EnumValue<SpaceProcessingModeValues>(SpaceProcessingModeValues.Preserve);
}
else
{
// There's nothing before the highlighted text -- remove the unneeded text run
paragraph.RemoveChild(found.Run);
}
}