尝试使用NPOI编辑现有Excel文件的单元格值

时间:2016-08-17 09:16:41

标签: c# excel npoi

我编写了以下代码,使用C#和NPOI库编辑Excel文件。没有错误,但是在我打开文件后运行代码后,不会编辑单元格的值。我做错了什么?

namespace Project37
{
    class Class1
    {
        public static void Main()
        {
            string pathSource = @"C:\Users\mvmurthy\Downloads\VOExportTemplate.xlsx";

            FileStream fs = new FileStream(pathSource, FileMode.Open, FileAccess.ReadWrite); 
            HSSFWorkbook templateWorkbook = new HSSFWorkbook(fs, true);
            HSSFSheet sheet = (HSSFSheet)templateWorkbook.GetSheet("ImportTemplate");
            HSSFRow dataRow = (HSSFRow)sheet.GetRow(4);

            dataRow.GetCell(1).SetCellValue("foo");

            MemoryStream ms = new MemoryStream();
            templateWorkbook.Write(ms);
        }     
    }
}

1 个答案:

答案 0 :(得分:9)

您没有看到更改的主要原因是您正在将工作簿编写为MemoryStream而不是写回文件。你应该做的是:

  1. FileStream模式下使用Read完全阅读电子表格文件;
  2. 进行所需的更改,然后
  3. FileStream模式下使用Write写回文件(或者,如果您不想销毁原文,可以选择写入其他文件 - 这可能更适合测试)。
  4. 另请注意,在使用实现using的所有IDisposable的类时,最好使用Streams语句。这将确保关闭文件并正确清理流使用的所有资源。

    我在您的代码中看到了另一个问题,那就是您显然正在尝试将HSSFWorkbook.xlsx文件一起使用。那不会奏效。 HSSFWorkbook(以及所有HSSF类)适用于.xls个文件。如果您需要使用.xlsx个文件,那么您应该使用XSSFWorkbook和相关的XSSF类。请注意,如果您需要支持这两种类型的文件,这两种类都会实现常见的接口,如IWorkbookISheetIRow等,以帮助减少代码重复。我建议尽可能使用它们。但是,您可能会发现您仍然需要偶尔转发以访问接口未涵盖的某些功能。

    我应该提到另一件事:如果特定行x在原始工作簿中不包含单元格,则GetRow(x)将返回null。同样,如果单元格GetCell(y)为空,y将返回null。如果您希望能够设置单元格的值,则需要检查空值并根据需要使用CreateRow(x)和/或CreateCell(y)以确保每个相应的实体都存在。

    以下是修订后的代码:

    string pathSource = @"C:\Users\mvmurthy\Downloads\VOExportTemplate.xlsx";
    
    IWorkbook templateWorkbook;
    using (FileStream fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read))
    {
        templateWorkbook = new XSSFWorkbook(fs);
    }
    
    string sheetName = "ImportTemplate";
    ISheet sheet = templateWorkbook.GetSheet(sheetName) ?? templateWorkbook.CreateSheet(sheetName);
    IRow dataRow = sheet.GetRow(4) ?? sheet.CreateRow(4);
    ICell cell = dataRow.GetCell(1) ?? dataRow.CreateCell(1);
    cell.SetCellValue("foo");
    
    using (FileStream fs = new FileStream(pathSource, FileMode.Create, FileAccess.Write))
    {
        templateWorkbook.Write(fs);
    }