通过OleDb将数据保存到Excel
在这里有一点需要注意的就是 文件是会自动创建的。如果预先创建出一个以xls结尾的文件会出现异常。
要让程序自动的创建文件 一定要主要连接字符串的拼写。
private const string CONN_STRING = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=no;IMEX=0'";
上面的连接字符串在使用时传入具体的路径即可。
protected override void Save(IReportData data, Data.IColumnMappingCollection mappings,
string path)
{
StringBuilder fieldString = new StringBuilder();
StringBuilder fieldParamStr = new StringBuilder();
StringBuilder fieldStringNovar = new StringBuilder();
using (OleDbConnection conn = new OleDbConnection(string.Format(ObjectUtil.SysCulture, CONN_STRING, path)))
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
conn.Open();
foreach (var col in mappings.ColumnMappings)
{
fieldString.Append(",").Append("[").Append(col.DisplayName).Append("] ").
Append(ToOledbType(col.DataType).ToString());
fieldStringNovar.Append(",").Append("[").Append(col.DisplayName).Append("]");
fieldParamStr.Append(",@").Append(col.FieldName);
cmd.Parameters.Add(new OleDbParameter(col.FieldName, OleDbType.VarChar));
}
cmd.CommandText = string.Format(ObjectUtil.SysCulture, "CREATE TABLE {0} ({1})", "Sheet1",
fieldString.ToString().Substring(1));
cmd.ExecuteNonQuery();
cmd.CommandText = string.Format(ObjectUtil.SysCulture, "INSERT INTO {0} ({1}) VALUES ({2})",
"Sheet1", fieldStringNovar.ToString().Substring(1),
fieldParamStr.ToString().Substring(1));
foreach (var row in data.Rows)
{
foreach (var col in mappings.ColumnMappings)
{
if (row[ReportUtil.GetDisplayFieldName(col)] == DBNull.Value)//row[col.FieldName]
cmd.Parameters[col.FieldName].Value = DBNull.Value;
else
{
if (col.DataType == XmlDataType.DateTime || col.DataType == XmlDataType.Date)
{
DateTime dateTime;
if (DateTime.TryParse(row[ReportUtil.GetDisplayFieldName(col)].ToString(),
out dateTime))
cmd.Parameters[col.FieldName].Value = dateTime.ToShortDateString();
else
cmd.Parameters[col.FieldName].Value = DBNull.Value;
}
else
cmd.Parameters[col.FieldName].Value = row[ReportUtil.GetDisplayFieldName(col)];
}
//cmd.Parameters[col.FieldName].Value = row[col.FieldName] ==
// DBNull.Value ? " " : row[ReportUtil.GetDisplayFieldName(col)].ToString();
}
cmd.ExecuteNonQuery();
}
}
}
上面的方法做了日期类型的转换。感觉应该会有更好的办法。希望高人指点。这里在插入数据时 没有清除 parameters
而是为parameters 重新赋值。同样是可行的。有一个问题希望知道的大哥说一声:为什么comand对象要using起来,他到底使用了什么非托管资源? 上面所遍历的对象不是大家常见的dataset 什么时候有空重新整一个常用的。对了还要特别注意一点就是字段要用[]包括,这是一个很好的习惯。有时异常就是这个原因。