Adding image in word document - c#

When I add an image to a word document then, when I open word it is showing me an XML error. The file cannot be opened because there is a problem with the content.
See error ->
I took reference from the below link.
Adding image to word document using OpenXML
and from Microsoft site
https://learn.microsoft.com/en-us/office/open-xml/how-to-insert-a-picture-into-a-word-processing-document
My Code is as follows: add Open XML to your project reference.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using A = DocumentFormat.OpenXml.Drawing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
namespace InsertImageWord
{
class Program
{
static void Main(string[] args)
{
//References
//https://www.e-iceblue.com/Tutorials/Spire.Doc/OpenXML/How-to-Insert-a-picture-into-a-word-processing-document.html
//https://coders-corner.net/2015/04/11/open-xml-add-a-picture/
//https://learn.microsoft.com/en-us/office/open-xml/how-to-insert-a-picture-into-a-word-processing-document
//file name
string folder = #"E:\TestImage";
string fileName = folder + #"\BlankDocument.doc";
string imageFileName = folder + #"\DesertTest.png";
//create file
using (var file = WordprocessingDocument.Create(
fileName, WordprocessingDocumentType.Document))
{
file.AddMainDocumentPart();
//add image part and add image from file
ImagePart imagePart = file.MainDocumentPart.AddImagePart(ImagePartType.Png);
using (FileStream stream = new FileStream(imageFileName, FileMode.Open))
{
imagePart.FeedData(stream);
}
//set content
var text = new Text("Hello Open XML world");
var run = new Run(text);
var paragraph = new Paragraph(run);
var body = new Body(paragraph);
var document = new Document(body);
//add image
Drawing imageElement = GetImageElement(
file.MainDocumentPart.GetIdOfPart(imagePart),
imageFileName,
"my image",
22,
22);
body.AppendChild(new Paragraph(new Run(imageElement)));
//save
file.MainDocumentPart.Document = document;
file.MainDocumentPart.Document.Save();
}
}
private static Drawing GetImageElement(
string imagePartId,
string fileName,
string pictureName,
double width,
double height)
{
double englishMetricUnitsPerInch = 914400;
double pixelsPerInch = 96;
//calculate size in emu
double emuWidth = width * englishMetricUnitsPerInch / pixelsPerInch;
double emuHeight = height * englishMetricUnitsPerInch / pixelsPerInch;
var element = new Drawing(
new DW.Inline(
new DW.Extent { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight },
new DW.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
new DW.DocProperties { Id = (UInt32Value)1U, Name = pictureName },
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 = fileName },
new PIC.NonVisualPictureDrawingProperties()),
new PIC.BlipFill(
new A.Blip(
new A.BlipExtensionList(
new A.BlipExtension { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }))
{
Embed = imagePartId,
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 = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight }),
new A.PresetGeometry(
new A.AdjustValueList())
{ Preset = A.ShapeTypeValues.Rectangle })))
{
Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture"
}))
{
DistanceFromTop = 0U,
DistanceFromBottom = 0U,
DistanceFromLeft = 0U,
DistanceFromRight = 0U,
EditId = "50D07946"
});
return element;
}
}
}
Please help me out of this. Thanks in Advance

your imageparttype has to match the mimetype of your image

Related

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. 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".
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. 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. I changed my code so that it generated a new ImagePart for each header and it worked.
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;
}

OpenXML added Image is in the Document media folder but not displayed in Office

I have trouble creating a Word Document (openXML) and adding an image to it. I already tried a lot with code snippets i found only as well as the offical MS Documentation (https://learn.microsoft.com/de-de/office/open-xml/how-to-insert-a-picture-into-a-word-processing-document).
To get this working I basically copied the complete Code from the Link above and wrapped 2 WPF FileDialogs around to create a Document first, and then choose the Image to add. I also add some text before the image to check if accessing the document works in general.
Everything compiles and runs without errors. However the created Document only has my text and no sign of the image. I often read about people having errors like "a red X" or some sign of the ressource of an added image being missing, but for me the document simply contains nothing but the added text.
HOWEVER when i open the Document as an archive (using winrar for example) I can see the image i have chosen is placed inside the "media" folder in my Document.
Why is nothing displayed when I open the document in an office application?
Below is my Code but its basically from the offical SDK:
using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
public static void ExportToDoc()
{
SaveFileDialog exportFile = new SaveFileDialog
{
Filter = "Word Document (*.docx)|*.docx",
AddExtension = true,
FileName = "Proposed-Filename.docx"
};
switch (exportFile.ShowDialog())
{
case true:
WordprocessingDocument doc = WordprocessingDocument.Create(exportFile.FileName, WordprocessingDocumentType.Document);
// Make some changes to the document.
MainDocumentPart mainDocumentPart = doc.AddMainDocumentPart();
mainDocumentPart.Document = new Document();
Document document = mainDocumentPart.Document;
Body body = document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Created text in body."));
//Prepare Image
OpenFileDialog openImage = new OpenFileDialog
{
Filter = "Bild (*.jpg)| *.jpg"
};
//Document is created
doc.Close();
switch (openImage.ShowDialog())
{
case true:
InsertAPicture(exportFile.FileName, openImage.FileName);
break;
default:
break;
}
Console.WriteLine("Bild angehÃĪngt");
break;
default:
break;
}
}
//from MSDN after this point:
public static void InsertAPicture(string document, string fileName)
{
using (WordprocessingDocument wordprocessingDocument =
WordprocessingDocument.Open(document, true))
{
MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
imagePart.FeedData(stream);
}
AddImageToBody(wordprocessingDocument, mainPart.GetIdOfPart(imagePart));
}
}
private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
{
// Define the reference of the image.
var element =
new DocumentFormat.OpenXml.Office.Drawing.Drawing(
new DW.Inline(
new DW.Extent() { Cx = 990000L, Cy = 792000L },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Picture 1"
},
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 = 990000L, Cy = 792000L }),
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.
wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element)));
}
}
Ok I figured it out myself:
I was using the wrong Namespace for Drawing. Thats it.
Funny how this didnt produce any errors at all but did not work.
So if you have this Problem here is what I changed:
private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
{
// Define the reference of the image.
var element =
new DocumentFormat.OpenXml.Office.Drawing.Drawing(
Changed to:
private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
{
// Define the reference of the image.
var element =
new DocumentFormat.OpenXml.Wordprocessing.Drawing(

Word Open XML: file corrupted if more than 3 images are inserted

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!
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);
}
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.

Open XML SDK - AddImagePart - Change image location from /media to /word/media

I am trying to insert an image into a document from C# using the Open XML SDK 2.5. The document is subsequently going to be uploaded to Google Drive and converted to a Google Document.
I am currently using the MainDocumentPart.AddImagePart method which inserts the image into the /media folder of the file hierarchy. However, Drive only wants to read the image if it is located in the /word/media folder.
Opening the document in Microsoft Word and saving it again relocates the image to the /word/media folder (and updates the part relationships), and thus makes Drive able to read the image, but the file is not going to be edited in Word before being uploaded to Drive.
Is there any way to place the image in the /word/media folder, short of closing the file in Open XML SDK, opening it up as a zip-archive, relocating the images and updating the relationships manually?
To add an image to the /word/media folder using the Open XML SDK 2.5
you have to create the package part for the image yourself.
The AddImagePart() member function of the MainDocumentPart class
always stores the image in the /media folder.
The code below shows how to insert an image into the /word/media folder
using the following steps:
Create a PackagePart with the path Uri set to /word/media.
Feed the image data into the package part.
Create a PackageReleationship for the image.
Use the ID of the PackageReleationship to reference the image in
the word document.
I've copied the code for the AddImageToBody() function
from this MSDN website.
static void Main(string[] args)
{
InsertAPicture("mydoc.docx", "mypic.jpg");
}
public static void InsertAPicture(string document, string fileName)
{
using (WordprocessingDocument wordprocessingDocument =
WordprocessingDocument.Open(document, true))
{
MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
Uri imageUri = new Uri("/word/media/" +
System.IO.Path.GetFileName(fileName), UriKind.Relative);
// Create "image" part in /word/media
// Change content type for other image types.
PackagePart packageImagePart =
wordprocessingDocument.Package.CreatePart(imageUri, "Image/jpeg");
// Feed data.
byte[] imageBytes = File.ReadAllBytes(fileName);
packageImagePart.GetStream().Write(imageBytes, 0, imageBytes.Length);
PackagePart documentPackagePart =
mainPart.OpenXmlPackage.Package.GetPart(new Uri("/word/document.xml", UriKind.Relative));
Console.Out.WriteLine(documentPackagePart.Uri);
// URI to the image is relative to releationship document.
PackageRelationship imageReleationshipPart = documentPackagePart.CreateRelationship(
new Uri("media/" + System.IO.Path.GetFileName(fileName), UriKind.Relative),
TargetMode.Internal, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
AddImageToBody(wordprocessingDocument, imageReleationshipPart.Id);
}
}
private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
{
var element =
new Drawing(
new DW.Inline(
new DW.Extent() { Cx = 990000L, Cy = 792000L },
new DW.EffectExtent()
{
LeftEdge = 0L,
TopEdge = 0L,
RightEdge = 0L,
BottomEdge = 0L
},
new DW.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Picture 1"
},
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 = 990000L, Cy = 792000L }),
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"
});
wordDoc.MainDocumentPart.Document.Body.AppendChild(
new DocumentFormat.OpenXml.Wordprocessing.Paragraph(
new DocumentFormat.OpenXml.Wordprocessing.Run(element)));
}
Of course, if you want to add other image types (e.g. PNG) you have to change the
the content type.

Images are not coming after creating word Document through Open XML

I am Creating a word document through the c# with the use of OpenXMl sdk.
I am converting all my html page to word document but while converting i am giving a absolute address for my images and after converting it is coming perfectly in my system but when i am trying to take this document to other system the Images are Not Coming there.
I checked the media Directory all images are there but with different Name.
my document is converted but I am Using this mathod.
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(documentPath, true))
{
XNamespace w =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace r =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships";
string altChunkId = "AltChunkId1";
MainDocumentPart mainPart = myDoc.MainDocumentPart;
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart("application/xhtml+xml", altChunkId);
using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
using (StreamWriter stringStream = new StreamWriter(chunkStream))
stringStream.Write(html);
XElement altChunk = new XElement(w + "altChunk",
new XAttribute(r + "id", altChunkId)
);
XDocument mainDocumentXDoc = GetXDocument(myDoc);
mainDocumentXDoc.Root
.Element(w + "body")
.Elements(w + "p")
.Last()
.AddAfterSelf(altChunk);
SaveXDocument(myDoc, mainDocumentXDoc);
}
private static XDocument GetXDocument(WordprocessingDocument myDoc)
{
// Load the main document part into an XDocument
XDocument mainDocumentXDoc;
using (Stream str = myDoc.MainDocumentPart.GetStream())
using (XmlReader xr = XmlReader.Create(str))
mainDocumentXDoc = XDocument.Load(xr);
return mainDocumentXDoc;
}
private static void SaveXDocument(WordprocessingDocument myDoc,
XDocument mainDocumentXDoc)
{
// Serialize the XDocument back into the part
using (Stream str = myDoc.MainDocumentPart.GetStream(
FileMode.Create, FileAccess.Write))
using (XmlWriter xw = XmlWriter.Create(str))
mainDocumentXDoc.Save(xw);
}
and this will generate a afchunk.dat file which is showing in the content and the Absolute path.
Basically i doesn't want to create a file through all coding i just want to convert the .html to .docx file .
so can any one tell me how can i convert without getting error in html.
Is there a reason you aren't embedding the images? Here's a link with sample code to show you how.
http://msdn.microsoft.com/en-us/library/bb497430.aspx
Try to create a DocumentResource (Item->Add new) and associate the images there.
Call the Document
using (Stream imgStream = ip.GetStream())
{
System.Drawing.Bitmap logo = DocumentResources._default;
logo.Save(imgStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Drawing drawing = BuildImage(imageRelationshipID, "_default.jpg", 200, 30);
And create the method to build image in the header or footer;
private static Drawing BuildImage(string imageRelationshipID, string imageName, int pixelWidth, int pixelHeight)
{
int emuWidth = (int)(pixelWidth * EMU_PER_PIXEL);
int emuHeight = (int)(pixelHeight * EMU_PER_PIXEL);
Drawing drawing = new Drawing();
d.Wordprocessing.Inline inline = new d.Wordprocessing.Inline { DistanceFromTop = 0, DistanceFromBottom = 0, DistanceFromLeft = 0, DistanceFromRight = 0 };
d.Wordprocessing.Anchor anchor = new d.Wordprocessing.Anchor();
d.Wordprocessing.SimplePosition simplePos = new d.Wordprocessing.SimplePosition { X = 0, Y = 0 };
d.Wordprocessing.Extent extent = new d.Wordprocessing.Extent { Cx = emuWidth, Cy = emuHeight };
d.Wordprocessing.DocProperties docPr = new d.Wordprocessing.DocProperties { Id = 1, Name = imageName };
d.Graphic graphic = new d.Graphic();
d.GraphicData graphicData = new d.GraphicData { Uri = GRAPHIC_DATA_URI };
d.Pictures.Picture pic = new d.Pictures.Picture();
d.Pictures.NonVisualPictureProperties nvPicPr = new d.Pictures.NonVisualPictureProperties();
d.Pictures.NonVisualDrawingProperties cNvPr = new d.Pictures.NonVisualDrawingProperties { Id = 2, Name = imageName };
d.Pictures.NonVisualPictureDrawingProperties cNvPicPr = new d.Pictures.NonVisualPictureDrawingProperties();
d.Pictures.BlipFill blipFill = new d.Pictures.BlipFill();
d.Blip blip = new d.Blip { Embed = imageRelationshipID };
d.Stretch stretch = new d.Stretch();
d.FillRectangle fillRect = new d.FillRectangle();
d.Pictures.ShapeProperties spPr = new d.Pictures.ShapeProperties();
d.Transform2D xfrm = new d.Transform2D();
d.Offset off = new d.Offset { X = 0, Y = 0 };
d.Extents ext = new d.Extents { Cx = emuWidth, Cy = emuHeight };
d.PresetGeometry prstGeom = new d.PresetGeometry { Preset = d.ShapeTypeValues.Rectangle };
d.AdjustValueList avLst = new d.AdjustValueList();
xfrm.Append(off);
xfrm.Append(ext);
prstGeom.Append(avLst);
stretch.Append(fillRect);
spPr.Append(xfrm);
spPr.Append(prstGeom);
blipFill.Append(blip);
blipFill.Append(stretch);
nvPicPr.Append(cNvPr);
nvPicPr.Append(cNvPicPr);
pic.Append(nvPicPr);
pic.Append(blipFill);
pic.Append(spPr);
graphicData.Append(pic);
graphic.Append(graphicData);
inline.Append(extent);
inline.Append(docPr);
inline.Append(graphic);
drawing.Append(inline);
return drawing;
}

Categories