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.
Related
I open an Excel file in c#, make some changes and I want to save it as pdf file.
I have searched about it and find this:
Microsoft.Office.Interop.Excel._Workbook oWB;
oWB.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, "D:\\xxxxx.pdf");
but this code sometimes opens a form and a printer must be selected! I don't know why?!
Is there any other way for exporting PDF from Excel?
I saw that Workbook.saveas() has a Fileformat object. How can we use it?
Check out Spire.Xls, below is the code for converting Excel to PDF.
Workbook workbook = new Workbook();
workbook.LoadFromFile("Sample.xlsx");
//If you want to make the excel content fit to pdf page
//workbook.ConverterSetting.SheetFitToPage = true;
workbook.SaveToFile("result.pdf", Spire.Xls.FileFormat.PDF);
It has a free version which you can use without charge:
https://www.e-iceblue.com/Introduce/free-xls-component.html (Also available on NuGet)
Use iTextSharp. It is native .NET code. Doesn't require any Excel interop -
https://www.nuget.org/packages/itextsharp/
If you're looking for an alternative approach, then check out GemBox.Spreadsheet:
https://www.nuget.org/packages/GemBox.Spreadsheet/
Here is how you can save Excel to PDF with it:
ExcelFile excel = ExcelFile.Load("D:\\xxxxx.xlsx");
excel.Save("D:\\xxxxx.pdf");
Or you can write it as following:
XlsxLoadOptions loadOptions = new XlsxLoadOptions();
ExcelFile excel = ExcelFile.Load("D:\\xxxxx.xlsx", loadOptions);
PdfSaveOptions saveOptions = new PdfSaveOptions();
excel.Save("D:\\xxxxx.pdf", saveOptions);
You can do this using this API. Please see documentation for further detail.
http://cdn.bytescout.com/help/BytescoutPDFExtractorSDK/html/55590148-5bef-4338-ac16-1de4056a952b.htm
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!
Using C# to write a method that takes a single worksheet out of a workbook and saves it as HTML.
I am using the Worksheet.SaveAs method as described on MSDN.
However, when I look at the output it has gone and saved all of the worksheets within the workbook, not just the one I selected. It's as though Worksheet.SaveAs and Workbook.SaveAs just do the same thing.
Simplified code:
public static void saveSingleSheetAsHTML(string workbook, string destination, string sheetName)
{
Application excel = new Application();
excel.Workbooks.Open(Filename: workbook);
Microsoft.Office.Interop.Excel._Worksheet worksheet = excel.Worksheets[sheetName];
var format = Microsoft.Office.Interop.Excel.XlFileFormat.xlHtml;
worksheet.SaveAs(destination, format);
}
Now when I open the resulting HTML file it has only gone and exported the entire workbook, not the sheet.
As said by Tim Williams in a comment I found after hitting a link posted by I love my monkey above:
"You cannot call SaveAs on a worksheet - first call .Copy to create a
standalone new workbook containing only that sheet, then save that
workbook."
No idea why you cannot. The docs on MSDN do not give any clue about this and suggest it should be possible.
So having created a new workbook:
var newbook = excel.Workbooks.Add(1);
Copy the sheet over, which will place it as the first sheet:
excelWorksheet.Copy(newbook.Sheets[1]);
Then delete the default "Sheet1", which will always be the 2nd sheet:
newbook.Worksheets[2].Delete();
Then call the SaveAs method and then close the new book:
newbook.SaveAs(Filename: destination, FileFormat: format);
newbook.Close();
This did save the new workbook as HTML, but also put the tabs at the bottom, which I was hoping to avoid as there is only 1 tab now. It does meet my minimum needs, though I would like to figure out how to make it a bit neater.
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;
How to create and download excel document using asp.net ?
The purpose is to use xml, linq or whatever to send an excel document to a customer via a browser.
Edit : Use case
The customer load a gridview ( made with ajax framework ) in a browser, the gridview is directly linked to an sql database.
I put a button 'export to excel' to let customer save this gridview data on his computer ansd i would like to launch a clean download of an excel.
The solutions proposed here are not clean, like send an html document and change the header to excel document etc, i'm searching a simple solution on codeplex right now, i will let you know.
Starter kit
First i have downloaded the Open XML Format SDK 2.0.
It comes with 3 useful tools in :
C:\Program Files\Open XML Format SDK\V2.0\tools
DocumentReflector.exe wich auto
generate the c# to build a
spreadsheet from the code.
OpenXmlClassesExplorer.exe display
Ecma specification and the class
documentation (using an MSDN style
format).
OpenXmlDiff.exe graphically compare
two Open XML files and search for
errors.
I suggest anyone who begin to rename .xlsx to .zip, so you can see the XML files who drive our spreadsheet ( for the example our sheets are in "xl\worksheets" ).
The code
Disclaimer : I have stolen all the code from an MSDN technical article ;D
The following code use an *.xlsx template i made manually to be able to modify it.
Namespaces references
using System.IO;
using System.Xml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
// Database object
DataClassesDataContext db = new DataClassesDataContext();
// Make a copy of the template file.
File.Copy(#"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\livreurs.xlsx", #"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\generated.xlsx", true);
// Open the copied template workbook.
using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(#"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\generated.xlsx", true))
{
// Access the main Workbook part, which contains all references.
WorkbookPart workbookPart = myWorkbook.WorkbookPart;
// Get the first worksheet.
WorksheetPart worksheetPart = workbookPart.WorksheetParts.ElementAt(2);
// The SheetData object will contain all the data.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// Begining Row pointer
int index = 2;
// Database results
var query = from t in db.Clients select t;
// For each item in the database, add a Row to SheetData.
foreach (var item in query)
{
// Cell related variable
string Nom = item.Nom;
// New Row
Row row = new Row();
row.RowIndex = (UInt32)index;
// New Cell
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
// Column A1, 2, 3 ... and so on
cell.CellReference = "A"+index;
// Create Text object
Text t = new Text();
t.Text = Nom;
// Append Text to InlineString object
InlineString inlineString = new InlineString();
inlineString.AppendChild(t);
// Append InlineString to Cell
cell.AppendChild(inlineString);
// Append Cell to Row
row.AppendChild(cell);
// Append Row to SheetData
sheetData.AppendChild(row);
// increase row pointer
index++;
}
// save
worksheetPart.Worksheet.Save();
}
I havent finished yet, my second job is to auto download the spreadsheet after modification.
Finally, i redirect the user to my generated spredsheet (from my aspx)
context.Response.Redirect("Oxml-tpl/generated.xlsx");
just set Response.ContentType = "application/vnd.ms-excel" and your page will rendered as an excel sheet on the clients browser
Sample code here
There are quite a few ways of handling this, depending on how extensive the Excel functionality is. Binoj's answer works if the Excel is just a spreadsheet and has no direct Excel functionality built in. The client can add functionality, concats, etc. These are "dumb" excel docs until the client does soemthing.
To create a more full featured Excel doc, you havve two basic choices that I can think of offhand.
Use either the office components (re: bad) to create an excel document, or a third party component, like SoftArtisan's ExcelWriter. Great component, but there is a cost.
Use a control on the page that allows export to Excel. Most vendors of ASSP.NET controls have this functionality on their grids.
Option #1 allows you pretty much all functionality of Excel. Option #2 is a bit more limited, at least in the controls I have tried.
Good article on how top export to excel from Erika Ehrli
http://blogs.msdn.com/erikaehrli/archive/2009/01/30/how-to-export-data-to-excel-from-an-asp-net-application-avoid-the-file-format-differ-prompt.aspx