I'm currently working on a project where I need to programmatically add images to a Word document in C#. I've been following the official documentation and various tutorials, but I seem to be running into an issue where the image is not being added to the correct location within the Word document. The images are added to media/image.jpg instead of word/media/image.jpg.
Here's a simplified version of the code I'm using:
class Program
{
static DocumentFormat.OpenXml.UInt32Value ID = 1;
public static void AddBase64ImageToWordDocument(MainDocumentPart mainPart, string base64String)
{
//Uri imageUri = new Uri("/word/media/" + System.IO.Path.GetFileName(fileName), UriKind.Relative);
// Convert the base64 string to bytes
byte[] imageBytes = Convert.FromBase64String(base64String);
Body body = mainPart.Document.Body;
// Create a paragraph to hold the image
var paragraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
// Create a Run to hold the image
var run = new DocumentFormat.OpenXml.Wordprocessing.Run();
var runProperties1 = new DocumentFormat.OpenXml.Wordprocessing.RunProperties();
NoProof noProof1 = new NoProof();
runProperties1.Append(noProof1);
run.Append(runProperties1);
// Create a Drawing object to hold the image data
Drawing drawing = new Drawing();
// Create the inline image object
DW.Inline inline = new DW.Inline();
// Create the extent and the graphic data for the image
DW.Extent extent = new DW.Extent() { Cx = 3370025L, Cy = 3408129L }; // Set the image size (in EMUs) //ooh I need to come back to you
A.Graphic graphic = new A.Graphic();
var picture = new DocumentFormat.OpenXml.Wordprocessing.Picture();
picture.AddNamespaceDeclaration("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture");
// Create the ImagePart and add the image bytes to it
var newUri = new Uri("word/media/image" + ID + ".jpg", UriKind.RelativeOrAbsolute);
var stringUri = ("word/media/image" + ID + ".jpg");
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
string relationshipId = mainPart.GetIdOfPart(imagePart);
//mainPart.AddExternalRelationship( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml", newUri, relationshipId);
var relationship = mainPart.Parts.FirstOrDefault(p => p.RelationshipId == relationshipId);
//relationship.TargetUri = newUri;
var imagePath = imagePart.Uri;
Console.WriteLine(imagePath);
//imagePart.AddExternalRelationship("Internal", newUri);
using (MemoryStream stream = new MemoryStream(imageBytes))
{
imagePart.FeedData(stream);
}
A.GraphicData graphicData = (GenerateGraphicData(mainPart, imagePart)); //new A.GraphicData() { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" };
string imageRelId = mainPart.GetIdOfPart(imagePart);
mainPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", new Uri("media/image.jpg", UriKind.Relative), imageRelId);
// Set the image properties
ID++;
// Create the picture data and set its properties
A.BlipFill blipFill = new A.BlipFill();
A.Blip blip = new A.Blip() { Embed = mainPart.GetIdOfPart(imagePart) };
A.Stretch stretch = new A.Stretch();
A.FillRectangle fillRectangle = new A.FillRectangle();
stretch.Append(fillRectangle);
blipFill.Append(blip, stretch);
// Create the shape properties
A.ShapeProperties shapeProperties = new A.ShapeProperties();
// Append the image parts to the picture
//picture.Append(blipFill, shapeProperties);
// Append the picture to the graphic data
//graphicData.Append(picture);
graphic.Append(graphicData);
// Append the graphic to the inline image
inline.Append(new DW.Extent() { Cx = extent.Cx, Cy = extent.Cy }, new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DW.DocProperties() { Id = 1U, Name = "Image" }, graphic);
// Append the inline image to the drawing object
drawing.Append(inline);
// Append the drawing object to the run
run.Append(drawing);
// Append the run to the paragraph
paragraph.Append(run);
// Append the paragraph to the body
body.Append(paragraph);
}
static void Main(string[] args)
{
string processedDocFilePath = "PathToGeneratedDocument.docx";
using (var newDoc = WordprocessingDocument.Create(processedDocFilePath, WordprocessingDocumentType.Document, true))
{
MainDocumentPart mainPart = newDoc.AddMainDocumentPart();
new Document(new Body()).Save(mainPart);
string base64Image = "YourBase64ImageString"; // Actual base64 image string
AddBase64ImageToWordDocument(mainPart, base64Image);
}
}
}
The relationships might not be set up correctly. I've tried different variations of the code and URI generation, but I'm not sure what's causing the problem.
Has anyone encountered a similar issue or can provide guidance on how to correctly add images to a Word document using the Open XML SDK? Any help or advice would be greatly appreciated.
--UPDATE: I've used the openXML helper tool to generate an "identical" document and when I run the code it still fails to place the image within proper uri.