我正在使用以下代码使用openxml突出显示Powerpoint演示文稿(.pptx)中的文本,但在pptx的以下代码中-它损坏了文件并在打开pptx时要求修复,并且在打开后突出显示了该单词,但未保留格式。因此共有2个问题:
1. File gets corrupted
2. Formatting is not preserved
But it highlights the text which i want (but it does not preserve formatting)
I have debuged my code line by line and problem is at below line, but i am not able to figure out what is the problem.
highlightRun.InsertAt(runPro, 0);
我已经使用openxml生产力工具比较了pptx的两个文件,其中一个未突出显示,一个突出显示:我看到的区别如下:我没有使用两次RunProperty,而是显示了2次:
损坏的文件:
public Run GenerateRun()
{
Run run1 = new Run();
RunProperties runProperties1 = new RunProperties(){ Language = "en-US", Dirty = false };
runProperties1.SetAttribute(new OpenXmlAttribute("", "smtClean", "", "0"));
SolidFill solidFill1 = new SolidFill();
RgbColorModelHex rgbColorModelHex1 = new RgbColorModelHex(){ Val = "FFF000" };
solidFill1.Append(rgbColorModelHex1);
runProperties1.Append(solidFill1);
RunProperties runProperties2 = new RunProperties(){ Language = "en-US", Dirty = false };
runProperties2.SetAttribute(new OpenXmlAttribute("", "smtClean", "", "0"));
SolidFill solidFill2 = new SolidFill();
RgbColorModelHex rgbColorModelHex2 = new RgbColorModelHex(){ Val = "FFFF00" };
solidFill2.Append(rgbColorModelHex2);
runProperties2.Append(solidFill2);
Text text1 = new Text();
text1.Text = "gaits";
run1.Append(runProperties1);
run1.Append(runProperties2);
run1.Append(text1);
return run1;
}
<a:r xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:rPr lang="en-US" dirty="0" smtClean="0">
<a:solidFill>
<a:srgbClr val="FFF000" />
</a:solidFill>
</a:rPr>
<a:rPr lang="en-US" dirty="0" smtClean="0">
<a:solidFill>
<a:srgbClr val="FFFF00" />
</a:solidFill>
</a:rPr>
<a:t>gaits</a:t>
</a:r>
更正文件:
public class GeneratedClass
{
// Creates an Run instance and adds its children.
public Run GenerateRun()
{
Run run1 = new Run();
RunProperties runProperties1 = new RunProperties(){ Language = "en-US", Dirty = false };
runProperties1.SetAttribute(new OpenXmlAttribute("", "smtClean", "", "0"));
SolidFill solidFill1 = new SolidFill();
RgbColorModelHex rgbColorModelHex1 = new RgbColorModelHex(){ Val = "FFFF00" };
solidFill1.Append(rgbColorModelHex1);
runProperties1.Append(solidFill1);
Text text1 = new Text();
text1.Text = "gaits";
run1.Append(runProperties1);
run1.Append(text1);
return run1;
}
<a:r xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:rPr lang="en-US" dirty="0" smtClean="0">
<a:solidFill>
<a:srgbClr val="FFFF00" />
</a:solidFill>
</a:rPr>
<a:t>gaits</a:t>
</a:r>
我缺少什么?我完整的代码如下:
using OpenXmlDrawing = DocumentFormat.OpenXml.Drawing;
private void HighLightTextPresentation(OpenXmlDrawing.Paragraph paragraph, string text)
{
var found = paragraph
.Descendants<OpenXmlDrawing.Run>()
.Where(r => !string.IsNullOrEmpty(r.InnerText) && r.InnerText != "\\s")
.Select(r =>
{
var runText = r.GetFirstChild<OpenXmlDrawing.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<OpenXmlDrawing.Text>().Text = text;
DocumentFormat.OpenXml.Drawing.RunProperties runPro = new DocumentFormat.OpenXml.Drawing.RunProperties() { Language = "en-US", Dirty = false };
runPro.SetAttribute(new OpenXmlAttribute("", "smtClean", "", "0"));
//Apply color to searched text
DocumentFormat.OpenXml.Drawing.SolidFill solidFill1 = new DocumentFormat.OpenXml.Drawing.SolidFill();
DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColorModelHex1 = new DocumentFormat.OpenXml.Drawing.RgbColorModelHex() { Val = "FFF000" };//Set Font-Color to Green (Hex "00B050").
solidFill1.Append(rgbColorModelHex1);
runPro.Append(solidFill1);
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);
OpenXmlDrawing.Text textNode = remainderRun.GetFirstChild<OpenXmlDrawing.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);
}
}
答案 0 :(得分:2)
如评论中所述,“被破坏”的原因是,您可以通过在a:rPr
元素中创建一个额外的RunProperties
元素(a:r
)来使XML结构无效( Run
),而只允许一个。
因此,在插入新元素之前,应首先检查RunProperties
中是否已经有Run
元素。如果RunProperties
元素已经存在,则应改用它。
// Either reuse an existing RunProperties element,
// or create a new one if there's none
RunProperties runPro = highlightRun.Descendants<RunProperties>().FirstOrDefault() ??
new RunProperties { Language = "en-US", Dirty = false };
// only add the element if it's really new, don't add existing one
if (runPro.Parent == null)
{
highlightRun.InsertAt(runPro, 0);
}