5

当使用 ExcelStorage.ExtractRecords 导入的 Excel 工作表的第一个单元格为空时,该过程将失败。IE。如果数据从第 1 列第 2 行开始,如果单元格 (2,1) 具有空值,则该方法将失败。

有人知道如何解决这个问题吗?我尝试将 FieldNullValue 属性添加到映射类,但没有成功。

是一个示例项目,显示有问题的代码

希望有人可以帮助我或指出某个方向。

谢谢!

4

3 回答 3

4

您似乎偶然发现了 FileHelpers 中的一个问题。

发生的事情是 ExcelStorage.ExtractRecords 方法使用空单元格检查它是否已到达工作表的末尾。这可以在 ExcelStorage.cs 源代码中看到:

while (CellAsString(cRow, mStartColumn) != String.Empty)
{
    try
    {
        recordNumber++;
        Notify(mNotifyHandler, mProgressMode, recordNumber, -1);

        colValues = RowValues(cRow, mStartColumn, RecordFieldCount);

        object record = ValuesToRecord(colValues);
        res.Add(record);

    }
    catch (Exception ex)
    {
        // Code removed for this example
    }
}


因此,如果任何行的起始列为空,则假定文件已完成。

解决此问题的一些选择:

  1. 不要在第一列位置放置任何空单元格。
  2. 不要使用 excel 作为文件格式——首先转换为 CSV。
  3. 看看您是否可以从开发人员那里获得补丁或自己修补源。

前两个是解决方法(并不是很好的解决方法)。第三个选项可能是最好的,但文件结束条件是什么?可能一整行是空的将是一个足够好的检查(但即使这样也可能并非在所有情况下都有效)。

于 2009-09-23T02:38:59.757 回答
4

感谢 Tuzo 的帮助,我可以找到解决此问题的方法。我向 ExcelStorage 类添加了一个方法来更改 while 结束条件。我没有查看第一个单元格的空值,而是查看当前行中的所有单元格是否为空。如果是这种情况,则在 while 中返回 false。这是对 ExtractRecords 的 while 部分的更改:

while (!IsEof(cRow, mStartColumn, RecordFieldCount))

代替

while (CellAsString(cRow, mStartColumn) != String.Empty)

IsEof 是一种检查整行是否为空的方法:

    private bool IsEof(int row, int startCol, int numberOfCols)
    {
        bool isEmpty = true;
        string cellValue = string.Empty;

        for (int i = startCol; i <= numberOfCols; i++)
        {
            cellValue = CellAsString(row, i);
            if (cellValue != string.Empty)
            {
                isEmpty = false;
                break;
            }
        }

        return isEmpty;
    }

当然,如果用户在两个数据行之间留下一个空行,则不会处理该行之后的行,但我认为继续努力是一件好事。

谢谢

于 2009-09-23T15:30:52.157 回答
3

我需要能够跳过空白行,因此我将以下代码添加到 FileHelpers 库中。我采用了SebastianIsEof代码并将方法重命名为IsRowEmpty并将循环ExtractRecords从 ...

while (CellAsString(cRow, mStartColumn) != String.Empty)

到 ...

while (!IsRowEmpty(cRow, mStartColumn, RecordFieldCount) || !IsRowEmpty(cRow+1, mStartColumn, RecordFieldCount))

然后我改变了这个......

colValues = RowValues(cRow, mStartColumn, RecordFieldCount);

object record = ValuesToRecord(colValues);
res.Add(record);

对此...

bool addRow = true;

if (Attribute.GetCustomAttribute(RecordType, typeof(IgnoreEmptyLinesAttribute)) != null && IsRowEmpty(cRow, mStartColumn, RecordFieldCount))
{
    addRow = false;
}

if (addRow)
{
    colValues = RowValues(cRow, mStartColumn, RecordFieldCount);

    object record = ValuesToRecord(colValues);
    res.Add(record);
}

这给了我跳过单个空行的能力。该文件将被读取,直到找到两个连续的空行

于 2011-03-18T22:39:03.083 回答