Open workbook in Interop.Excel from byte array - c#

I want to open Excel from byte[] because my file is encrypted and I want to open after decrypt but without write in a file.
The office has "restricted access" and I want to open my file with this protection but without saving the decrypted content in a file.
myApp.Workbooks.Open only supports a path.
Is it possible?

As an alternative to OpenXml there's also ExcelDataReader which from my experience is a lot faster in processing data compared to Interop.Excel(around 3 times+).
It can also open encrypted Excel files directly(stackoverflow)
The github page for ExcelDataReader has some great examples on how to use it. The only thing you'd have to do is:
This:
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
Becomes this:
using (var stream = new MemoryStream(yourByte[])
And if you just want to open the password protected excel file you'd do this:
var conf = new ExcelReaderConfiguration { Password = "yourPassword" }; //Add this
excelReader = ExcelReaderFactory.CreateReader(stream, conf); //change the excel Reader to this
Make sure to check the Github page for more info!

It is not possible because the interop is actually an interface for programs to run and operate existing excel on the computer.
I think you need to use openxml created by Microsoft to work with excel word and PowerPoint.
DocumentFormat.OpenXml
Then you can use:
ExcelPackage excelPackage = new ExcelPackage(stream)
or
var pck = new OfficeOpenXml.ExcelPackage();
pck.Load(File.OpenRead(path));
pck.Load(Stream) can use any stream as input not only from a file.
It depends on your needs.

Related

Password Protected Excel Download using EPPLUS

I am exporting data in Excel form using EPPLUS Excel Library. I want that when excel downloaded it will ask for password. I have tried following code.
FileInfo newFile = new FileInfo("sample.xlsx");
using (ExcelPackage package = new ExcelPackage(newFile)
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add("demo");
ws.Cells[A1].LoadFromDataTable(dataTable, false);
package.Workbook.Protection.SetPassword("EPPLUS");
package.Save();
}
Just need to use the .Save overload with a password as the option:
package.Save("password");
Response To Comments
To apply a password if saving via a byte array it is very similar:
Byte[] bin = pck.GetAsByteArray("password");
System.IO.File.WriteAllBytes(fullFilePath, bin);
It's not documented, but you can do as following:
package.Encryption.Password = "your password here";
Then serve your package with Save() or GetAsByteArray() of your choice
If you are saving the excel package into a MemoryStream (for sending as an email attachment) you have to do this:
excelPackage.SaveAs(memoryStream, "pa$$w0rd");
package.GetAsByteArray("sometest"); ---> this will protect your excel sheet with password sometest :)

Editing Excel Template with NPOI C#

I have an Excel Template which i want to write into with data from a database. Whenever I edit and Save the file in c#, when I open the template, Microsoft Office Excel says the file is corrupt. Apparently, I think I'm going about editing it wrongly. this is how i went about it below. I am using NPOI 2.0 beta 2. if it matters, the template contains macros and formulas
FIleStream fs = new FileStream(pathString, FIleMode.Open, FileAccess.Read);
IWorkbook wkb = WorkbookFactory.Create(fs);
ISheet sheet = wkb.GetSheet("sheet1");
ICell cell = sheet.GetRow(row).GetCell(column);
if(cell != null)
{
cell.SetCellValue(value);
}
FileStream fs1 = new FileStream(pathString, FileMode.OpenOrCreate);
wkb.Write(fs1);
fs.CLose();
fs1.Close();
But If I try to read the corrupted excel file, i can still retrieve values from the sheet using NPOI. Any pointers as to my errors. Thanks in anticipoation

Write an Excel file with C# [duplicate]

Is there any easy to implement library that can be used to read excel files and may be create them later on?
is this my best bet?
http://support.microsoft.com/kb/302084
Try this: http://epplus.codeplex.com
EPPlus is a .net library that reads and writes Excel 2007/2010 files
using the Open Office Xml format (xlsx).
If you are willing to commit yourself to a later version of Excel (2007+) you can also take a look at the OpenXML SDK. It's free, doesn't tie you to having MS Office installed on the machine it will be running on and there are quite a few resources available on how to use it online (including blogs from the OpenXML team).
There is excel package plus:
http://epplus.codeplex.com/
Only works on xlsx though, but Office 2003 is cycling out anyway.
You can use ExcelLibrary ,Although it works for .xls only which is 2003 format
The aim of this project is provide a native .NET solution to create, read and modify Excel files without using COM interop or OLEDB connection.
I had a chance of using EPPLUS ,it was wonderful :) ,It works for new excel format .xlsx which is used in 2007/2010
EPPlus is a .net library , you can read and write to excel files ,create charts ,pictures ,shapes... and Much more
Also take a look at this SO post
I've used oledb, interop and just started using Epplus. So far epplus is proving to be simplest.
http://epplus.codeplex.com/
However, I just posted a problem I have with epplus, but I posted some code you could use as reference.
c# epplus error Removed Part: Drawing shape
I like to use ExcelDataReader for reading and the aforementioned EPPlus for writing. Here's an example.
Here's an example of reading with it:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
// Reading from a binary Excel file ('97-2003 format; *.xls)
// IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
// Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
// Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
var cdm = new ValueSetRepository();
for (int i = 0; i < result.Tables.Count; i++)
{
// CHECK if tableNames filtering is specified
if (tableNames != null)
{
// CHECK if a table matches the specified tablenames
var tablename = result.Tables[i].TableName;
if (!tableNames.Contains(tablename))
{
continue;
}
}
var lookup = new ValueSetLookup();
lookup.CmsId = result.Tables[i].Rows[2][0].ToString();
lookup.NqfNumber = result.Tables[i].Rows[2][1].ToString();
lookup.Data = new List<ValueSetAttribute>();
int row_no = 2;
while (row_no < result.Tables[i].Rows.Count) // i is the index of table
// (sheet name) which you want to convert to csv
{
var currRow = result.Tables[i].Rows[row_no];
var valueSetAttribute = new ValueSetAttribute()
{
Id = currRow[0].ToString(),
Number = currRow[1].ToString(),
tName = currRow[2].ToString(),
Code = currRow[7].ToString(),
Description = currRow[8].ToString(),
};
lookup.Data.Add(valueSetAttribute);
row_no++;
}
cdm.AddRecord(lookup);
A company I used to work for did a lot of research on this and decided a product by SoftArtisans was their best bet:
OfficeWriter
I always found it strange how weak the support for Excel reading and writing was. I'm pretty sure that if you use Microsoft's libraries you have to have Excel installed anyway which is an extra expense just like OfficeWriter.
You could either go for VBA or use the free library from FileHelpers. If you are planning to buy some commerical solutions, I would recommend ASPOSE
According to this website you need to include a reference to the Microsoft Excel 12.0 Object library. From there, you need to do a few things to open up the file. There's a code sample on the website.
PS - Sorry it's not too detailed but I couldn't find the Microsoft Office developer reference with more details.
I used ExcelLibrary with very great results! (until now it support Excel 2003 or lower versions).
http://code.google.com/p/excellibrary/
Yes, multiple open-source libraries exist to help read and/or write Excel spreadsheets using C#.
Here is a shortlist of C# libraries:
Microsoft.Office.Interop.Excel
ExcelDataReader
NPOI
ExcelMapper - NPOI extension
EPPlus
An up-to-date curated list is maintained here.
Example: Reading Excel File using ExcelMapper
a. Install using NuGet, by running below command in NuGet Packet Manager:
Install-Package ExcelMapper
b. Sample C# Code for ExcelMapper
public void ReadExcelUsingExcelMapperExtension()
{
string filePath = #"C:\Temp\ListOfPeople.xlsx";
var people = new ExcelMapper(filePath).Fetch<Person>().ToList();
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Disclaimer: I like the conciseness of ExcelMapper, therefore included sample code for this package. To do the same using other libraries, requires a lot more code.

Add multiple crystal reports pdfs to zip file

I'm trying to export the pdf files from Crystal to streams, then I want to add them (7 total) to a zip file using the DotNetZip Library. I'm just trying to add one below. I have a feeling I'm way off. Please help.
MemoryStream oStream;
CrystalDecisions.CrystalReports.Engine.ReportDocument rpt = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
if (a2batch.Count > 0) // a2batch - My Crystal Datasource List
{
rpt.Load(Server.MapPath("~\\Report\\Construction\\ScheduleA2.rpt"));
rpt.SetDataSource(a2batch);
oStream = (MemoryStream)rpt.ExportToStream(ExportFormatType.PortableDocFormat);
using (ZipFile zipFile = new ZipFile())
{
zipFile.AddEntry("Report.pdf", oStream);
zipFile.Save("Report.zip");
}
}
Does the code in your question work? If so, the easiest is probably to just open the zip file when you add the other streams:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
Then use the same code as in you question to add the new file, and then save it with:
zip.Save();
You can add and remove files to an existing zip archive at will. If you are creating all the streams in the same method, it is also possible to just add data from several streams before you close the file, that is adding several zip.AddEntry statements after each other.

Excel 2007 file writer in C# results in a corrupt file

I am using a BinaryReader to read an Excel 2007 file from an Exchange mailbox using a OWA, the file is then written to disk using a BinaryWriter. My problem is that the two files don't match when the writer finishes. Worse still Excel 2007 won't open the writen file.
Previously Excel 2003 has had no problem with the solution below. And Excel 2007 doesn't have an issue if the file is an Excel 2003 format file, only if the file format is Excel 2007 (*.xlsx).
BinaryReader:
using(System.IO.Stream stream = resource.GetInputStream(attachedFiles[k].Address))
{
using(System.IO.BinaryReader br = new System.IO.BinaryReader(stream))
{
attachment.Data = new byte[attachedFiles[k].Size];
int bufPosn=0, len=0;
while ((len = br.Read( attachment.Data, bufPosn, attachment.Data.Length-bufPosn )) > 0)
{
bufPosn += len;
}
br.Close();
}
}
BinaryWriter:
FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter binWriter = new BinaryWriter(fs);
binWriter.Write( content, 0, content.Length );
binWriter.Close();
fs.Close();
Suggestions gratfully received.
This issue was caused by the value being returned by attachedFiles[k].Size which was far inexcess of the actual file size. Excel 2003 files it seems are unaffected by this, but Excel 2007 files are vulnerable due to their compressed nature (the decompression routine obviously sees the file differently).
Once I corrected the size of the buffer the files are fine.
Thanks for the suggestions
There is an issue with IE8 and OWA but I am not sure if it applies in your case.
Checkout this site which also has a link to this site. They basically explain how to get around the problem of download xmlx and docx files with an OWA.

Categories