Reputation: 57
I made a program for splitting a cell into two cells and write them in a different sheets but after I run it the excel file gets corrupted.
IWorkbook workbook;
using(FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
workbook = new XSSFWorkbook(stream);
}
IWorkbook newWorkbook = new XSSFWorkbook();
ISheet sheet = workbook.GetSheetAt(0);
ISheet oneWordSheet = newWorkbook.CreateSheet();
ISheet moreWordsSheet = newWorkbook.CreateSheet();
IRow tmpRow;
for(int i = 5; i < 100/*sheet.LastRowNum*/ + 1; i++)
{
tmpRow = sheet.GetRow(i);
string[] strings = tmpRow.GetCell(2).StringCellValue.Split(' ');
string companyName = strings[0];
bool parseFailed = true;
for(int j = 1; parseFailed && j < strings.Length; j++)
{
try
{
int.Parse(strings[j]);
parseFailed = false;
}
catch (FormatException)
{
companyName += strings[j];
j++;
}
}
tmpRow.CreateCell(4).SetCellValue(companyName);
if(companyName.Trim().Split(' ').Length < 2)
{
copyRowToSheet(tmpRow, oneWordSheet);
}
else
{
copyRowToSheet(tmpRow, moreWordsSheet);
}
}
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Write))
{
newWorkbook.Write(stream);
}
I made a copyRowToSheet method like this. It should be correct
private static void copyRowToSheet(IRow row, ISheet sheet)
{
IRow newRow = sheet.CreateRow(sheet.LastRowNum + 1);
newRow.CreateCell(0).SetCellValue(row.GetCell(0).NumericCellValue);
newRow.CreateCell(1).SetCellValue(row.GetCell(1).StringCellValue);
newRow.CreateCell(2).SetCellValue(row.GetCell(4).StringCellValue);
newRow.CreateCell(3).SetCellValue(row.GetCell(2).StringCellValue);
newRow.CreateCell(4).SetCellValue(row.GetCell(3).StringCellValue);
}
I tried writing from workbook instead of newWorkbook, but it still corrupts the file, I also tried removing copyRowToSheet method (just leaving both the if and else case empty but the result doesn't change...
Edit: I tried removing the whole body of the program leaving just this:
IWorkbook workbook;
using(FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
workbook = new XSSFWorkbook(stream);
stream.Close();
}
IWorkbook newWorkbook = new XSSFWorkbook();
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Write))
{
workbook.Write(stream);
stream.Close();
}
If I'm not wrong this should only read the file and then save it back without editing anything, but it still corrupts the file
Upvotes: 2
Views: 1814
Reputation: 3432
I hit the same issue myself a couple of weeks ago when i was starting out with npoi. Quite a tricky one to diagnose as the code you are using is repeated time and again in tutorials and blogs.
The problem occurs when you are creating your second FileStream to write back the spreadsheet to disk. You are writing to the same file that you read earlier.
The behavour of FileMode.Open when writing to an existing file is to append the data to the end of the file. This results in you having 2 excel spreadsheets in a single file which when you open it is declared corrupt.
FileMode.Create on the other hand will overwrite an existing file so this is more likely to be what you need.
using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
{
workbook.Write(stream);
stream.Close();
}
Here's the docs file FileMode as there are alternates to Create that you may prefer.
Upvotes: 3