Excel 使用 SqlBulkCopy 在 asp.net 上传文件

Excel File upload in asp.net using SqlBulkCopy

我正在使用以下 code.It 在 asp.net c# 中上传 excel 文件工作正常,但问题是在 excel 文件中某些列值始终是数字,如果其中一些数值是文本格式,然后它正在上传空值。这是我的代码 - 请提出任何建议。

if (!Convert.IsDBNull(FileUpload.PostedFile) &
    FileUpload.PostedFile.ContentLength > 0)
{
    //FIRST, SAVE THE SELECTED FILE IN THE ROOT DIRECTORY.
    FileUpload.SaveAs(Server.MapPath(".") + "\" + FileUpload.FileName);
    //  File.Delete(Server.MapPath(FileUpload.FileName));
    SqlBulkCopy oSqlBulk = null;

    // SET A CONNECTION WITH THE EXCEL FILE.
    OleDbConnection myExcelConn = new OleDbConnection(
        "Provider=Microsoft.ACE.OLEDB.12.0; " +
        "Data Source=" + Server.MapPath(".") + "\" + FileUpload.FileName +
        ";Extended Properties=Excel 12.0;");
    try
    {
        myExcelConn.Open();

        // GET DATA FROM EXCEL SHEET.
        OleDbCommand objOleDB =
            new OleDbCommand("SELECT SSS.*,'" + Session["vUserName"].ToString() + "' FROM [Sheet1$] SSS", myExcelConn);

        // READ THE DATA EXTRACTED FROM THE EXCEL FILE.
        OleDbDataReader objBulkReader = null;
        objBulkReader = objOleDB.ExecuteReader();

        // SET THE CONNECTION STRING.
        // con = new SqlConnection(dbcon);

        using (con = new SqlConnection(dbcon))
        {
            con.Open();

            // FINALLY, LOAD DATA INTO THE DATABASE TABLE.
            oSqlBulk = new SqlBulkCopy(con);
            oSqlBulk.DestinationTableName = "tmpStuffing"; // TABLE NAME.

            oSqlBulk.WriteToServer(objBulkReader);
        }

        lblConfirm.Text = "DATA IMPORTED SUCCESSFULLY.";
        lblConfirm.Attributes.Add("style", "color:green");
    }
    catch (Exception ex)
    {
        lblConfirm.Text = ex.Message;
        lblConfirm.Attributes.Add("style", "color:red");
    }
    finally
    {
        // CLEAR.
        oSqlBulk.Close();
        oSqlBulk = null;
        myExcelConn.Close();
        myExcelConn = null;
    }
}

欢迎来到处理 Excel 怪癖的有趣和令人兴奋的世界,以及为什么使用 Excel 电子表格作为数据源是个坏主意。遗憾的是,您需要做更多的工作才能正常工作。

您需要检查每一行并对每一列执行适当的类型转换。最简单的可能是将源数据读入 DataTable 并将其传递给 WriteToServer 方法。

所以...创建一个兼容的 DataTable 并通过使用 Read() 推进和各种 Get*() 方法遍历 Ole IDataReader 实例来填充它现场数据。当它读取数字失败时,因为它是一个字符串,使用 Int32.TryConvert(...) 或类似的方法将字符串转换为正确的数字格式。一旦到达数据末尾(Read() returns false),DataTable 就可以使用 SqlBulkCopy 转储到 SQL 服务器,方法与你在上面做的。

一个快捷方式是使用 as 关键字检测类型错误,并使用 ?? 空合并运算符调用类型转换:

int? num = (reader.Item[1] as int?) ?? ParseInt(reader.GetString(1));

或者,如果可能,您可以使用扩展方法进行转换:

public static int? AsInt32(this IDataReader rdr, int index)
{
    Type ft = rdr.GetFieldType(index);
    if (ft == typeof(int))
        return rdr.GetInt32(index);
    else if (ft == typeof(string))
    {
        int v;
        if (Int32.TryParse(rdr.GetString(index), out v))
            return v;
    }
    else if (ft == typeof(object))
    {
        object fv = rdr.GetValue(index);
        int? v = fv as int?;
        if (v != null)
            return v.Value;
    }

    return null;
}

AsString 添加一个类似的(这相当简单),您可以使用如下方法将 Excel IDataReader 转换为 DataTable

public DataTable ImportData(IDataReader reader)
{
    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(int));
    table.Columns.Add("UserName", typeof(string));

    int rownum = 0;
    while (reader.Read())
    {
        ++rownum;
        int? id = reader.AsInt32(0);
        if (id == null)
            throw new Exception(string.Format("Invalid ID on row {0}, value: {1}", rownum, reader.GetValue(0)));

        string name = reader.AsString(1);

        table.Rows.Add(id.Value, name);
    }

    return table;
}

您好,我已经解决了更改现有代码中以下部分的问题。

"Provider=Microsoft.ACE.OLEDB.12.0; " +
                      "Data Source=" + Server.MapPath(".") + "\" + FileUpload.FileName +
                      ";Extended Properties='Excel 12.0;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0';"

我认为 IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0' 可以导入混合数据类型。

谢谢