C#将数据保存到Excel时,数据需要保持原来的类型,而不是简单的分为数字和文本将数据保存。
public static bool SaveByOLEDB(DataTable dt, string path)
{
bool success = true;
string connStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + path + ";Extended Properties=Excel 8.0;";//仅支持2003格式的Excel
OleDbConnection conn = new OleDbConnection(connStr);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
try
{
conn.Open();
string cmdText = "Create Table sheet1 (";
for(int i = 0; i < dt.Columns.Count; i++)
{
string columnName = dt.Columns[i].ColumnName;
cmdText += " "+ columnName;
string typeName =GetExcelMapDataType(dt.Columns[i].DataType.Name);
cmdText += " "+ typeName;
if(i == dt.Columns.Count - 1)
{
cmdText += ")";
}
else
{
cmdText += ",";
}
}
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
for (int i = 0; i < dt.Rows.Count; i++)
{
cmdText = "Insert into sheet1 values (";
for (int j = 0; j < dt.Columns.Count; j++)
{
string columnName = dt.Columns[j].ColumnName;
cmdText += "@" + columnName;
cmd.Parameters.AddWithValue("@" + columnName, dt.Rows[i][columnName]);
if (j == dt.Columns.Count - 1)
{
cmdText += ")";
}
else
{
cmdText += ",";
}
}
cmd = new OleDbCommand(cmdText, conn);
for (int j = 0; j < dt.Columns.Count; j++)
{
string columnName = dt.Columns[j].ColumnName;
string columnType = dt.Columns[j].DataType.Name;
if(columnType.ToLower() == "datetime")
{
OleDbParameter pm = new OleDbParameter();
pm.ParameterName = "@" + columnName;
pm.OleDbType = OleDbType.Date;
pm.Value = dt.Rows[i][columnName];
cmd.Parameters.Add(pm);
continue;
}
cmdText += "@" + columnName;
cmd.Parameters.AddWithValue("@" + columnName, dt.Rows[i][columnName]);
}
cmd.ExecuteNonQuery();
}
}
catch(Exception ex)
{
}
finally
{
conn.Close();
conn.Dispose();
}
return success;
}
一些特殊类型需要转为OLEDB兼容的数据类型。
static string GetExcelMapDataType(string dataType)
{
string result = dataType;
switch (dataType.ToLower())
{
case "int":
case "int32":
result = "INTEGER";
break;
case "datetime":
result = "DATE";
break;
case "boolean":
result = "bit";
break;
default:
break;
}
return result;
}
附Excel的数据类型

在进行转换时OLEDB作为中间层实现了C#数据类型和Excel数据类型的映射,但是C#数据类型转为OLEDB数据类型这儿需要自己处理。
图片截取自:https://www.promotic.eu/en/pmdoc/Subsystems/Db/Excel/DataTypes.htm
