当第一个单元格为空时 Filehelpers ExcelStorage.ExtractRecords 失败

发布于 2024-08-05 16:57:44 字数 340 浏览 15 评论 0原文

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

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

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

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

谢谢你!

When the first cell of an excel sheet to import using ExcelStorage.ExtractRecords is empty, the process fail. Ie. If the data starts at col 1, row 2, if the cell (2,1) has an empty value, the method fails.

Does anybody know how to work-around this? I've tried adding a FieldNullValue attribute to the mapping class with no luck.

Here is a sample project that show the code with problems

Hope somebody can help me or point in some direction.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愿与i 2024-08-12 16:57:44

您似乎在 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. 看看是否可以从开发人员那里获取补丁或自己修补源代码。

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

It looks like you have stumbled upon an issue in FileHelpers.

What is happening is that the ExcelStorage.ExtractRecords method uses an empty cell check to see if it has reached the end of the sheet. This can be seen in the ExcelStorage.cs source code:

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
    }
}



So if the start column of any row is empty then it assumes that the file is done.

Some options to get around this:

  1. Don't put any empty cells in the first column position.
  2. Don't use excel as your file format -- convert to CSV first.
  3. See if you can get a patch from the developer or patch the source yourself.

The first two are workarounds (and not really good ones). The third option might be the best but what is the end of file condition? Probably an entire row that is empty would be a good enough check (but even that might not work in all cases all of the time).

七秒鱼° 2024-08-12 16:57:44

感谢 Tuzo 的帮助,我找到了解决这个问题的方法。
我向 ExcelStorage 类添加了一个方法来更改 while 结束条件。我没有查看第一个单元格的空值,而是查看当前行中的所有单元格是否为空。如果是这种情况,则返回 false 到 while。这是对 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;
    }

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

谢谢

Thanks to the help of Tuzo, I could figure out a way of working this around.
I added a method to ExcelStorage class to change the while end condition. Instead of looking at the first cell for empty value, I look at all cells in the current row to be empty. If that's the case, return false to the while. This is the change to the while part of ExtractRecords:

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

instead of

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

IsEof is a method to check the whole row to be empty:

    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;
    }

Of course if the user leaves an empty row between two data rows the rows after that one will not be processed, but I think is a good thing to keep working on this.

Thanks

洋洋洒洒 2024-08-12 16:57:44

我需要能够跳过空行,因此我将以下代码添加到 FileHelpers 库中。我采用了 SebastianIsEof 代码,并将该方法重命名为 IsRowEmpty< /code> 并将 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);
}

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

I needed to be able to skip blank lines, so I've added the following code to the FileHelpers library. I've taken Sebastian's IsEof code and renamed the method to IsRowEmpty and changed the loop in ExtractRecords from ...

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

to ...

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

I then changed this ...

colValues = RowValues(cRow, mStartColumn, RecordFieldCount);

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

to this ...

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);
}

What this gives me is the ability to skip single empty rows. The file will be read until two successive empty rows are found

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文