2012-10-09 75 views
2

我試圖從sql導出數據行到excel,但我的插入命令似乎每次都失敗。我花了很多時間試圖創造這個,但我終於碰壁了。使用OleDb寫入excel

excel文檔是由IRS生成的,我們沒有大聲修改第16行以上的內容。第16行是標題行,下面的所有內容都需要來自sql的數據。標題名稱中都有空格,這似乎是我遇到麻煩的地方。

在行16列名起爲: 與會者名字,與會者姓氏,與會者PTIN,程序號,授予程序CE小時,完成日期

這是我在嘗試寫脫穎而出

private void GenerateReport() 
{ 
    FileInfo xlsFileInfo = new FileInfo(Server.MapPath(CE_REPORTS_PATH + CE_PTIN_TEMPLATE + EXTENSION)); 

    string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes'", xlsFileInfo.FullName); 

    //create connection 
    OleDbConnection oleDBConnection = new OleDbConnection(connectionString); 
    oleDBConnection.Open(); 

    //create the adapter with the select to get 
    OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$A16:F16]", oleDBConnection); 

    // Create the dataset and fill it by using the adapter. 
    DataTable dataTable = new DataTable(); 
    adapter.FillSchema(dataTable, SchemaType.Source); 
    adapter.Fill(dataTable); 

    string[] colNames = new string[dataTable.Columns.Count]; 
    string[] colParms = new string[dataTable.Columns.Count]; 

    for (int i = 0; i < dataTable.Columns.Count; i++) 
    { 
     colNames[i] = String.Format("[{0}]", dataTable.Columns[i].ColumnName); 
     colParms[i] = "?"; 
    } 

    // Create Insert Command 
    adapter.InsertCommand = new OleDbCommand(String.Format("INSERT INTO [Sheet1$] ({0}) values ({1})", string.Join(",", colNames), string.Join(",", colParms)), oleDBConnection); 

    // Create Paramaters 
    for (int i = 0; i < dataTable.Columns.Count; i++) 
    { 
     OleDbParameter param = new OleDbParameter(String.Format("@[{0}]", dataTable.Columns[i].ColumnName), OleDbType.Char, 255, dataTable.Columns[i].ColumnName); 
     adapter.InsertCommand.Parameters.Add(param); 
    } 

    // create a new row 
    DataRow newCERecord = dataTable.NewRow(); 

    // populate row with test data 
    for (int i = 0; i < dataTable.Columns.Count; i++) 
    { 
     newCERecord[i] = "new Data"; 
    } 
    dataTable.Rows.Add(newCERecord); 

    // Call update on the adapter to save all the changes to the dataset 
    adapter.Update(dataTable); 

    oleDBConnection.Close();  
} 

我得到的錯誤發生在adapter.Update(dataTable中)被稱爲是如下

$exception {"The INSERT INTO statement contains the following unknown field name: 'Attendee First Name'. Make sure you have typed the name correctly, and try the operation again."} System.Exception {System.Data.OleDb.OleDbException} 

釷是令人沮喪的,因爲我直接從colNames [i] = String.Format(「[{0}]」,dataTable.Columns [i] .ColumnName)獲得的列名稱中提取每個字段。我發現我需要[]來解釋列名中的空格,但在這一點上,我不確定問題是什麼。當我看着excel文件時,一切似乎對我都是正確的。

+0

您尚未設置clientsAdapter的UpdateCommand屬性。從我能看到的..我看到它設置爲插入,看看這個StackOverFlow帖子,看看這是否有助於你http://stackoverflow.com/questions/10535663/how-do-i-update-excel-file-with-oledbdataadapter-updatemydataset – MethodMan

+0

我不更新,而是插入到Excel文件中。這個想法是,測試行將出現在Excel文件的下一個。 – Siegeon

+0

你仍然可以按照相同的例子少更新..hope這有助於 – MethodMan

回答

4

我實際上找到了一個微軟的文章,裏面有完整的代碼 - 你可能會複製&粘貼你最喜歡的解決方案。這裏的鏈接:

http://support.microsoft.com/kb/306023

這似乎是一個與CopyRecordset是你的最簡單的方法,雖然他們做解釋一個我提到(使用製表符分隔的文件)。

編輯:這是我最初的答案,爲了完整起見。請參閱上面的鏈接,瞭解更多詳細信息和更好的解決方案。

這不是你的問題的答案,而是一個改變你的方法(如果可以的話)的建議。通過COM調用添加數據時,Excel往往非常緩慢,我假定OleDB在內部使用COM。根據我的經驗,將數據輸出到Excel的最快(並且最巧妙的方式)是生成一個帶有所有數據的製表符分隔的文本文件,然後只將該文件導入到Excel中,並使用COM互操作在表單上執行任何格式化。當我以這種方式生成Excel報表時,我的大多數報表生成的速度幾乎比使用Excel COM對象模型快100倍。 (我不知道這對OleDB調用是否是相同的,因爲我從來沒有使用OleDB和Excel,但我願意打賭OleDB適配器在內部使用COM。)

這也會照顧您的嵌入式空間問題,因爲選項卡將是列分隔符。

在您的特定情況下,我會將文本文件導入Excel到新工作表中,然後複製&將其粘貼到IRS工作表的正確位置。完成後,可以刪除臨時工作表。

+0

或導出到XML然後用它作爲數據源 – Jesse

+0

@Jesse是的,XML也可以。 – xxbbcc

+0

結局都很重要,但我不熟悉這個過程。 – Siegeon

0

數據庫表中的字段名稱是什麼?你可以提及他們與Excel頭列名稱?

+0

數據庫表中的字段名稱與Excel文件中的字段名稱相同,但是對於此示例,我只是使用測試字符串而不是字段名稱 – Siegeon