NPOI ArgumentOutOfRangeException on WorkbookFactory.Create - c#

I have been using NPOI to read Excel files, and I now need to write out files. I am trying to use the WorkbookFactory, which doesn't show up in a lot of examples online (doesn't appear in the NPOI examples on CodePlex either). Here is the code:
this.FileStream = new FileStream(
this.FilePath,
FileMode.OpenOrCreate,
FileAccess.ReadWrite);
this.Workbook = WorkbookFactory.Create(
this.FileStream);
When it gets to the second statement, I get an ArgumentOutOfRangeException with the following message: "Non-negative number required.\r\nParameter name: value".
Next few lines in the call stack:
at System.IO.FileStream.set_Position(Int64 value)
at NPOI.Util.PushbackStream.set_Position(Int64 value)
at NPOI.POIXMLDocument.HasOOXMLHeader(Stream inp)
at NPOI.SS.UserModel.WorkbookFactory.Create(Stream inputStream)

The WorkbookFactory (link to POI documentation) reads existing file data from an input stream, and determines on the fly whether to create an HSSFWorkbook or an XSSFWorkbook (i.e. whether you are working with XLS or XLSX-like files).
From your code, it seems you are trying to create a new file using this class. That is not something the WorkbookFactory can help you with. To write files, use the following pattern:
var workbook = new XSSFWorkbook();
...
using (var fileData = new FileStream(#"path\filename.xlsx", FileMode.Create))
{
workbook.Write(fileData);
}
(In other words, WorkbookFactory is a class factory, not a file factory :-))

Related

Is there any way to read xlsx when i open a excel to edit it at the same time in c#?

When I use c# to read a excel which I use excel to open it, there is a error The process cannot access the file 'xxxx' because it is being used by another process.
Is there any way to do this, I don't wan't open it for every time.
I'm not sure how you're trying to read the xlsx file, so it might not be possible using the library or tool that you are currently using.
It is possible to open the file stream for reading while Excel has the file open. However, you should be aware that it is also inherently dangerous. The process reading the excel file expects to be reading a consistent view of the file. If Excel decides to write to that same file while it is being read, then it is almost assured that the reading process will fail in some catastrophic way. Since an .xlsx file is just a zip file, the most likely result will be a failure in accessing or decompressing one of the .xlsx entries.
Here is an example of how you can do this using a library I maintain: Sylvan.Data.Excel.
var file = "myfile.xlsx";
// DANGEROUS: open it for reading, but allow other processes to write to it at the same time.
var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// gets the workbook type from the filename extension
var type = ExcelDataReader.GetWorkbookType(file);
// create the data reader
var reader = ExcelDataReader.Create(stream, type);
// loop over rows
while (reader.Read())
{
// write out the data in the row
Console.WriteLine("Row: " + reader.RowNumber);
for (int i = 0; i < reader.RowFieldCount; i++)
{
Console.WriteLine(reader.GetString(i));
}
Console.WriteLine();
}

NPOI corrupting xlsm workbook

I am required to write some data into an macro enabled workbook which was developed in 1998, i am using NPOI dotnet core library for this task. I am able to write the values into the excel correctly, however i am seeing that alignment and formatting of the sheets is lost. Screenshots below:
First one shows the file after open the file using NPOI and downloading the same, and second shows the file when it is locally opened.
below is the code i am using
public XSSFWorkbook OpenExcelFile(string filePath, string tempSavePath)
{
using (var stream = new FileStream(tempSavePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
var temphssfwb = new XSSFWorkbook(OPCPackage.Open(filePath));
temphssfwb.Write(stream);
}
XSSFWorkbook hssfwb;
hssfwb = new XSSFWorkbook(OPCPackage.Open(tempSavePath));
hssfwb.CreateSheet("casevalidationsheet");
return hssfwb;
}
Can someone please help me understand why NPOI is ruining the alignment of my excel workbook?

Npoi xls file save corrupts excel file

So I am able to open and dig through an xls (Excel 97-2003) file. However, the problem is when I try to save it. After I save it, and it succeeds, I then go and manually open the Excel file and get an error saying that it cannot open the Excel file and that it is corrupt. This happens regardless of whether I make any changes or not.
I am still able to, within the program, open the excel file and read through the data.
I am using NPOI 2.2.1 and 2.3.0 (which I installed via Nuget). Both versions have the same results.
string excelLocation = settings.GetExcelDirectory() + week.ExcelLocation;
HSSFWorkbook wbXLS;
// Try to open and read existing workbook
using (FileStream stream = new FileStream(excelLocation, FileMode.Open, FileAccess.Read))
{
wbXLS = new HSSFWorkbook(stream);
}
ISheet sheet = wbXLS.GetSheet("Schedule");
using (FileStream stream = new FileStream(excelLocation, FileMode.Create, FileAccess.Write))
{
wbXLS.Write(stream);
}
Do you have multi-line cell contents (with a line break)?
I just came across such a problem with my column headers in row 0.
Excel encodes a line break by replacing it with _x000a_ (i.e. line1_x000a_line2), NPOI doesn't do that.
Tried with nuget 2.3.0 and xlsx file, but might also be helpful in your case.
I worked around (and verified the cause) by replacing line feeds before saving:
// Encode LineFeeds in column headers (row 0)
IRow rowColHeaders = sheet.GetRow(0);
foreach (ICell cell in rowColHeaders.Cells)
{
string content = cell.StringCellValue;
if (content.Contains("\n"))
cell.SetCellValue(content.Replace("\n", "_x000a_"));
}
try something like
FileStream sw = File.Create(excelLocation);
wbXLS.Write(sw);
sw.Close();

Can't edit the existing Excel file with NPOI?

I've tried creating a new Excel file with NPOI and it works OK, reading (only) an Excel file is also OK. However now I want to open an existing Excel file and append some rows on it, it's crashed right at the code line of the NPOI.HSSF.UserModel.HSSFWorkbook constructor. Here is the code:
using(FileStream fs = new FileStream(myFile, FileMode.Append)){
HSSFWorkbook wb = new HSSFWorkbook(fs); //<-- It is crashed right at here
....
}
There is no exception detail, it just shows a window saying that the app is crashed and give 3 options to choose, the middle one is to close the application:
snapshot
That's why I can't understand and feel hard to solve it.
If I change the FileMode to FileMode.Open, the constructor can work well, but that's just for reading. I think there is some thing related to FileAccess policy and tried this:
using(FileStream fs = new FileStream(myFile, FileMode.Append, FileAccess.ReadWrite)){//<-- However it is crashed right at here
HSSFWorkbook wb = new HSSFWorkbook(fs);
....
}
I've tried a workaround by opening (read only) the existing Excel file, copy 1 sheet of it and add this sheet to a new HSSFWorkbook and write (write only) to a new file stream, however there is no way to do that, because the HSSFWorkbook has no collection of Worksheet and there is also no Add method, the new sheet is just created by CreateSheet() method. It's so annoying.
Could you please help me with this? I'm trying NPOI first, then I'll try EPPlus.Your help would be highly appreciated.Thanks.
What's your file format? xls or xlsx? If xlsx, you can try NPOI 2.0 now. xlsx is supported.
Here is the download link: https://npoi.codeplex.com/releases/view/112932

Cannot access the file because it is being used by another process

My web method creates a pdf file in my %temp% folder and that works. I then want to add some custom fields (meta) to that file using the code below.
The class PdfStamper generates an IOException, whether I use its .Close() method or the using block just ends. The process that is still holding on to the file handle is the webdev web server itself (I'm debugging in VS2010 SP1).
private string AddCustomMetaData(string guid, int companyID, string filePath)
{
try
{
PdfReader reader = new PdfReader(filePath);
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
PdfStamper st = new PdfStamper(reader, fs);
Dictionary<string, string> info = reader.Info;
info.Add("Guid", guid);
info.Add("CompanyID", companyID.ToString());
st.MoreInfo = info;
st.Close();
}
reader.Close();
return guid;
}
catch (Exception e)
{
return e.Message;
}
}
No matter what I try, it keeps throwing the exception at st.Close();, to be more precise:
The process cannot access the file 'C:\Users[my
username]\AppData\Local\Temp\53b96eaf-74a6-49d7-a715-6c2e866a63c3.pdf'
because it is being used by another process.
Either I'm overlooking something obvious or there's a problem with the PdfStamper class I'm as of yet unaware of. Versions of itextsharp used are 5.3.3.0 and 5.4.0.0, the issue is the same.
Any insight would be greatly appreciated.
EDIT: I'm currently "coding around" the issue, but I haven't found any solution.
Your problem is that you are writing to a file while you are also reading from it. Unlike some file types (JPG, PNG, etc) that "load" all of the data into memory, iTextSharp reads the data as a stream. You either need to use two files and swap them at the end or you can force iTextSharp to "load" the first file by binding your PdfReader to a byte array of the file.
PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath));
I suggest you to use the FileShare enumerator when you open the file, so Try to open a file with None sharing
File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
Try to .Dispose() your PDF reader (or whatever you use for creating it) when you save the file for the first time
Try this solution if you think its feasible for you - Once the webmethod creates file in Temp folder, you need to copy the file and paste it into other location or same location with different name and pass newly copied file path to your PDF reader.

Categories

Resources