Reputation: 2514
I'm having some troubles with OPEN XML during the image creation.
I'm replacing some Text inside the document with some images. If I replace 1 to 3 images the saved file is perfect: the images are shown and everything looks good.
If I replace more than 3 images the file results corrupted and after the Microsoft Word "recovery" it's perfect too.
I tried to move images, to change the order, to change the images and so on, but when I go over the 3 inserted image the doc seems to be broken.
Here is the method I call:
private static void ReplaceTextWithImage(string find, string filepath, Bitmap bitmap, int incremental)
{
using (WordprocessingDocument doc = WordprocessingDocument.Open(filepath, true))
{
MainDocumentPart mainPart = doc.MainDocumentPart;
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
using (var ms = new MemoryStream())
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
imagePart.FeedData(ms);
}
var relID = mainPart.GetIdOfPart(imagePart);
var element =
new Drawing(
new DW.Inline(
new DW.Extent() { Cx = 990000L * (long)(7.13 / 1.08), Cy = 792000L * (long)(8.51 / 0.87) },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "img" + incremental
},
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 = "img" + incremental + ".jpg"
},
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension()
{
Uri = Guid.NewGuid().ToString()
})
)
{
Embed = relID,
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 = 990000L * (long)(7.13 / 1.08), Cy = 792000L * (long)(8.51 / 0.87) }),
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"
});
var paragraphs = doc.MainDocumentPart.Document.Body.ChildElements.First(x => x.OuterXml.Contains(find));
doc.MainDocumentPart.Document.Body.InsertAfter(new Paragraph(new Run(element)), paragraphs);
doc.MainDocumentPart.Document.Body.RemoveChild(paragraphs);
doc.Close();
}
}
As you can see it's the very tipical method, I already tried to change some ID etc but without success!
Upvotes: 0
Views: 1653
Reputation: 254
This maybe an old thread, but I thought I'd answer this question seeing as I was faced with it earlier today. You need to give the images a unique Id to everything else that is contained within the XML document.
new DW.DocProperties()
{
Id = (UInt32Value)1U, // THIS NEEDS TO BE A UNIQUE VALUE
Name = "img" + incremental
},
As does this...
new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)0U, // UNIQUE VALUE HERE AS WELL
Also EditId is not supported with word earlier than 2010.
I noticed the code is from MSDN, and as usual with their stuff, it is rubbish with very little explanation.
Also I would recommend using the validation tool to check for any other underlying problems...
Stick this in your code and run it against your doc.
using DocumentFormat.OpenXml.Validation;
using System.Diagnostics;
public static bool IsDocumentValid(WordprocessingDocument mydoc)
{
OpenXmlValidator validator = new OpenXmlValidator();
var errors = validator.Validate(mydoc);
Debug.Write(Environment.NewLine);
foreach (ValidationErrorInfo error in errors)
Debug.Write(error.Description + Environment.NewLine);
return (errors.Count() == 0);
}
Upvotes: 2
Reputation: 161
Try opening up the document with error using OpenXml SDK 2.0 productivity tool and see if you can find the error in the document.xml file.
Also, if the text is static, you can think about adding content controls and then replacing them dynamically.
Upvotes: 1