EPPlus with OpenXML and streams - c#

I am trying to automate a Powerpoint presentation. I am using OpenXML to navigate the powerpoint presentation up to the point that I find the Excel linked to a chart. Now I want to use EPPlus to load a datatable into one of the worksheets (because EPPlus has a simple LoadFromDataTable function whereas I think I would have to write lots of code to use OpenXML).
So my problem is this.
I have a PresentationDocument in memory. And I have navigated to the particular chart that I want to manipulate via:
doc.PresentationPart.SlideParts.ElementAt(0).ChartParts.ElementAt(0)
I get the Excel part using:
var stream = chartpart.EmbeddedPackagePart.GetStream()
Then I tried:
using(var pck = new ExcelPackage(stream)) {
`do stuff;
`pck.Save();
}
and then at the end I do a doc.PresentationPart.Presentation.Save but this hasn't changed the Presentation. I can change it using OpenXML instead with:
using (var xl = Spreadsheet.Document.Open(stream, true))
{
`do stuff;
`xl.Close();
}
With everything else the same. So I guess either xl.Close() is doing stuff that pck.Save() isn't or I am using the stream incorrectly - can anyone advise?

Related

OpenXml. How to add creator using C# in docx?

I am trying to add some core properties to the Docx document. I have found only one example in different places of how it can be done.
For instance here. But there is a problem.
If we look at the structure of the Docx itself created by Word application and using OpenXml, there is a difference between them.
Structure of the docx created using openxml and document.PackageProperties.Creator = "vso"
Moreover, validation of the file can't be succeeded if I want to check the file by productivity tool from Microsoft. Of course, the word can read this file, but it is not a proper way to generate a word file from my point of view.
Here you can see the structure of the docx created by the word application itself
One more aspect, if I write following:
CoreFilePropertiesPart corePackageProperties = document.CoreFilePropertiesPart;
if (corePackageProperties == null)
{
corePackageProperties = document.AddCoreFilePropertiesPart();
}
then core.xml file is created in the proper place of structure, but it is empty.
So, the question is does OpenXML SDK have the way to get the structure of the docx the same as using the word application itself?
Microsoft documentation suggests :
using (XmlTextWriter writer = new XmlTextWriter(coreFilePropPart.GetStream(FileMode.Create), System.Text.Encoding.UTF8))
{
writer.WriteRaw("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<cp:coreProperties xmlns:cp=\"https://schemas.openxmlformats.org/package/2006/metadata/core-properties\"></cp:coreProperties>");
writer.Flush();
}
I had the same issue when creating an Excel file and this sort it out.

Programatically Create Excel Sheets from different templates using a Addin

I am developing an Excel Addin that is able to fetch data from our database.Instead of dumping the data directly , I would like to have the data presented in a nice format. I have got our local VBA expert to develop a templates for the same since there can be multiple sheets all of which can have different formats.
It is while adding the worksheet that I am stuck at.
string TemplateFileLocation = Path.GetFullPath(fileName);
if(File.Exists(fileName))
{
Worksheet newWorkSheet = (WorkSheet)Globals.ThisAddin.Aplication.Worksheets.Add(Missing.Value,Missing.Value,1,TemplateFileLocation);
}
The code crashes while it hits this location.
The Error code returned is : 0x800A03EC
I have verified that the path to the template file is correct.
Each of these templates have only one work sheet.
You can use EPPlus
using System.IO;
using System.Reflection;
using OfficeOpenXml;
//Create a stream of .xlsx file contained within my project using reflection
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("EPPlusTest.templates.VendorTemplate.xlsx");
//EPPlusTest = Namespace/Project
//templates = folder
//VendorTemplate.xlsx = file
//ExcelPackage has a constructor that only requires a stream.
ExcelPackage pck = new OfficeOpenXml.ExcelPackage(stream);

Read Data from Excel Worksheet in c#?

I need some way to read worksheets from an Excel file, then select what it's important, and put all the Data in a Database.
It's a job for one time only. It's an old excel file with information, that have to be passed to a Database, and which will work with an application that i have developed.
I saw many examples but i am not understanding well how it works, and which way is the best to do this type of work.
My idea is to develop some application in c# that to this process.
LINQ may work and would be preferable for a relatively simple table.
A traditional approach would be to use COM Interop. Here's a Microsoft page about to work with Excel using COM interop (it is for spreadsheet creation, but the principles are the same - just use different API methods to open and read data):
http://msdn.microsoft.com/en-us/library/ms173186(v=vs.80).aspx
I strongly suggest using a linq provider to connect to excel. This should make it very easy to query for the information you are looking for. Once you have it, inserting into the database should be easy.
http://code.google.com/p/linqtoexcel/
I've used this before and it works well.
http://exceldatareader.codeplex.com/
had an example handy...
using (FileStream fileStream = File.Open(inputFilenames[0], FileMode.Open, FileAccess.Read))
{
IExcelDataReader excelReader;
if (Path.GetExtension(inputFilenames[0]) == ".xls")
excelReader = Factory.CreateReader(fileStream, ExcelFileType.Binary);
else
excelReader = Factory.CreateReader(fileStream, ExcelFileType.OpenXml);
excelReader.NextResult();
while (excelReader.Name != this.Worksheet)
excelReader.NextResult();
while (excelReader.Read())
{
if (FirstRowHasColumnNames)
{
FirstRowHasColumnNames = false;
}
else
{
//do stuff
var test = GetColumnData(excelReader, 1);
}
}
this.Save(outputFilename);
}
Read Data from Excel Worksheet in c#? I got the Exact solution here visit
http://microsoftdotnetsolutions.blogspot.in/2012/12/get-excel-sheet-data.html

C# Read Excel using late binding

Hi
I have not used late binding before but it would seem to be the solution, if only I could find a concise example!
Or may be it's not the solution but I'm sure you guys will know!
I need to fill a dropdown combbox list from a column in excel reading down to the first blank cell. the solution needs to work with excel 2003 and above some PCs never have had 2003 install only office 2010 other have been upgraded from 2003 and some are still on 2003!
I need a solution that works on all of the above.
So I'm looking into late binding is this the correct way to go? would Linq help!?
Its a clasic windows Form app using .Net 4.
I thought I would write a method that takes the file name and path and returns a list which I would then assign to the combobox.
But being new I'm not getting pass go!
Any help/examples PLEASE
It sounds like you're looking at using COM interop/automation with the Excel application installed on client machines.
If your sole requirement is to extract data from an Excel file, you'll be better off using a library that can simply read data out of the file itself, rather than launching the Excel process in the background.
It is faster, cleaner, and more testable.
I've used NPOI for .xls files (and there are certainly others), and there are LOTS of options for .xlsx files. This SO question is about creating a file, but any of the suggested libraries can of course read files as well.
The only time I'd use COM automation is to interact with a running instance of Excel.
Edit (in response to comments)
Here is a sample of getting the values of column B as strings:
using System;
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var stream = new FileStream(#"c:\my_workbook.xls", FileMode.Open);
var workbook = new HSSFWorkbook(stream);
stream.Close();
var sheet = workbook.GetSheet("My Sheet Name");
var row_enumerator = sheet.GetRowEnumerator();
while (row_enumerator.MoveNext())
{
var row = (Row)row_enumerator.Current;
var cell = row.GetCell(1); // in Excel, indexes are 1-based; in NPOI the indexes are 0-based
Console.WriteLine(cell.StringCellValue);
}
Console.ReadKey();
}
}
}

Read excel file from a stream

I need a way to read a Excel file from a stream. It doesn't seem to work with the ADO.NET way of doing things.
The scenario is that a user uploads a file through a FileUpload and i need to read some values from the file and import to a database.
For several reasons I can't save the file to disk, and there is no reason to do so either.
So, anyone know of a way to read a Excel file from a FileUpload stream?
It seems i found a soultion to the problem myself.
http://www.codeplex.com/ExcelDataReader
This library seems to work nicely and it takes a stream to read the excel file.
ExcelDataReader reader = new ExcelDataReader(ExcelFileUpload.PostedFile.InputStream);
This can be done easily with EPPlus.
//the excel sheet as byte array (as example from a FileUpload Control)
byte[] bin = FileUpload1.FileBytes;
//gen the byte array into the memorystream
using (MemoryStream ms = new MemoryStream(bin))
using (ExcelPackage package = new ExcelPackage(ms))
{
//get the first sheet from the excel file
ExcelWorksheet sheet = package.Workbook.Worksheets[1];
//loop all rows in the sheet
for (int i = sheet.Dimension.Start.Row; i <= sheet.Dimension.End.Row; i++)
{
//loop all columns in a row
for (int j = sheet.Dimension.Start.Column; j <= sheet.Dimension.End.Column; j++)
{
//do something with the current cell value
string currentCellValue = sheet.Cells[i, j].Value.ToString();
}
}
}
SpreadsheetGear can do it:
SpreadsheetGear.IWorkbook workbook = SpreadsheetGear.Factory.GetWorkbookSet().Workbooks.OpenFromStream(stream);
You can try it for yourself with the free evaluation.
Disclaimer: I own SpreadsheetGear LLC
Infragistics has an excel component that can read an excel file from a stream.
I'm using it in a project here and it works well.
Also the open source myXls component could easily be modified to support this. The XlsDocument contstructor only supports loading from a file given by a file name, but it works by creating a FileStream and then reading the Stream, so changing it to support loading from streams should be trivial.
Edit:
I see that you found a solution but I just wanted to note that I updated the source code for the component so that it now can read an excel file directly from a stream. :-)
I use ClosedXML nuget package to read excel content from stream. It has a constructor overload in XLWorkbook class which takes stream pointing to an excel file (aka workbook).
imported namespace at the top of your code file:
using ClosedXML.Excel;
Source code:
var stream = /*obtain the stream from your source*/;
if (stream.Length != 0)
{
//handle the stream here
using (XLWorkbook excelWorkbook = new XLWorkbook(stream))
{
var name = excelWorkbook.Worksheet(1).Name;
//do more things whatever you like as you now have a handle to the entire workbook.
var firstRow = excelWorkbook.Worksheet(1).Row(1);
}
}

Categories

Resources