Having trouble replacing an image in a ActiveX Image Control. No problems replacing a normal image. I used the control so I could use the PictureSizeMode = fmPictureSizeModeZoom.
The test unit is
[TestMethod]public void test_ReplaceLogo(){ private string testPath = @"Path to files\"; private string testLogoSheet = "Logo Reserved.xlsx"; // contains only a activex image control with a default bmp already loaded containing the text 'Reserved Logo' private string testLogoSave = "Logo Saved.xlsx"; private string testLogoNew = @"Path to Logo\logo.bmp"; File.Copy(testPath + testLogoSheet, testPath + testLogoSave, true); using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(testPath + testLogoSave, true)) { foreach (WorksheetPart worksheetPart in spreadsheetDocument.WorkbookPart.WorksheetParts) { ImagePart imagePart = TableUtil.getImagePart(worksheetPart, "pLogo"); TableUtil.saveImagePart(imagePart, testLogoNew); } spreadsheetDocument.WorkbookPart.Workbook.Save(); }}
and from the utility class
/// <summary> /// Retrieve the anchor from the image name. /// </summary> /// <param name="worksheetPart">The WorksheetPart to retrieve the ImagePart from.</param> /// <param name="imageName">The name of the control.</param> /// <returns>If found, returns the TwoCellAnchor. If not found, returns null.</returns> public static SSS.TwoCellAnchor getTwoCellAnchorFromImageName(DrawingsPart DrawingsPart, string imageName) { SSS.TwoCellAnchor ReturnValue = null; if (DrawingsPart != null) { foreach (SSS.TwoCellAnchor twoCellAnchor in DrawingsPart.WorksheetDrawing.Descendants<SSS.TwoCellAnchor>()) { if (twoCellAnchor.Descendants<SSS.Shape>().Count() > 0) { SSS.Shape shape = twoCellAnchor.Descendants<SSS.Shape>().FirstOrDefault(); if (shape.NonVisualShapeProperties.NonVisualDrawingProperties.Name.ToString().Contains(imageName)) { ReturnValue = twoCellAnchor; } } } } return ReturnValue; } /// <summary> /// Retrieve the rId of a imagepart associated with an anchor from the image name. /// </summary> /// <param name="worksheetPart">The WorksheetPart to retrieve the rId from.</param> /// <param name="imageName">The name of the control.</param> /// <returns>If found, returns the rId. If not found, returns null.</returns> public static uint getTwoCellAnchorRefIdFromImageName(DrawingsPart DrawingsPart, string imageName) { uint ReturnValue = (uint)0; if (DrawingsPart != null) { foreach (SSS.TwoCellAnchor twoCellAnchor in DrawingsPart.WorksheetDrawing.Descendants<SSS.TwoCellAnchor>()) { if (twoCellAnchor.Descendants<SSS.Shape>().Count() > 0) { SSS.Shape shape = twoCellAnchor.Descendants<SSS.Shape>().FirstOrDefault(); if (shape.NonVisualShapeProperties.NonVisualDrawingProperties.Name.ToString().Contains(imageName)) { ReturnValue = shape.NonVisualShapeProperties.NonVisualDrawingProperties.Id; } } } } return ReturnValue; } /// <summary> /// Retrieve a ImagePart based on a controls name. /// </summary> /// <param name="worksheetPart">The WorksheetPart to retrieve the ImagePart from.</param> /// <param name="imageName">The name of the control.</param> /// <returns>If found, returns the ImagePart. If not found, returns null.</returns> public static ImagePart getImagePart(WorksheetPart worksheetPart, string imageName) { ImagePart imagePart = null; SSS.TwoCellAnchor twoCellAnchor = null; if (worksheetPart.DrawingsPart!=null) { twoCellAnchor = getTwoCellAnchorFromImageName(worksheetPart.DrawingsPart, imageName); } if (twoCellAnchor != null) { uint shapeId = getTwoCellAnchorRefIdFromImageName(worksheetPart.DrawingsPart, imageName); foreach (ss.Control control in worksheetPart.Worksheet.Descendants<ss.Control>()) { if (control.Name.Value.Equals(imageName)&&control.ShapeId.InnerText.Equals(shapeId.ToString())) { //uint shapeId = control.ShapeId; string controlPtId = control.ControlProperties.Id.Value; imagePart = (ImagePart)worksheetPart.GetPartById(controlPtId); break; } } } return imagePart; } /// <summary> /// Save a new image to a ImagePart /// </summary> /// <param name="imagePart">The ImagePart to save the new image to.</param> /// <param name="newImagePathName">The complete path to the new image.</param> public static void saveImagePart(ImagePart imagePart, string newImagePathName) { if (File.Exists(newImagePathName)&&imagePart!=null) { using (FileStream stream = new FileStream(newImagePathName, FileMode.Open)) { imagePart.FeedData(stream); } //var newImageBytes = File.ReadAllBytes(newImagePathName); //using(var writer = new BinaryWriter(imagePart.GetStream())) //{ // writer.Write(newImageBytes); //} } }
I have tried 2 saves. Both FeedData and BinaryWriter replaces image1.emf (opening Logo Saved.xlsx in Visual Studio and exporting image1.emf proves this) but when opening in Excel 2010, the original image is displayed ??
Has anyone had experience with this or provide some direction for me please?
Have attached a zip containing required files for a basic unit test.
ta
James