【问题标题】:Why would there be no data in the visualiser when there is valid data in the DataTable?为什么 DataTable 中有有效数据时,可视化器中没有数据?
【发布时间】:2017-04-11 13:18:53
【问题描述】:

我正在尝试为 SpreadsheetLight 构建一个包装器,该包装器从通过它的任何 .xlsx 文档返回一个 DataSet。但是,我似乎遇到了 DataRows 未添加到临时 DataTable 的问题。

以下是解析工作表并从中生成 DataTable 的部分代码:

    public DataSet ReadToDataSet(string fileName)
    {

        using (var wb = new SLDocument(fileName))
        {
            var set = new DataSet(GenerateTitle(wb.DocumentProperties.Title));

            foreach (var wsName in wb.GetWorksheetNames())
            {

                var ws = wb.SelectWorksheet(wsName);

                // Select worksheet returns a bool, so if it comes back false, try the next worksheet instead.
                if (!ws) continue;

                // Statistics gives indecies of the first and last data cells
                var stats = wb.GetWorksheetStatistics();

                // Create a new DataTable for each worksheet
                var dt = new DataTable(wsName);

                //var addDataColumns = true;

                for (var colIdx = stats.StartColumnIndex; colIdx < stats.EndColumnIndex; colIdx++)
                    dt.Columns.Add(colIdx.ToString(), typeof(string));


                // Scan each row
                for (var rowIdx = stats.StartRowIndex; rowIdx < stats.EndRowIndex; rowIdx++)
                {
                    //dt.Rows.Add();

                    var newRow = dt.NewRow();

                    // And each column for data
                    for (var colIdx = stats.StartColumnIndex; colIdx < stats.EndColumnIndex; colIdx++)
                    {
                        //if (addDataColumns)
                        //    dt.Columns.Add();

                        newRow[colIdx - 1] = wb.GetCellValueAsString(rowIdx, colIdx);

                        //if (colIdx >= stats.EndColumnIndex)
                        //    addDataColumns = false;
                    }
                    dt.Rows.Add(newRow);
                }

                set.Tables.Add(dt);
            }

            // Debug output
            foreach (DataRow row in set.Tables[0].Rows)
            {
                foreach (var output in row.ItemArray)
                {
                    Console.WriteLine(output.ToString());
                }
            }

            return set;
        }
    }

注意:SpreadsheetLight 索引从 1 而不是 0 开始;

现在,我尝试将dt.Rows.Add() 替换为new object[stats.EndColumnIndex -1];,以及来自var newRow = dt.NewRow(); 的临时变量,然后将它们传递到DataTable,但仍然得到相同的最终结果。行对象正在正确填充,但最后没有传输到 DataTable。

当您在运行时探索对象时,它会在相关属性中显示正确的行数和列数。但是当你在 DataVisualiser 中打开它时,你只能看到列,看不到行。

我一定遗漏了一些明显的东西。

更新

我遍历结果表并将值输出到控制台作为测试。出现所有正确的值,但可视化器保持为空:

我想现在的问题是,为什么DataTable中有有效数据时,可视化器中没有数据

更新 2 添加了完整的参考方法,包括一组简单的 for 循环,用于遍历第一个 DataTable 中的所有行和列。注意:我还尝试将列创建从循环中拉出来,甚至设置数据类型。没有区别。注释代码显示原始代码。

【问题讨论】:

  • 如果你要否决一个问题,至少有礼貌地解释为什么......
  • 您确定要探索实际的 DataTable 吗?因为看起来你的 DataTable 只不过是一个局部变量......
  • 在 for 循环结束时,DataTable 被添加到 DataSet 中
  • 在这种情况下,不是填充表格的代码部分,而是实际查看表格的部分。

标签: c# datatable datarow spreadsheetlight


【解决方案1】:

好的,事实证明问题很可能出在添加的列上。要么是有太多列供可视化器处理 (1024),我很难相信,要么是 Visual Studio 中存在随机纠正的错误。

SpreadsheetLight 中还有一个错误,当您调用 GetWorksheetStatistics(); 时,它会将所有列列为具有数据的列;所以我使用了一种解决方法,即使用可用的总单元格的最大数量或 stats.NumberOfColumns,以最小者为准。

不管怎样,下面的代码现在都可以运行了。

public DataSet ReadToDataSet(string fileName)
{

    using (var wb = new SLDocument(fileName))
    {
        var set = new DataSet(GenerateTitle(wb.DocumentProperties.Title));

        foreach (var wsName in wb.GetWorksheetNames())
        {

            var ws = wb.SelectWorksheet(wsName);

            // Select worksheet returns a bool, so if it comes back false, try the next worksheet instead.
            if (!ws) continue;

            // Statistics gives indecies of the first and last data cells
            var stats = wb.GetWorksheetStatistics();

            // There is a bug with the stats columns. Take the total number of elements available or the columns from the stats table, whichever is the smallest
            var newColumnIndex = stats.NumberOfCells < stats.NumberOfColumns
                                ? stats.NumberOfCells
                                : stats.NumberOfColumns;

            // Create a new DataTable for each worksheet
            var dt = new DataTable(wsName);

            var addDataColumns = true;

            // Scan each row
            for (var rowIdx = stats.StartRowIndex; rowIdx < stats.EndRowIndex; rowIdx++)
            {

                var newRow = dt.NewRow();

                // And each column for data
                for (var colIdx = stats.StartColumnIndex; colIdx < newColumnIndex; colIdx++)
                {
                    if (addDataColumns)
                        dt.Columns.Add();

                    newRow[colIdx - 1] = wb.GetCellValueAsString(rowIdx, colIdx);

                }

                addDataColumns = false;

                dt.Rows.Add(newRow);
            } 

            set.Tables.Add(dt);
        }

        return set;
    }
}

希望其他人将来能将此作为有用的参考,无论是用于 Visual Studio 中的 SpreadsheetLight 或 DataVisualiser。如果有人知道可视化器的任何限制,我会全力以赴!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-03
    • 2018-08-28
    • 2012-02-08
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 2015-04-24
    相关资源
    最近更新 更多