尝试使用 epplus 读取 excel 文件并出现 System.NullException 错误?
Trying to read excel file with epplus and getting System.NullException error?
编辑
根据以下回复,我遇到的错误可能会也可能不会导致我无法读取我的 excel 文件。也就是说,我没有从下面给出的 for 循环中的 worksheet.Cells[row,col].Value
行获取数据。
问题
我正在尝试 return 一个包含来自 excel 文件的信息的数据表。具体来说,我相信它是 2013 excel 的 xlsx 文件。请看下面的代码:
private DataTable ImportToDataTable(string Path)
{
DataTable dt = new DataTable();
FileInfo fi = new FileInfo(Path);
if(!fi.Exists)
{
throw new Exception("File " + Path + " Does not exist.");
}
using (ExcelPackage xlPackage = new ExcelPackage(fi))
{
//Get the worksheet in the workbook
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();
//Obtain the worksheet size
ExcelCellAddress startCell = worksheet.Dimension.Start;
ExcelCellAddress endCell = worksheet.Dimension.End;
//Create the data column
for(int col = startCell.Column; col <= endCell.Column; col++)
{
dt.Columns.Add(col.ToString());
}
for(int row = startCell.Row; row <= endCell.Row; row++)
{
DataRow dr = dt.NewRow(); //Create a row
int i = 0;
for(int col = startCell.Column; col <= endCell.Column; col++)
{
dr[i++] = worksheet.Cells[row, col].Value.ToString();
}
dt.Rows.Add(dr);
}
}
return dt;
}
错误
这就是事情变得奇怪的地方。我可以在 startCell
和 endCell
中看到正确的值。但是,当我看 worksheet
时,我在 Cells
下看了一眼,我看到了一些我不明白的东西:
worksheet.Cells.Current' threw an exception of type 'System.NullReferenceException
尝试次数
- 正在使用常规字段重新格式化我的 excel。
- 确保我的 excel 中没有字段为空
- RTFM 编辑的 epplus 文档。没有任何迹象表明此错误。
- 查看 Whosebug 上的 EPPlus 错误。我的问题很独特。
老实说,我很难弄清楚这个错误到底在说什么?我的格式有问题吗? epplus有问题吗?我在这里读到人们对带有 eeplus 的 2013 xlsx 没有任何问题,我只是想逐行解析 excel 文件。如果有人可以帮助我阐明此错误的含义以及如何纠正它。我将不胜感激。我花了很长时间试图弄清楚这一点。
current为枚举时的当前范围。
当它没有在枚举范围内使用时,在调试检查中抛出异常没有任何问题。
代码示例:
var range = ws.Cells[1,1,1,100];
foreach (var cell in range)
{
var a = range.Current.Value; // a is same as b
var b = cell.Value;
}
就像@Thorians 所说的那样,当您枚举单元格时,电流确实是要使用的。如果你想以最纯粹的形式使用它并且实际上能够调用 current
那么你需要这样的东西:
using (var pck = new ExcelPackage(existingFile))
{
var worksheet = pck.Workbook.Worksheets.First();
//this is important to hold onto the range reference
var cells = worksheet.Cells;
//this is important to start the cellEnum object (the Enumerator)
cells.Reset();
//Can now loop the enumerator
while (cells.MoveNext())
{
//Current can now be used thanks to MoveNext
Console.WriteLine("Cell [{0}, {1}] = {2}"
, cells.Current.Start.Row
, cells.Current.Start.Column
, cells.Current.Value);
}
}
请注意,您必须创建一种 local
集合 cells
才能使其正常工作。否则,如果您尝试“worksheet.cells.current”
,Current
将为空
但是使用 ForEach
并让 CLR 为您完成工作会更简单。
更新:基于评论。您的代码应该可以正常工作,它可以是您的 excel 文件:
[TestMethod]
public void Current_Cell_Test()
{
//
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[] { new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (int)),new DataColumn("Col3", typeof (object)) });
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow(); row[0] = i; row[1] = i * 10; row[2] = Path.GetRandomFileName(); datatable.Rows.Add(row);
}
//Create a test file
var fi = new FileInfo(@"c:\temp\test1.xlsx");
if (fi.Exists)
fi.Delete();
using (var pck = new ExcelPackage(fi))
{
var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
pck.Save();
}
var dt = new DataTable();
using (ExcelPackage xlPackage = new ExcelPackage(fi))
{
//Get the worksheet in the workbook
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();
//Obtain the worksheet size
ExcelCellAddress startCell = worksheet.Dimension.Start;
ExcelCellAddress endCell = worksheet.Dimension.End;
//Create the data column
for (int col = startCell.Column; col <= endCell.Column; col++)
{
dt.Columns.Add(col.ToString());
}
for (int row = startCell.Row; row <= endCell.Row; row++)
{
DataRow dr = dt.NewRow(); //Create a row
int i = 0;
for (int col = startCell.Column; col <= endCell.Column; col++)
{
dr[i++] = worksheet.Cells[row, col].Value.ToString();
}
dt.Rows.Add(dr);
}
}
Console.Write("{{dt Rows: {0} Columns: {1}}}", dt.Rows.Count, dt.Columns.Count);
}
在输出中给出:
{Rows: 11, Columns: 3}
当我们给予:
dr[i++] = worksheet.Cells[row, col].Value.ToString();
它在该列搜索值,如果该列为空,则给出 Null 引用错误。
试试看:
dr[i++] = worksheet.Cells[row, col].Text;
希望这会有所帮助
我在阅读 excel 文件时也遇到了同样的问题,none 提供的解决方案对我有用。这是工作代码:
public void readXLS(string FilePath)
{
FileInfo existingFile = new FileInfo(FilePath);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int colCount = worksheet.Dimension.End.Column; //get Column Count
int rowCount = worksheet.Dimension.End.Row; //get row count
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value.ToString().Trim());
}
}
}
}
编辑
根据以下回复,我遇到的错误可能会也可能不会导致我无法读取我的 excel 文件。也就是说,我没有从下面给出的 for 循环中的 worksheet.Cells[row,col].Value
行获取数据。
问题
我正在尝试 return 一个包含来自 excel 文件的信息的数据表。具体来说,我相信它是 2013 excel 的 xlsx 文件。请看下面的代码:
private DataTable ImportToDataTable(string Path)
{
DataTable dt = new DataTable();
FileInfo fi = new FileInfo(Path);
if(!fi.Exists)
{
throw new Exception("File " + Path + " Does not exist.");
}
using (ExcelPackage xlPackage = new ExcelPackage(fi))
{
//Get the worksheet in the workbook
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();
//Obtain the worksheet size
ExcelCellAddress startCell = worksheet.Dimension.Start;
ExcelCellAddress endCell = worksheet.Dimension.End;
//Create the data column
for(int col = startCell.Column; col <= endCell.Column; col++)
{
dt.Columns.Add(col.ToString());
}
for(int row = startCell.Row; row <= endCell.Row; row++)
{
DataRow dr = dt.NewRow(); //Create a row
int i = 0;
for(int col = startCell.Column; col <= endCell.Column; col++)
{
dr[i++] = worksheet.Cells[row, col].Value.ToString();
}
dt.Rows.Add(dr);
}
}
return dt;
}
错误
这就是事情变得奇怪的地方。我可以在 startCell
和 endCell
中看到正确的值。但是,当我看 worksheet
时,我在 Cells
下看了一眼,我看到了一些我不明白的东西:
worksheet.Cells.Current' threw an exception of type 'System.NullReferenceException
尝试次数
- 正在使用常规字段重新格式化我的 excel。
- 确保我的 excel 中没有字段为空
- RTFM 编辑的 epplus 文档。没有任何迹象表明此错误。
- 查看 Whosebug 上的 EPPlus 错误。我的问题很独特。
老实说,我很难弄清楚这个错误到底在说什么?我的格式有问题吗? epplus有问题吗?我在这里读到人们对带有 eeplus 的 2013 xlsx 没有任何问题,我只是想逐行解析 excel 文件。如果有人可以帮助我阐明此错误的含义以及如何纠正它。我将不胜感激。我花了很长时间试图弄清楚这一点。
current为枚举时的当前范围。
当它没有在枚举范围内使用时,在调试检查中抛出异常没有任何问题。
代码示例:
var range = ws.Cells[1,1,1,100];
foreach (var cell in range)
{
var a = range.Current.Value; // a is same as b
var b = cell.Value;
}
就像@Thorians 所说的那样,当您枚举单元格时,电流确实是要使用的。如果你想以最纯粹的形式使用它并且实际上能够调用 current
那么你需要这样的东西:
using (var pck = new ExcelPackage(existingFile))
{
var worksheet = pck.Workbook.Worksheets.First();
//this is important to hold onto the range reference
var cells = worksheet.Cells;
//this is important to start the cellEnum object (the Enumerator)
cells.Reset();
//Can now loop the enumerator
while (cells.MoveNext())
{
//Current can now be used thanks to MoveNext
Console.WriteLine("Cell [{0}, {1}] = {2}"
, cells.Current.Start.Row
, cells.Current.Start.Column
, cells.Current.Value);
}
}
请注意,您必须创建一种 local
集合 cells
才能使其正常工作。否则,如果您尝试“worksheet.cells.current”
Current
将为空
但是使用 ForEach
并让 CLR 为您完成工作会更简单。
更新:基于评论。您的代码应该可以正常工作,它可以是您的 excel 文件:
[TestMethod]
public void Current_Cell_Test()
{
//
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[] { new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (int)),new DataColumn("Col3", typeof (object)) });
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow(); row[0] = i; row[1] = i * 10; row[2] = Path.GetRandomFileName(); datatable.Rows.Add(row);
}
//Create a test file
var fi = new FileInfo(@"c:\temp\test1.xlsx");
if (fi.Exists)
fi.Delete();
using (var pck = new ExcelPackage(fi))
{
var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
pck.Save();
}
var dt = new DataTable();
using (ExcelPackage xlPackage = new ExcelPackage(fi))
{
//Get the worksheet in the workbook
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();
//Obtain the worksheet size
ExcelCellAddress startCell = worksheet.Dimension.Start;
ExcelCellAddress endCell = worksheet.Dimension.End;
//Create the data column
for (int col = startCell.Column; col <= endCell.Column; col++)
{
dt.Columns.Add(col.ToString());
}
for (int row = startCell.Row; row <= endCell.Row; row++)
{
DataRow dr = dt.NewRow(); //Create a row
int i = 0;
for (int col = startCell.Column; col <= endCell.Column; col++)
{
dr[i++] = worksheet.Cells[row, col].Value.ToString();
}
dt.Rows.Add(dr);
}
}
Console.Write("{{dt Rows: {0} Columns: {1}}}", dt.Rows.Count, dt.Columns.Count);
}
在输出中给出:
{Rows: 11, Columns: 3}
当我们给予:
dr[i++] = worksheet.Cells[row, col].Value.ToString();
它在该列搜索值,如果该列为空,则给出 Null 引用错误。
试试看:
dr[i++] = worksheet.Cells[row, col].Text;
希望这会有所帮助
我在阅读 excel 文件时也遇到了同样的问题,none 提供的解决方案对我有用。这是工作代码:
public void readXLS(string FilePath)
{
FileInfo existingFile = new FileInfo(FilePath);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int colCount = worksheet.Dimension.End.Column; //get Column Count
int rowCount = worksheet.Dimension.End.Row; //get row count
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value.ToString().Trim());
}
}
}
}