Editing Excel Template with NPOI C# - 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

Related

Open workbook in Interop.Excel from byte array

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.

C# NPOI exception "Extern sheet is part of LinkTable" while creating object HSSFWorkbook from FileStream

Code below throw exception "Extern sheet is part of LinkTable". Using NPOI 2.3.0 .
HSSFWorkbook xlsFile;
using (var fileRead = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
try
{
xlsFile = new HSSFWorkbook(fileRead);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How i can open this file using NPOI? Because of Microsoft Office could open this file easily and offer to resave it. And after resaving by MS Office - NPOI opens this file (no errors with creating HSSFWorkbook object).
But i need work only with NPOI (open file, repair file if needed, do some work and save). Tried work by POIFS, instead of creating HSSFWorkbook object - this is not working, couse of POIFS already contains errors and can not access it.
File with exception

NPOI writing to XLS but not XLSX

Having a difficult time with this one...
Everything worked 100% with XLS (I'm using NPOI on my ASP.NET app):
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
private MemoryStream ms = new MemoryStream();
private IWorkbook workbook;
private ISheet worksheet;
private byte[] buffer;
using (FileStream file = new FileStream(#"C:\template.xls", FileMode.Open, FileAccess.Read))
{
workbook = new HSSFWorkbook(file);
}
worksheet = workbook.GetSheetAt(0);
worksheet.GetRow(11).GetCell(11).SetCellValue("hello"); // etc etc etc
workbook.Write(ms);
buffer = ms.ToArray();
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Type", "application/vnd.ms-excel");
response.AddHeader("Content-Disposition", String.Format("attachment; filename=template.xls; size={0}", buffer.Length.ToString()));
response.BinaryWrite(buffer);
response.End();
Requirements have changed and the new Excel template uses features from XLSX, so it's now template.xlsx. I've been using NPOI 2.0 all along, and I've seen that it supports XLSX (using XSSF instead of HSSF). I changed the code like this (only showing the differences here - everything else is the same):
using NPOI.XSSF.UserModel;
using (FileStream file = new FileStream(#"C:\template.xlsx", FileMode.Open, FileAccess.Read))
{
workbook = new XSSFWorkbook(file);
}
response.AddHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.AddHeader("Content-Disposition", String.Format("attachment; filename=template.xlsx; size={0}", buffer.Length.ToString()));
The exception gets thrown at the line workbook.Write(ms);:
System.NotImplementedException: The method or operation is not implemented.
at NPOI.XSSF.UserModel.XSSFChartSheet.Write(Stream out1)
at NPOI.XSSF.UserModel.XSSFSheet.Commit()
at NPOI.POIXMLDocumentPart.OnSave(List`1 alreadySaved)
at NPOI.POIXMLDocumentPart.OnSave(List`1 alreadySaved)
at NPOI.POIXMLDocument.Write(Stream stream)
What could I be doing incorrectly?
edit: I've tried NPOI 2.1.1 Beta - same issue
I ran some tests with your sample code and a bunch of different XLSX files. Based on the results, and the exception you got, the issue is not with your code, but with the NPOI library and the XLSX template file you are working with.
Basically, in Excel, you can display a chart in two ways:
Embedded in a worksheet, such that the worksheet can display other information.
All by itself in a separate sheet. This is known as a Chart Sheet.
It seems that your XLSX template contains a chart sheet, and the error occurs while trying to write out the chart sheet (XSSFChartSheet.Write). Currently, NPOI has no support for writing out XLSX chart sheets, it just throws an exception instead.
This leaves you with three options:
Remove all chart sheets from your XLSX file.
Convert all chart sheets in your template to embedded charts. Note that in my testing, NPOI support for embedded charts was a bit iffy. While it did not throw an exception while writing them out, the resultant charts would sometimes have data labels added where there were none, or cause Excel to recover the document by removing the chart itself. Your mileage may vary.
Drop NPOI and use some other library, for e.g., EPPlus which seems to have support for charts in XLSX files, based on this answer.

Reading Embedded Object in Excel File

I have an excel file contains Attachment column, which has another excel object embedded into it.
I need to read that embedded excel file and process its data.
So far i used Excel Reader to read the normal excel file and retrieve as DataSet.
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 result = excelReader.AsDataSet();
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
excelReader.Close();
Now i want to read the embedded object(excel file)
Is there any dll/component/code which will help us to read embedded object inside excel file?
Note: I dont have a Microsoft Office Package installed in server. So i dont want to use Microsoft.Interoperability package

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