NPOI writing to XLS but not XLSX - c#

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.

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.

how can we convert word to .pdf format and excel to .pdf format from c#

How can we convert the excel file and word file to .pdf format from c#. i tried the following code but it shows the an error
this is my code:
Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
wordDocument = appWord.Documents.Open(#"C:\Users\ITPro2\Documents\test.docx");
wordDocument.ExportAsFixedFormat(#"D:\desktop\DocTo.pdf", Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
and i got the following Error
The export failed because this feature is not installed. during export to pdf from word from c#
While not directly related the documentation under
https://msdn.microsoft.com/en-us/library/office/ff198122.aspx
gives a note, that if the pdf add-in is not installed, exactly this error will occur. So check your prerequisites, i.e. Office installed and the add-in, too.
1) Excel 2013 Primary Interop Assembly Class Library and it works perfectly fine under .NET 4.5.1 Just add Microsoft.Office.Interop.Excel assembly to your references and you are ready to go.
using System;
using Microsoft.Office.Interop.Excel;
namespace officeInterop
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open("d:\\x.xlsx");
wkb.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, "d:\\x.pdf");
}
}
}
OR
2) refer this link to convert DOC or DOCx file into PDF
http://www.rasteredge.com/how-to/csharp-imaging/pdf-convert-word-to-pdf/
Since my other comment got deleted, here is the updated version.
For converting my files to pdf in c# i used the metamorphosis libary, this could also be a solution for you.
Below is a code example from me where i used a blobstorage to download PDF files from regular files.
var converter = new SautinSoft.PdfMetamorphosis();
var ms = new MemoryStream();
await blob.DownloadToStreamAsync(ms);
ms.Seek(0, SeekOrigin.Begin);
var pdfStream = converter.DocxToPdfConvertStream(ms);
if (pdfStream != null)
{
await _storageProvider.SaveFileAsync(containerName, fileName, pdfStream);
}
ms.Close();
var result = await _storageProvider.GetFileWithAttributesAsync(containerName, fileName);
return new ServiceResponse<CloudBlockBlob>(result);
Below i posted some links with the sample code from the library itself:
Word to PDF example
Excel to PDF example

Exporting Repeater Data to Excel in C# .net

I have to Provide the functionality to export all the data shown in repeater to excel file. I have successfully done that but the file size goes above 4MBs.
Here is the code I am using.
public void ExportToExcel(Repeater name)
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=RepeaterExport.csv");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
Repeater rp = name;
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
foreach (RepeaterItem item in name.Items)
{
item.Controls.Remove(item.FindControl("hd_Depot"));
item.Controls.Remove(item.FindControl("hd_ProdCode"));
item.Controls.Remove(item.FindControl("hd_Closing"));
item.Controls.Remove(item.FindControl("hd_groupName"));
}
rp.RenderControl(hw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
Now when I use xls or xlsx it downloads perfectly but with large size but if I use csv it writes the whole html code to excel file. my main motive here is to shrink the size of the excel file to less than 1MB. Please advise.
It looks like you write an HTML or CSV file and pretends it is an Excel sheet in the Content-Type so that it opens with Excel. A better solution is to create a real Excel sheet, i.e. with an xlsx extension, using some library that can do this for you.
I think the xlsx contains the entire html, and that's why it's so big.
If you just want to export to csv:
create a string which contains the data (in your for loop)
Contenttype is: "text/csv"
I use a kbCSV and the CSVWriter.

EPPlus - saved file corrupted when using template

I'm evaluating EPPlus as a replacement for GemBox, but can't even save a valid Excel file. I have this minimal C# code:
In library:
public Stream GenerateReport(string templateFilePath)
{
using (var xls = new OfficeOpenXml.ExcelPackage(new FileInfo(templateFilePath), true))
{
var stream = new MemoryStream();
xls.SaveAs(stream);
stream.Position = 0;
return stream;
}
}
In controller:
return File(GenerateReport("filename.xltx"), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "filename.xlsx");
The file is created and saved succesfully but when I open it with Excel I get the error:
"We found a problem with some content in 'filename.xlsx'. Do you want
to try to recover as much as we can?".
I answer Yes and get:
"The workbook cannot be opened or repaired by Microsoft Excel because
it is corrupt".
I have verified that the template file is in the correct format and none of the other suggested solutions here on stackoverflow fixes the problem.
Any suggestions?
UPDATE:
I also tried without using a template and that works without problem:
using (var xls = new OfficeOpenXml.ExcelPackage())
{
xls.Workbook.Worksheets.Add("New");
var stream = new MemoryStream();
xls.SaveAs(stream);
stream.Position = 0;
return stream;
}
UPDATE 2:
Saving the .xltx template as a .xlsx and using the .xlsx as the template does not raise any errors when opened.
I answered a similar question here:
.xlsx Created and Saved Using Template with EPPlus is Unreadable/Corrupt
Short answer: EPPlus does not actually support xltx template files, the 'template' parameter just expects an appropriately pre-formatted xlsx file.
I've recently found similar bug (Excel complained about some invalid xl/styles.xml section). After searching I came into solution: change version to 3.1.3 (3.1.2 has a bug). It seems 3.1.1 is ok too.

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

Categories