尝试使用NPOI编辑现有Excel文件的单元格值
我写了下面的代码来编辑使用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); } } }
您没有看到更改的主要原因是因为您正在将工作簿写入MemoryStream
而不是写回文件。 你应该做的是这样的:
- 在
Read
模式下使用FileStream
来完全读取电子表格文件; - 然后做出你想要的改变
- 在
Write
模式下使用FileStream
来回写文件(或者如果不想破坏原始文件(这可能更适合于testing),可以写入不同的文件)。
另外请注意,在使用实现IDisposable
类(所有Streams
)时使用using
语句是一个很好的习惯。 这将确保文件closures,并且正确清理stream使用的所有资源。
我在代码中看到了另外一个问题,那就是你显然试图使用带有.xlsx
文件的HSSFWorkbook
。 这是行不通的。 HSSFWorkbook
(和所有的HSSF
类)是.xls
文件。 如果您需要使用.xlsx
文件,则应该使用XSSFWorkbook
和相关的XSSF
类。 请注意,如果您需要支持这两种types的文件,那么这两种类的类都可以实现IWorkbook
, ISheet
, IRow
等通用接口,以帮助减less代码重复。 我build议尽可能使用它们。 但是你可能会发现你仍然需要不时地倒下来访问某些没有被接口覆盖的特性。
还有一件事我应该提到:如果一个特定的行x
在原始工作簿中不包含单元格,则GetRow(x)
将返回null。 同样,如果单元格y
为空, GetCell(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); }