使用NPOI编写文件

时间:2015-03-13 21:42:13

标签: c# .net .net-4.5 npoi

尝试从DLL执行此操作时,我无法使用NPOI将xlsx更改保存到磁盘。

我有一组我目前存储在数据库中的数据,以及一个本土的ORM数据。本土的ORM存放在自己的DLL中。我想编写一个实用程序,它使用ORM来获取数据的子集来读/写它。我使用NPOI(v2.1.3.0)来完成它。

实用程序调用如下所示:

    private void Test_Click(object sender, RoutedEventArgs e)
    {
        var model = new ExcelDal(this.filename);
        model.Clients.Save(new Client { 
              DateOfBirth = DateTime.Now, DisplayName = "Test", Male = true
        });
    }

我希望我能得到一张名为&#34的客户xlsx;客户"和#34; DateOfBirth"," DisplayName"和"男"的文本列。确实创建了一个文件,但尝试打开它失败了。另一方面,如果我用这个替换代码,我会得到预期的结果:

    private void Test_Click(object sender, RoutedEventArgs e)
    {
        IWorkbook workbook = new XSSFWorkbook();
        ISheet sheet = workbook.CreateSheet("Client");
        MainWindow.Create(sheet, 0, "DateOfBirth", "DisplayName", "Male");
        MainWindow.Create(sheet, 1, "1900/1/1", "Test", "true");

        FileMode mode = File.Exists(this.filename) ? FileMode.Truncate : FileMode.Create;

        using (FileStream fs = new FileStream(this.filename, mode, FileAccess.ReadWrite))
        {
            workbook.Write(fs);
        }
    }

    private static void Create(ISheet sheet, int rowNum, params string[] values)
    {
        IRow row = sheet.CreateRow(rowNum);
        for (int i = 0; i < values.Length; i++)
        {
            ICell cell = row.CreateCell(i);
            cell.SetCellValue(values[i]);
        }
    }

到目前为止尝试的故障排除步骤:

  • 将创建的文件重命名为zip并将其解压缩,这是一个有效的zip。
  • 将文件压缩并重命名为xlsx,我收到的错误略有不同,但仍无法打开。
  • 一切都是.Net 4.5
  • 在转换字符串值的答案中使用ICreationHelper提到的另一个SO question,所以我也试过了,但它没有改变任何东西。
  • 关于ORM的一些注意事项,因为包含所有相关代码可能有点过分。我使用的代码与上面的代码完全相同;我构建了测试代码,试图弄清楚我做错了什么,但它还是令人沮丧地工作了。

这就是设置单元格值的代码(请注意,在实际保存时,值已经是toString()&#39; d):

    public void SetValue(IRow row, string column, string value)
    {
        int columnIndex = this.GetColumnIndex(column);
        ICell cell = ColumnMapping.GetOrCreateCell(row, columnIndex);
        cell.SetCellValue(value);
    }

    private static ICell GetOrCreateCell(IRow row, int columnIndex)
    {
        return row.GetCell(columnIndex) ?? row.CreateCell(columnIndex);
    }

这是保存文件的代码:

    public void Save()
    {
        FileMode mode = File.Exists(this.filename) ? FileMode.Truncate : FileMode.Create;

        using (FileStream fs = new FileStream(this.filename, mode, FileAccess.ReadWrite))
        {
            this.workbook.Write(fs);
        }
    }

我无法发现任何差异。唯一可能的是,通过上述ORM间接使用NPOI,并且直接使用NPOI。

1 个答案:

答案 0 :(得分:0)

我无法找到一种用NPOI可靠地做到这一点的方法。该实用程序创建的文件总是损坏。我切换到EPPlus for xlsx。结果代码如下所示:

public void SetValue(int row, string column, string value)
{
    row += 2;   //EPPlus is 1-index based, and the first row is the heading
    int columnIndex = this.GetColumnIndex(column);
    this.excelSheet.SetValue(row, columnIndex, value);
}

保存文件的相应代码如下所示:

public void Dispose()
{
    //ExcelPackage is gone once it is written out.  It must be re-created.
    this.excelPackage.SaveAs(new FileInfo(this.filename));
    this.excelPackage.Dispose();
}

因此,实现是添加一个Flush(),它将处理当前的ExcelPackage,然后处理当前在内存中的所有ExcelSheet,然后从写出的文件中重新初始化所有内容。