C# 从Excel导入:某些单元格变为空

C# 从Excel导入:某些单元格变为空,c#,asp.net,excel,C#,Asp.net,Excel,我正在从excel文件导入数据,我刚刚注意到导入后一些单元格变为“” 这是我正在使用的代码 FileUploadExcel.SaveAs("C:\\datatop.xls"); string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\1.xls;Extended Properties=Excel 8.0;";

我正在从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();
                }
问题列为
数量
,包含:

12
14
15
11
19k/yr
4
2
导入后,它将成为我的gridview上的一个空间。所有其他单元格在gridview上都显示得很好

GridView中的输出:

12
14
15
11

4
2

有什么想法吗?

在使用OLEDB和Excel时,列的数据类型由每列中的前几项决定。在您的例子中,列中的前几项是数字,因此它假定该列的类型为
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]);
}
使用Microsoft.Office.Interop.Excel;
使用Sd=系统数据;
专用void FillTableData(Sd.DataTable、工作表、范围单元格)
{
使用(var com=new ComObjectManager())
{
var firstCell=GetFirstCell(com,cells);
var beginCell=com.Get(()=>(范围)cells.Item[2,1]);
var endCell=GetLastContinguousCell(com、cells、firstCell);
if(beginCell.Value==null)返回;
var range=GetRange(com、cells、beginCell、endCell);
变量数据=(对象[,])range.Value;
var rowCount=data.GetLength(0);
对于(var rowIndex=0;rowIndex(范围)cells.Item[1,1]);
}
专用范围GetLastContinguousCell(ComObjectManager com、范围单元格、范围beginCell)
{
var bottomCell=com.Get(()=>beginCell.End[XlDirection.xlDown]);
var rightCell=com.Get(()=>beginCell.End[XlDirection.xlToRight]);
返回com.Get(()=>(范围)cells.Item[bottomCell.Row,rightCell.Column]);
}
COM对象管理器-确保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());
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Runtime.InteropServices;
公共类共对象管理器:IDisposable
{
私有堆栈_comObjects=新堆栈();
公共TComObject Get(Func getter)
{
var comObject=getter();
_comObject.Push(comObject);
返回共对象;
}
公共空间处置()
{
而(_comObjects.Count>0)
Marshal.ReleaseComObject(_comObject.Pop());
}
}
@Pod-Mays 相反,您可以使用第三方DLL与excel一起进行许多操作,而且使用它非常容易

另外,通过使用它附带的源代码,您可以轻松快速地学习如何使用它


我也推荐它,因为它工作得非常好,也没有给我带来任何问题。

您的一些代码被切断了吗?我没有得到
1.Text
2.Text
@DanM是的,我编辑了它,谢谢。如果你能编辑你的Excel文件,试着在19k/年之前加一个撇号(')。@DanM它仍然不显示Mate哦,我知道问题出在哪里。看看我的答案。谢谢你,伙计。但还有别的办法吗?因为我要导入将近一百个excel文件,编辑它们非常繁琐。另外一种可能是使用excel互操作。只有在安装了Office的机器上工作时,这才有效,但如果安装了Office,它比OLEDB提供了更大的灵活性。我将用一些示例代码更新我的答案。