简体   繁体   English

NPOI文件损坏

[英]NPOI Corrupted file

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. 我制作了一个程序,用于将一个单元格拆分为两个单元格,并将它们写在不同的工作表中,但是运行它后,excel文件被损坏。

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. 我做了这样的copyRowToSheet方法。 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... 我尝试从工作簿而不是newWorkbook进行写操作,但是它仍然损坏了文件,我还尝试了删除copyRowToSheet方法(只是将if和else case都保留为空,但结果没有改变...

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 如果我没记错,这应该只读取文件,然后将其保存回去而不进行任何编辑,但是它仍然会损坏文件

I hit the same issue myself a couple of weeks ago when i was starting out with npoi. 几周前,我刚接触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. 当您创建第二个FileStream以便将电子表格写回到磁盘时,会发生此问题。 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. 写入现有文件时,FileMode.Open的行为是将数据附加到文件末尾。 This results in you having 2 excel spreadsheets in a single file which when you open it is declared corrupt. 这将导致您在一个文件中有2个excel电子表格,当您打开该文件时,它们被声明为损坏。

FileMode.Create on the other hand will overwrite an existing file so this is more likely to be what you need. 另一方面,FileMode.Create会覆盖现有文件,因此这很可能是您所需要的。

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. 这是docs文件FileMode,因为您可能更喜欢Create的替代方法。

Doc for FileMode 文件模式文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM