c# add a picture to excel from resources - c#

I'm currently doing the below to add an image to an excel file I'm creating via "interop"
private Excel.Workbook _xlWorkBook;
_xlWorkSheet.Shapes.AddPicture(appPath + #"\ImageFile.png", Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, 5, 5, 60, 60);
I have a couple of questions if I may.
How can I access the picture once it's added - e.g. to draw a border on it.
Doing the above for my app means that I have to distribute the image file as well so I thought I would put it in the application resources. How do I add the image from the resources to the excel file? Again once added, how do I access it to add border etc?
_xlWorkSheet.Shapes.AddPicture(Properties.Resources.ImageFile); //dosn't work
Many thanks

1.) I believe you can access the picture by using
// after adding the picture
Picture pic = (Picture) ActiveSheet.Pictures(ActiveSheet.Pictures.Count - 1);
pic.Border.LineStyle = XlLineStyle.xlContinuous;
pic.Border.Weight = XlBorderWeight.xlMedium;
Or
// add the picture using Pictures.Insert
// this should return a Picture cast-able object
Picture pic = (Picture) ActiveSheet.Pictures.Insert(FileName);
// etc...
2.) The simplest way would be to pull the file from resources write it to a temp file, add it into excel and then remove the temp file.
This code is very much untested. Excel interop is a head-ache.

Sorry or the archeology.
For the second question, adding a picture from a ressource, I may have found a solution using the clipboard:
System.Drawing.Bitmap pic = Properties.Resources.my_ressource;
System.Windows.Forms.Clipboard.SetImage(pic);
Range position = (Range)myWorksheet.Cells[Y, X];
myWorksheet.Paste(position); //copy the clipboard to the given position

RE: 2. I did this:
S = Shapes.AddPicture(filename,MsoTriState.msoFalse,MsoTriState.msoTrue,0,0,50,50);
S.Name = "Picture";
S.Placement = XlPlacement.xlMoveAndSize;

Related

Accessing Images in PowerPoint file via VSTO Add-In (C#)

I am trying to build a PowerPoint add-in that will allow me to do a one-click optimization of the current presentation by removing unused master slides and converting huge 24-bit PNG files to slightly-compressed JPGs.
I have the first part handled already, and now I'm working on the images. Although I can easily find the Shape object containing the image, I cannot find a way to access the source image through the managed API. At best, I can copy the shape to the clipboard, which does give me the image but in a different format (MemoryBmp).
using PPTX = Microsoft.Office.Interop.PowerPoint;
...
foreach (PPTX.Slide slide in Globals.ThisAddIn.Application.ActivePresentation.Slides)
{
foreach (PPTX.Shape shape in slide.Shapes)
{
if (shape.Type == MsoShapeType.msoPicture)
{
// Now, how can I access the source image contained within this shape?
// I -can- copy it via the clipboard, like this:
shape.Copy();
System.Drawing.Image image = Clipboard.GetImage();
// ...but image's format reflects a MemoryBmp ImageFormat, as noted here:
// https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/ImageFormat.cs
// ...which doesn't help me determine if the source image is something that should be optimized.
}
}
}
Obviously, I can get to the images directly via other methods (e.g. accessing the contents of the file as a ZIP, or using OpenXML SDK), but I'm trying to perform all the steps from within the already-opened presentation (which means I can't update the open file). Any thoughts on how I can do this?
You could use a Microsoft.Office.Interop.PowerPoint.Shape Export function.
void Export(string PathName, PpShapeFormat Filter, int ScaleWidth = 0, int ScaleHeight = 0, PpExportMode ExportMode = PpExportMode.ppRelativeToSlide)
There is a very little documentation of this function.
I've found it in the Shape interface definition.
So your code would look something like:
shape.Export(<some_file>, PpShapeFormat.ppShapeFormatPNG);
More info on MSDN

How to export Chart created in EPPlus to Image file

I have tried this;
var excelPicture = sheet.Drawings[0] as OfficeOpenXml.Drawing.ExcelPicture;
var img = excelPicture.Image;
However the excelPicture variable become null. How can I create image file from ExcelDrawing??
It seems that this can't be done via EPPlus API. There is the opened issue in the GitHub project repository how export the drawings to a file. But the provided solution in the question does not work (it seems #Onchomngebul himself wrote the the comment)
Alternative solution is to use Workbook class in Spire.XLS nuget-package (or via free version FreeSpire.XLS).
var workbook = new Workbook();
workbook.LoadFromFile(workbookFileName, ExcelVersion.Version2010);
var sheet = workbook.Worksheets[0]; // index or name of your worksheet
var image = workbook.SaveChartAsImage(sheet, 0); // chart index
img.Save(chartFileName, ImageFormat.Png);
For more details please see this comment in the issue.
Another solution is to try to use Excel.ChartObject. I think this question Exporting Excel Charts as Images may help you.

Excel Interop Picture not displaying

hopefully you guys can help me here. I have this excel interop picture code that seems to be only working on my end. The picture is in a folder in the mapped network drive. When I run the code and receive the excel file, the picture is on the file.
Microsoft.Office.Interop.Excel.Range picRange = xlWorkSheet.get_Range("A1:G1");
picRange.Merge(Type.Missing);
Microsoft.Office.Interop.Excel.Pictures p = xlWorkSheet.Pictures(misValue) as Microsoft.Office.Interop.Excel.Pictures;
Microsoft.Office.Interop.Excel.Picture pic = null;
pic = p.Insert(Server.MapPath("~/images/letter.gif"), misValue);
pic.Left = 87;
pic.Top = Convert.ToDouble(picRange.Top);
pic.Height = 80.25;
pic.Width = 320;
pic.Placement = Microsoft.Office.Interop.Excel.XlPlacement.xlFreeFloating;
However, if I run the code on a different computer, which also has access to that mapped network drive, it the excel file comes with an error on the image that says:
the linked image cannot be displayed. The file may have been moved
renamed or deleted
I've checked three times and made sure that the image file is the right name and the right place. But it only seems to work locally on my computer.
Is there a function in the excel interop library where I can create an instance of the image instead of linking to the image file? Any help will do.

EPPlus Excel error when using AddPicture

I been trying to find the solution for this for so many hours i'm really tired, i hope someone can indicate me with i'm missing. I will try to be as clear as posible with all the possible information so there is no confusion.
I'm using EPPlus 3.1.3.0, Visual Studio 2010, C#, MVC.NET Framework 4.0 and MS Excel 2007
I'm just trying to do a simple thing: download an Excel file with a picture in it. Nothing else.
I have an action that opens an excel file, fills it with data and adds a picture which code looks like this:
public ActionResult FillExcelFile(string imagePath)
{
FileInfo template = new FileInfo([path_of_excel_file]);
ExcelPackage xls = new ExcelPackage(template);
ExcelWorksheet worksheet = xls.Workbook.Worksheets["Sheet1"];
worksheet.Cells[1, 1].Value = "data1";
worksheet.Cells[1, 2].Value = "data2";
worksheet.Cells[1, 3].Value = "data3";
/* ToDo: add picture */
return File(xls.GetAsByteArray(), "application/vnd.ms-excel", "excel.xlsx"));
}
At this moment everything works great! The file have the information and i can download and open it with no problem at all.
Now i will add the picture i want, i will change the ToDo part with the next code:
Image img = Image.FromFile(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
Run it, download it, open it aaand... error:
Excel found unreadable content in "excel.xlsx". Do you want to recover... blah blah blah
Of course i want to recover.
Files open aaand... is empty and an error appear:
Replaced Part: /xl/worksheets/sheet1.xml part with XML error. Load error. Line...
From this moment till now i been adding different code:
Image img = Image.FromFile(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
pic.SetSize(100, 100);
And...
Bitmap img = new Bitmap(Image.FromFile(imagePath));
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
And...
FileInfo img = new FileInfo(imagePath);
ExcelPicture pic = worksheet.Drawings.AddPicture("img", img);
pic.SetPosition(1, 1);
With the last one there as exception:
: System.ArgumentException: Part URI is not valid per rules defined in the Open Packaging Conventions specification
And many many many more like open the image with a stream, adding the setSize because someone said some kind of problem if you don't define it, define my own URI, save the file in the server then download it, etc.
I really appreciate any help that you can give me, really. I don't known what else to check. If you require more information be free to ask.
i found the problem... or kind of. Thanks to #Chris to guide me in this one and to #Ernie for the sugestion.
The problem is the template file that i was trying to fill has something inside that doesn't work fine when i try to add an image. #Chris says "you already have a drawing part in the template and EPPlus is creating some sort of conflict". I don't know what could that be.
So i create a new template from scratch (the template i was using was done by someone else) and everything worked like charm.
Steps that i performed:
I created a new file with using EPPlus and download it and it worked.
I created a new empty template and add the image with EPPlus and it worked.
I created a new template with all the stuff i needed in it and it worked.
I hope this help someone else if they have a similar problem.
I had the same problem. With prueba prueba's answer I analysed my original template and found this: If the table formatting feature (see screenshot) is used then AddPicture causes the XML errors. My solution was to remove the table formatting.
I've had the same issue and noticed that when you add a background-picture before adding the picture the file gets corrupted. If you add the background picture afterwards it works fine.
osheet.BackgroundImage.Image = My.Resources.anyimage
I found the same problem. I'm using the version 4.1.0.0.
I try to use this code:
Bitmap arquivoLogotipo = new Bitmap(#"C:\xxxxxx.jpg");
ExcelPicture logotipoExcel = principal.Drawings.AddPicture("logotipo", arquivoLogotipo);
logotipoExcel.SetPosition(50, 250);
I try this too:
FileInfo logotipoEndereco = new FileInfo("C\okokoko.jpg");
var logotipo = principal.Drawings.AddPicture("logotipo", logotipoEndereco);
logotipo.SetPosition(50, 250);
In my case, I just have a blank sheet. My cod just insert a name of a project and one image.I really don't know what is happening.
Thanks :D!

C# Toolbar Image Collection Editor

I have an application with a tool bar and an Image Collection. The problem is that I do not have the original images and I need to create another tool bar with some of the same buttons. Is there a way to save the Images Collection from the tool bar to a file?
I tried extracting the images from a resource file but I do not know which one has the images stored in.
Although I did not find an answer for my question, I managed to get the images by reading the tool bar image list and saving each one to a file according to the given image key.
for (int x = 0; x < this.imageListToolbar3small.Images.Count; ++x)
{
Image temp = this.imageListToolbar.Images[x];
temp.Save(this.imageListToolbar.Images.Keys[x] + ".png");
}
This came from an answer to this question: How to Export Images from an Image List in VS2005?
I just added the code after the InitializeComponent call and saved all images in debug mode. I did not needed to run the full application.
If anyone does have a better idea or a small application to retrieve images from a tool bar using only the resource file, that would be appreciated. I will not mark as an answer since it is more a workaround.
I use this approach:
foreach (ToolBarButton b in toolBar.Buttons)
{
//can be negative, for separators, because separators don't have images
if (b.ImageIndex >= 0)
{
Image i = toolBar.ImageList.Images[b.ImageIndex];
i.Save(b.ImageIndex + ".png");
}
}
I needed to recover images from a private ImageList member of a Control. I used the following code (Sorry, it's VB but s/b easy to refactor)
Dim cntrl = New TheClassWithThePrivateImageList
Dim pi As Reflection.PropertyInfo, iml As System.Windows.Forms.ImageList, propName = "ThePropertyName"
pi = cntrl.GetType.GetProperty(propName, Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
iml = CType(pi.GetValue(cntrl), System.Windows.Forms.ImageList)
For Each key In iml.Images.Keys
Dim image As Drawing.Image = iml.Images.Item(key)
image.Save($"{propName}_{key}")
Next

Categories