使用OleDB读取Excel文件会以错误的格式返回UPC编号

时间:2014-02-18 12:01:02

标签: c# excel oledb number-formatting oledbconnection

我必须在Web应用程序中使用OleDB读取Excel文件并将数据保存在数据库中。

访问该文件并使用DataAdapter或OleDbDataReader读取它。我需要指定IMEX = 1和TypeGuessRows = 0,因为文件中的数据包含我需要解析的标题,但它们不在第一行。所以基本上,我需要阅读这些行,直到我点击一个已知的标题,然后开始解析它之后的所有数据。

在第一列中有UPC编号,其值如下:5053366261702 但即使字段被读取为文本,OleDbDataReader也会以科学的方式返回数字:5.05337E+12

如果我不将这些行作为文本读取,则会正确返回这些数字,但标题会消失。

我添加了代码的重要部分。在此先感谢您的帮助。

string conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";
using (OleDbConnection objConn = new OleDbConnection(conn))
{
      objConn.Open();
      var exceltables = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
      var tablename = exceltables.Rows[0]["TABLE_NAME"];
      using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "]", objConn))
      {
            using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
            {
                while (reader.Read())
                {
                    string abc = reader[0].ToString(); //do some parsing
                }
            }                    
      }
}

2 个答案:

答案 0 :(得分:1)

我找到了一个适合我的解决方案。我现在用两个不同的连接字符串打开文件。

Provider=Microsoft.ACE.OLEDB.12.0;Data Source='filename.xlsx';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'

首先获取标题,当我找到它们时,我保存行号并再次使用IMEX = 0打开文件。

Provider=Microsoft.ACE.OLEDB.12.0;Data Source='filename.xlsx';Extended Properties='Excel 12.0;HDR=No;IMEX=0;ImportMixedTypes=Text;TypeGuessRows=0'

string connHeaders = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";
string connData = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=0;ImportMixedTypes=Text;TypeGuessRows=0'";

int dataStartRow = 0;
string tablename = "";

#region Open file to find headers
using (OleDbConnection objConn = new OleDbConnection(connHeaders))
{
    objConn.Open();
    var exceltables = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
    tablename = exceltables.Rows[0]["TABLE_NAME"].ToString();
    using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "] ", objConn))
    {
        using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
        {
            while (reader.Read())
            {
                if (reader[0].ToString().ToLower() == "upc")
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        //find all necessary headers
                    }
                    break;
                }
                dataStartRow++;
            }
        }
    }
}
#endregion

#region Open file again to read data
using (OleDbConnection objConn = new OleDbConnection(connData))
{
    objConn.Open();
    using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "] ", objConn))
    {
        using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
        {
            for (int i = 0; i < dataStartRow; i++) reader.Read();
            while (reader.Read())
            {
                //read the line to save it in Database
            }
        }
    }
}

答案 1 :(得分:0)

我有一个简单的答案对我有用。

File.WriteAllText(file, Regex.Replace( File.ReadAllText(file), "(?<=,)([0-9]{12,})(?=,)", "\"$1\""));

之所以起作用,是因为它将科学记号引入时在带有12个或更多数字的任何字段周围加上双引号。