【问题标题】:Importing from Excel: some cells become null从 Excel 导入:某些单元格变为空
【发布时间】:2011-05-24 04:54:13
【问题描述】:

我正在从 excel 文件中导入数据,我只是注意到导入后某些单元格变成了“”

这是我正在使用的代码

                FileUploadExcel.SaveAs("C:\\datatop.xls");
                string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\1.xls;Extended Properties=Excel 8.0;";


                using (OleDbConnection connection = new OleDbConnection(connectionString))
                {
                    connection.Open();
                    OleDbCommand command = new OleDbCommand("Select MONTH, QTY FROM [Sheet1$]", connection);
                    DataTable tb = new DataTable();
                    using (System.Data.Common.DbDataReader dr = command.ExecuteReader())
                    {
                        tb.Load(dr);
                    }
                    gv.DataSource = tb;
                    gv.DataBind();
                }

有问题的列是QTY,其中包含:

12
14
15
11
19k/yr
4
2

导入后它在我的网格视图上变成了一个空间。所有其他单元格在 gridview 上都显示得很好。

GridView 中的输出:

12
14
15
11

4
2

有什么想法吗?

【问题讨论】:

  • 您的某些代码是否被截断?我没有收到1.Text2.Text
  • @DanM 是的,我编辑了它,谢谢。
  • 您是否能够编辑您的 Excel 文件,请尝试在 19k/yr 之前添加撇号 (')。
  • @danm 它仍然没有显示 mate
  • 哦,我知道问题出在哪里了。看我的回答。

标签: c# asp.net excel


【解决方案1】:

在 Excel 中使用 OLEDB 时,列的数据类型由每列中的前几项确定。在您的情况下,列中的前几项是数字,因此假定该列的类型为int。如果您希望将该列视为文本,则需要确保顶部有一些虚拟行,其中包含确保正确数据类型的数据,然后在将数据读入数据表后过滤掉这些行。我知道这是一个小插曲,但它应该可以工作。

编辑 - 替代方法:使用 Excel Interop/COM 填充数据表

using Microsoft.Office.Interop.Excel;
using Sd = System.Data;

private void FillTableData(Sd.DataTable table, Worksheet worksheet, Range cells)
{
    using (var com = new ComObjectManager())
    {
        var firstCell = GetFirstCell(com, cells);
        var beginCell = com.Get<Range>(() => (Range)cells.Item[2, 1]);
        var endCell = GetLastContiguousCell(com, cells, firstCell);
        if (beginCell.Value == null) return;
        var range = GetRange(com, cells, beginCell, endCell);
        var data = (object[,])range.Value;
        var rowCount = data.GetLength(0);
        for (var rowIndex = 0; rowIndex < rowCount; rowIndex++)
        {
            var values = new object[table.Columns.Count];
            for (var columnIndex = 0; columnIndex < table.Columns.Count; columnIndex++)
            {
                var value = data[rowIndex + 1, columnIndex + 1];
                values[columnIndex] = value;
            }
            table.Rows.Add(values);
        }
    }
}

private Range GetFirstCell(ComObjectManager com, Range cells)
{
    return com.Get<Range>(() => (Range)cells.Item[1, 1]);
}

private Range GetLastContiguousCell(ComObjectManager com, Range cells, Range beginCell)
{
    var bottomCell = com.Get<Range>(() => beginCell.End[XlDirection.xlDown]);
    var rightCell = com.Get<Range>(() => beginCell.End[XlDirection.xlToRight]);
    return com.Get<Range>(() => (Range)cells.Item[bottomCell.Row, rightCell.Column]);
}

ComObjectManager - 确保 COM 对象在使用后得到正确处理

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public class ComObjectManager : IDisposable
{
    private Stack<object> _comObjects = new Stack<object>();

    public TComObject Get<TComObject>(Func<TComObject> getter)
    {
        var comObject = getter();
        _comObjects.Push(comObject);
        return comObject;
    }

    public void Dispose()
    {
        while (_comObjects.Count > 0)
            Marshal.ReleaseComObject(_comObjects.Pop());
    }
}

【讨论】:

  • 谢谢伙计。但还有其他方法吗?因为我要导入近百个 excel 文件,而且要全部编辑它们非常繁琐
  • 另一种可能性是使用 Excel 互操作。这仅在您使用安装了 Office 的机器上工作时才有效,但如果您这样做,它会提供比 OLEDB 更大的灵活性。我会用一些示例代码更新我的答案。
【解决方案2】:

@Pod 梅斯 相反,您可以使用第三方 DLL 来使用 excel 进行许多操作,并且使用它非常容易。 Here is the link to its download :

还可以通过使用它提供的源代码,您可以轻松快速地学习如何使用它。 which is available here :

我也推荐它,因为它效果很好,而且也没有给我带来任何问题。

【讨论】:

    猜你喜欢
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 2016-01-13
    • 2021-04-06
    相关资源
    最近更新 更多