<SCRIPT src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript> </SCRIPT> <IFRAME name=google_ads_frame marginWidth=0 marginHeight=0 src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-0660578626274101&dt=1227798924218&lmt=1227660492&output=html&slotname=5846816625&correlator=1227798924218&url=http%3A%2F%2Fwww.zxbc.cn%2Fhtml%2F20081126%2F68321.html&ea=0&ref=http%3A%2F%2Fwww.zxbc.cn%2Fhtml%2F20081126%2F68321_2.html&frm=0&ga_vid=337886013.1227798924&ga_sid=1227798924&ga_hid=1912940174&flash=10.0.12.36&u_h=800&u_w=1280&u_ah=800&u_aw=1280&u_cd=32&u_tz=480&u_his=1&u_java=true&dtd=16" frameBorder=0 width=300 scrolling=no height=250 allowTransparency></IFRAME> |
因爲現在用到的是winform,對web的解決沒有去關注,所以現在只是對winform操作excel做筆記
以前做考試系統的時候,接觸過excel導入,不過當時不是我負責所以瞭解不多,只是知道在.net中excel可以想其他數據源一樣訪問。
C# 操作Excel分兩種情況
1.利用office組件,就是要安裝office(或者下載dll添加引用也可以,沒試過) 。代碼1
2.不利用office組件,而是用TextWriter的某些子類編寫器將字節流寫入文件,這些文件其實不是真正的excel文件(可以用記事本打開不亂碼),雖然能用excel打開。如果你在把這些導出的文件當作excel數據源,就不行了。
其實還有一種方法雖然不利用office組件不過當導出到excel的時候有有一個事先創建好的excel文件(這樣比用office組件好點,畢竟有別的編譯器可以生成excel文件,不過這樣也只是自欺欺人吧)。這個方法是導出的時候也把已經創建好的excel當做數據源用OleDbCommand.ExecuteNonQuery()等方法寫入excel。我們把這標記爲代碼3,以便下面提供代碼。
相關代碼:
我們先看最後一種方法代碼(我開始用的是這個不上不下的方法)
代碼3
/// <summary>
/// 將DataTable導出爲excel 自動創建excel
/// </summary>
/// <param name="dt"> 數據源</param>
/// <param name="ExcelFileName"> 要保存的excel的name</param>
/// <param name="strWorkSheetName">創建的表的名字 </param>
public static string ExportTable2ExcelFile(DataTable dt, string ExcelFileName, string strWorkSheetName)
{
if (File.Exists(ExcelFileName) == false)
{
return "指定文件不存在!";
}
if (dt == null)
{
return "數據不能爲空!";
}
if (strWorkSheetName.ToString() == "")
{
return "數據表名不可以爲空!";
}
dt.TableName = strWorkSheetName;
int iRows = dt.Rows.Count;
int iCols = dt.Columns.Count;
StringBuilder stringBuilder;
string connString;
if (iRows == 0)
{
return "沒有可導入數據!";
}
stringBuilder = new StringBuilder();
connString = ExcelOperation.GetExcelConnection(ExcelFileName);// "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFileName + ";Extended Properties=Excel 8.0;";
//先查看此Excel中是否有相關Table,如果有的話就刪除,然後導入新的。
//生成創建表的腳本
stringBuilder.Append("CREATE TABLE ");
stringBuilder.Append(dt.TableName + " ( ");
for (int i = 0; i < iCols; i++)
{
//此處是本版本改進中最實用的地方
string strType = ExcelOperation.GetOleDataType(dt.Columns[i]);
if (i < iCols - 1)
stringBuilder.Append(string.Format("{0} {1},", dt.Columns[i].ColumnName, strType));
else
stringBuilder.Append(string.Format("{0} {1})", dt.Columns[i].ColumnName, strType));
}
using (OleDbConnection objConn = new OleDbConnection(connString))
{
OleDbCommand objCmd = new OleDbCommand();
objCmd.Connection = objConn;
//插入新表
objCmd.CommandText = stringBuilder.ToString();
try
{
objConn.Open();
//插入新表
objCmd.ExecuteNonQuery();
}
catch (Exception e)
{
return "在Excel中創建表失敗!錯誤信息:" + e.Message;
}
stringBuilder.Remove(0, stringBuilder.Length);
stringBuilder.Append("INSERT INTO ");
stringBuilder.Append(dt.TableName + " ( ");
//先插入標頭
for (int i = 0; i < iCols; i++)
{
if (i < iCols - 1)
stringBuilder.Append(dt.Columns[i].ColumnName + ",");
else
stringBuilder.Append(dt.Columns[i].ColumnName + ") values (");
}
for (int i = 0; i < iCols; i++)
{
if (i < iCols - 1)
stringBuilder.Append("@" + dt.Columns[i].ColumnName + ",");
else
stringBuilder.Append("@" + dt.Columns[i].ColumnName + ")");
}
//建立插入動作的Command
objCmd.CommandText = stringBuilder.ToString();
OleDbParameterCollection oleParam = objCmd.Parameters;
oleParam.Clear();
for (int i = 0; i < iCols; i++)
{
OleDbType oleDbType = ExcelOperation.GetRefOleDataType(dt.Columns[i]);
//此處是本版本改進中最實用的地方
oleParam.Add(new OleDbParameter("@" + dt.Columns[i].ColumnName, oleDbType));
}
//遍歷DataTable將數據插入新建的Excel文件中
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < oleParam.Count; i++)
{
oleParam[i].Value = row[i];
}
objCmd.ExecuteNonQuery();
}
return "數據已成功導入Excel!";
}
}
/// <summary>
/// 獲取與本地DataSet中指定列的類型對應的OleDbType的數據類型字符串
/// </summary>
/// <param name="dataColumn"></param>
/// <returns></returns>
public static string GetOleDataType(DataColumn dataColumn)
{
switch (dataColumn.DataType.Name)
{
case "String"://字符串
{
return "VarChar";
}
case "Double"://數字
{
return "Double";
}
case "Decimal"://數字
{
return "Decimal";
}
case "DateTime"://時間
{
return "Date";
}
default://
{
return "VarChar";
}
}
}
/// <summary>
/// 獲取與本地DataSet中指定列的類型對應的OleDbType類型
/// </summary>
/// <param name="dataColumn"></param>
/// <returns></returns>
public static OleDbType GetRefOleDataType(DataColumn dataColumn)
{
switch (dataColumn.DataType.Name)
{
case "String"://字符串
{
return OleDbType.VarChar;
}
case "Double"://數字
{
return OleDbType.Double;
}
case "Decimal"://數字
{
return OleDbType.Decimal;
}
case "DateTime"://時間
{
return OleDbType.Date;
}
default:
{
return OleDbType.VarChar;
}
}
}
public static string GetExcelConnection(string strFilePath)
{
if (!File.Exists(strFilePath))
{
throw new Exception("指定的Excel文件不存在!");
}
return
@"Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source=" + strFilePath + ";" +
@"Extended Properties=" + Convert.ToChar(34).ToString() +
@"Excel 8.0;" + "Imex=2;HDR=Yes;" + Convert.ToChar(34).ToString();
}
2.不利用office組件,而是用TextWriter的某些子類編寫器將字節流寫入文件。
這個提供一個類庫的使用吧,就不發代碼了4百多行,可以到下面的網址去下。項目是vs2003做的要轉換下然後把RKLib.ExportData.dll複製到bin下引用(或直接引用)然後就可以直接用了
導出到excel的代碼: RKLib.ExportData.Export objExport = new RKLib.ExportData.Export("Win");
objExport.ExportDetails(dt, Export.ExportFormat.Excel, saveFileDialog1.FileName);
這個還提供了web導出和CSV格式導出。