[英]Error when trying to Replace Text with Image in docx header using OpenXML
So up until recently this code worked, and then the users changed the format of the headers.所以直到最近这段代码才起作用,然后用户改变了标题的格式。
I am using C# and OpenXML to edit the term [Sample Client] out of a header and replacing it with an Image.我正在使用 C# 和 OpenXML 从 header 中编辑术语 [Sample Client] 并将其替换为图像。 This has worked in the past, and actually works with some of the headers, but not others.这在过去有效,实际上适用于某些标题,但不适用于其他标题。 I can't figure out why.我不知道为什么。 The error I get is "Cannot insert the OpenXmlElement "newChild" because it is part of a tree".我得到的错误是“无法插入 OpenXmlElement “newChild”,因为它是树的一部分”。
It fails on the line:它在线上失败:
textPlaceHolder.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Drawing>(element, textPlaceHolder);
I have found some answers mentioning that I have to use CloneNode, but I am not sure how to implement that, or why.我发现一些答案提到我必须使用 CloneNode,但我不确定如何实现它,或者为什么。 I could use some assistance.我可以使用一些帮助。
Sorry for the terrible code.对不起,糟糕的代码。
private static string AddImageToHeader(WordprocessingDocument wordDoc, string relationshipId, int xwidth, int yheight)
{
LogWriter log = new LogWriter("");
// Define the reference of the image.
string results = "";
var element =
new DocumentFormat.OpenXml.Wordprocessing.Drawing(
new DW.Inline(
//new DW.Extent() { Cx = 990000, Cy = 792000L },
new DW.Extent() { Cx = xwidth, Cy = yheight },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Header Image"
},
new DW.NonVisualGraphicFrameDrawingProperties(
new A.GraphicFrameLocks() { NoChangeAspect = true }),
new A.Graphic(
new A.GraphicData(
new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)0U,
Name = "New Bitmap Image.jpg"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri =
"{28A0092B-C50C-407E-A947-70E740481C1C}"
})
)
{
Embed = relationshipId,
CompressionState =
A.BlipCompressionValues.Print
},
new A.Stretch(
new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(
new A.Offset() { X = 0L, Y = 0L },
new A.Extents() { Cx = xwidth, Cy = yheight }),
new A.PresetGeometry(
new A.AdjustValueList()
)
{
Preset = A.ShapeTypeValues.Rectangle
})
)
)
{ Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
)
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U,
EditId = "50D07946"
});
// Append the reference to body, the element should be in a Run.
// Search for text holder
Text textPlaceHolder = null;
try
{
foreach (var headerPart in wordDoc.MainDocumentPart.HeaderParts)
{
//Gets the text in headers
textPlaceHolder = headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>().Where((x) => x.Text.Contains("Sample Client")).First();
// Insert image (the image created with your function) after text place holder.
textPlaceHolder.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Drawing>(element, textPlaceHolder);
// Remove text place holder.
textPlaceHolder.Remove();
// }
foreach (var currentText in headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>())
{
currentText.Text = currentText.Text.Replace("[", "");
currentText.Text = currentText.Text.Replace("]", "");
}
}
}
catch (Exception ex)
{
results = results + "\r\n" + ex.Message.ToString();
log.LogWrite("ERROR adding image to header: "+ex.Message.ToString());
log.ErrorWrite("ERROR adding image to header: " + ex.Message.ToString());
textPlaceHolder = null;
Console.WriteLine(results);
}
if (textPlaceHolder == null)
{
log.ErrorWrite("Error textPlaceHolder is null");
}
else
{
var parent = textPlaceHolder.Parent;
if (!(parent is Run)) // Parent should be a run element.
{
results = results + "\r\nERROR: Parent is not run\r\n";
//log.LogWrite("ERROR: Parent is not run");
}
else
{
// Insert image (the image created with your function) after text place holder.
textPlaceHolder.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Drawing>(element, textPlaceHolder);
// Remove text place holder.
textPlaceHolder.Remove();
}
}
return results;
}
The issue was that I was using the same ImagePart in each of the headers.问题是我在每个标题中使用了相同的 ImagePart。 I changed my code so that it generated a new ImagePart for each header and it worked.我更改了我的代码,以便它为每个 header 生成一个新的 ImagePart 并且它可以工作。
public string AddImage2(string file, string imageLoc)
{
string results = "";
if (imageLoc != "")
{
try
{
using (WordprocessingDocument document = WordprocessingDocument.Open(file, true))
{
//remove document protection
DocumentFormat.OpenXml.Wordprocessing.DocumentProtection dp = document.MainDocumentPart.DocumentSettingsPart.Settings.GetFirstChild<DocumentFormat.OpenXml.Wordprocessing.DocumentProtection>();
if (dp != null && dp.Enforcement == OnOffValue.FromBoolean(true) && dp.Edit == DocumentFormat.OpenXml.Wordprocessing.DocumentProtectionValues.ReadOnly)
{
log.LogWrite("DOCUMENT PROTECTED");
}
else
{
dp.Enforcement = OnOffValue.FromBoolean(false);
//results = results + "\r\nDOCUMENT NOT PROTECTED\r\n";
//log.LogWrite("Document Not Protected");
}
//end doc protection removal
MainDocumentPart mainPart = document.MainDocumentPart;
try
{
// get conversion factor for image to fit the 200 X 75 image slot
int iWidth = 0;
int iHeight = 0;
using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(imageLoc))
{
iWidth = bmp.Width;
iHeight = bmp.Height;
}
double ratio = 1;
if (iHeight > 75)
{
ratio = 75 / (double)iHeight;
}
if ((iWidth * ratio) > 200)
{
ratio = 250 / (double)iWidth;
}
double conversionFactor = ratio * 9525;
iWidth = (int)Math.Round((decimal)iWidth * (decimal)conversionFactor);
iHeight = (int)Math.Round((decimal)iHeight * (decimal)conversionFactor);
// end conversion code
foreach (var headerPart in document.MainDocumentPart.HeaderParts)
{
ImagePart imagePart = headerPart.AddImagePart(ImagePartType.Jpeg);
using (FileStream imageStream = new FileStream(imageLoc, FileMode.Open))
{
imagePart.FeedData(imageStream);
}
string addImageResult = AddImageToHeader(headerPart, headerPart.GetIdOfPart(imagePart), iWidth, iHeight);
results = results + "\r\n" + addImageResult;
//log.LogWrite(addImageResult);
}
results = results + "\r\nImage " + imageLoc + " added to " + file + "\r\n";
log.LogWrite("Image " + imageLoc + " added to " + file);
}
catch (Exception ex)
{
results = results + "\r\nERROR: Unable to add Image. Exception Thrown: \r\n" + ex.Message;
log.LogWrite("ERROR: Unable to add Image. Exception Thrown: " + ex.Message);
log.ErrorWrite("ERROR: Unable to add Image. Exception Thrown: " + ex.Message);
Console.WriteLine(results);
}
}
}
catch (Exception ex)
{
results = results + "\r\nERROR: Document " + file + " Failed to Open\r\n Exception:\r\n" + ex.Message.ToString();
Console.WriteLine(results);
log.LogWrite("ERROR: Document " + file + " Failed to Open\r\n Exception:" + ex.Message.ToString());
log.ErrorWrite("ERROR: Document " + file + " Failed to Open\r\n Exception:" + ex.Message.ToString());
}
}
else
{
results = "\r\nERROR: No Image to add for " + file;
log.LogWrite("ERROR: No Image to add for " + file);
log.ErrorWrite("ERROR: No Image to add for " + file);
}
return results;
}
private string AddImageToHeader(HeaderPart headerPart, string relationshipId, int xwidth, int yheight)
{
// Define the reference of the image.
string results = "";
var element =
new DocumentFormat.OpenXml.Wordprocessing.Drawing(
new DW.Inline(
//new DW.Extent() { Cx = 990000, Cy = 792000L },
new DW.Extent() { Cx = xwidth, Cy = yheight },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Header Image"
},
new DW.NonVisualGraphicFrameDrawingProperties(
new A.GraphicFrameLocks() { NoChangeAspect = true }),
new A.Graphic(
new A.GraphicData(
new PIC.Picture(
new PIC.NonVisualPictureProperties(
new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)0U,
Name = "New Bitmap Image.jpg"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri =
"{28A0092B-C50C-407E-A947-70E740481C1C}"
})
)
{
Embed = relationshipId,
CompressionState =
A.BlipCompressionValues.Print
},
new A.Stretch(
new A.FillRectangle())),
new PIC.ShapeProperties(
new A.Transform2D(
new A.Offset() { X = 0L, Y = 0L },
new A.Extents() { Cx = xwidth, Cy = yheight }),
new A.PresetGeometry(
new A.AdjustValueList()
)
{
Preset = A.ShapeTypeValues.Rectangle
})
)
)
{ Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
)
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U,
EditId = "50D07946"
});
// Append the reference to body, the element should be in a Run.
// Search for text holder
Text textPlaceHolder = null;
try
{
//int iterationcount = 0;
textPlaceHolder = headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>().Where((x) => x.Text.Contains("Sample Client")).First();
// Insert image (the image created with your function) after text place holder.
//var cloneElement = element.CloneNode();
textPlaceHolder.Parent.InsertAfter<DocumentFormat.OpenXml.Wordprocessing.Drawing>(element, textPlaceHolder);
// Remove text place holder.
textPlaceHolder.Remove();
// }
//clean up brackets
foreach (var currentText in headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>())
{
currentText.Text = currentText.Text.Replace("[", "");
currentText.Text = currentText.Text.Replace("]", "");
}
}
catch (Exception ex)
{
results = results + "\r\n" + ex.Message.ToString();
log.LogWrite("ERROR adding image to header: "+ex.Message.ToString());
log.ErrorWrite("ERROR adding image to header: " + ex.Message.ToString());
textPlaceHolder = null;
Console.WriteLine(results);
}
if (textPlaceHolder == null)
{
log.ErrorWrite("Error textPlaceHolder is null");
}
return results;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.