public void Create( string mdbPath ){if( File.Exists(mdbPath) ) //檢查數據庫是否已存在{throw new Exception( "目標數據庫已存在,無法創建 ");}// 可以加上密碼,這樣創建后的數據庫必須輸入密碼后才能打開mdbPath = "PRovider=Microsoft.Jet.OLEDB.4.0;Data Source= " + mdbPath;// 創建一個CatalogClass對象的實例,ADOX.CatalogClass cat = new ADOX.CatalogClass();// 使用CatalogClass對象的Create方法創建ACCESS數據庫cat.Create(mdbPath);}///壓縮修復ACCESS數據庫,mdbPath為數據庫絕對路徑public void Compact( string mdbPath ){if( !File.Exists(mdbPath) ) //檢查數據庫是否已存在{throw new Exception( "目標數據庫不存在,無法壓縮 ");}//聲明臨時數據庫的名稱string temp = DateTime.Now.Year.ToString();temp += DateTime.Now.Month.ToString();temp += DateTime.Now.Day.ToString();temp += DateTime.Now.Hour.ToString();temp += DateTime.Now.Minute.ToString();temp += DateTime.Now.Second.ToString() + ".bak ";temp = mdbPath.Substring(0, mdbPath.LastIndexOf( "http:// ")+1) + temp;//定義臨時數據庫的連接字符串string temp2 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + temp;//定義目標數據庫的連接字符串string mdbPath2 = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + mdbPath;//創建一個JetEngineClass對象的實例JRO.JetEngineClass jt = new JRO.JetEngineClass();//使用JetEngineClass對象的CompactDatabase方法壓縮修復數據庫jt.CompactDatabase( mdbPath2, temp2 );//拷貝臨時數據庫到目標數據庫(覆蓋)File.Copy( temp, mdbPath, true );//最后刪除臨時數據庫File.Delete( temp );}/// 備份數據庫,mdb1,源數據庫絕對路徑; mdb2: 目標數據庫絕對路徑public void Backup( string mdb1, string mdb2 ){if( !File.Exists(mdb1) ){throw new Exception( "源數據庫不存在 ");}try{File.Copy( mdb1, mdb2, true );}catch( IOException ixp ){throw new Exception(ixp.ToString());}}///恢復數據庫,mdb1為備份數據庫絕對路徑,mdb2為當前數據庫絕對路徑public void Recover( string mdb1, string mdb2 ){if( !File.Exists(mdb1) ){throw new Exception( "備份數據庫不存在 ");}try{File.Copy( mdb1, mdb2, true );}catch( IOException ixp ){throw new Exception(ixp.ToString());}}============================================================================================================使用ADOX創建Access數據庫和表using System;using ADOX;namespace WebPortal{/// <summary>/// CreateAccessDB 的摘要說明。/// 對于不同版本的ADO,需要添加不同的引用 /// 請添加引用Microsoft ADO Ext. 2.7 for DDL and Security /// 請添加引用Microsoft ADO Ext. 2.8 for DDL and Security/// </summary>public class CreateAccessDB : System.Web.UI.Page{ private void Page_Load(object sender, System.EventArgs e) { //為了方便測試,數據庫名字采用比較隨機的名字,以防止添加不成功時還需要重新啟動IIS來刪除數據庫。 string dbName = "D://NewMDB"+DateTime.Now.Millisecond.ToString()+".mdb"; ADOX.CatalogClass cat = new ADOX.CatalogClass(); cat.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbName +";"); Response.Write("數據庫:" + dbName + "已經創建成功!"); ADOX.TableClass tbl = new ADOX.TableClass(); tbl.ParentCatalog = cat; tbl.Name="MyTable"; //增加一個自動增長的字段 ADOX.ColumnClass col = new ADOX.ColumnClass(); col.ParentCatalog = cat; col.Type=ADOX.DataTypeEnum.adInteger; // 必須先設置字段類型 col.Name = "id"; col.Properties["Jet OLEDB:Allow Zero Length"].Value= false; col.Properties["AutoIncrement"].Value= true; tbl.Columns.Append (col,ADOX.DataTypeEnum.adInteger,0); //增加一個文本字段 ADOX.ColumnClass col2 = new ADOX.ColumnClass(); col2.ParentCatalog = cat; col2.Name = "DescrExcel,問題轉化成了Excel怎么樣轉成Access,這點實現起來相對來說比較容易,office本身就有這個功能,但問題是,從web頁面導出的Excel不能很兼容的導成Access,這是一點,還有一個方面是讓客戶去做這個轉化工作不是太好,為了提高用戶體驗,最好是用代碼實現了。能不能一下子轉成Access出來呢?這是我一下想的的問題,如果有的話,客戶就省很多力氣了,但找了一些相關資料,沒有找到把GridView直接導成Access的,也就是客戶端比較難實現。想到這里,客戶端難實現,服務端應該好實現吧,先把我數據庫中的數據轉化成一個access的文件,然后客戶再下載下來,這個相對來說比較容易實現。主要思路:在服務端,把一種數據中的數據,生成access文件,下載給客戶商。分步實現:第一:創建Access文件第二:復制數據庫格式,在Access文件中創建新表第三:復制數據到Access文件中第四:實現下載創建Access文件原本創建Access文件的語法比較簡單首先引入命名空間using ADOX; 該命名空間位于Interop.ADOX.dll文件中,ADOX.CatalogClass cat = new ADOX.CatalogClass();cat.Create(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/Data.mdb;");這樣,就能在指定的D盤下創建一個Data.mdb的Access文件。文件是創建好了,但引來了后續的一些問題,因為我們在實現下載時,要用到Response.WriteFile(文件),此時的Response.WriteFile()要求是獨立享有這個文件操作權限,但前期創建時的進程一直釋放不掉(如果誰有好的方法可以告我如何釋放),這里還得考慮多人操作,有可能同時有多要在創建Access文件或釋放這個文件。這樣就會出現運行時錯誤,提示該文件被其他進程獨占。為了解決這個問題,同時還涉及到防止進程的釋放帶來的其他問題,這里我捌了一下彎來實現,先創建一個Data.mdb存放在網站的App_Data文件夾下,后期所有客戶端要下導出Access表,都在這里拷貝一份,然后對新文件進行操作。另外再新建一個DownLoad文件夾用來存用戶下載的Access文件。代碼如下://拷貝Access數據表,不移動string newfile=DateTime .Now.ToString ("MMddhhmmss")+".mdb";File.Copy(Server.MapPath("~") + @"/App_Data/data.mdb", Server.MapPath("~") + @"/App_Data/" + newfile);復制數據庫格式,在Access文件中創建新表在這里,我是從SQL Server中生表生成Access的表,當然,可以用相關的工具完成些功能,但如果對方的數據庫不是SQL Server可能就不太好用了。這里選擇SQL Server只是一種演示數據庫。我們知道,創建一張表有幾個要素,表名,字段名,字段類型,字段大小,這里,我們得先從SQL Server中查出該表的這些要素,然后創建Access表,如果是其他數據庫,就要相應的轉化一下對應的數據類型格式。代碼實現如下:在web.config中創建兩個連接字符串<add name="AccessConStr" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|/data.mdb;Persist Security Info=True;" providerName="System.Data.OleDb"/><add name="SqlConStr" connectionString="server=.;database=cum_data;uid=sa;pwd=sa;" providerName="System.Data.SqlClient"/>這兩個字符,一個用來連接SQL Server數據庫一個用來連接我們創建的Access數據庫。接來查看導庫的代碼:string SqlConstr = ConfigurationManager.ConnectionStrings["SqlConStr"].ConnectionString;string sql = "select column_name,data_type,character_maximum_length from information_schema.columns where table_name='kh'";SqlConnection con = new SqlConnection(SqlConstr);SqlCommand cmd = new SqlCommand(sql, con);string AccSql = "";//用來組合生成Access表的SQL語句try{con.Open();SqlDataReader DR = cmd.ExecuteReader();while (DR.Read()){if (DR.GetValue(2).ToString() == ""){AccSql += DR.GetValue(0).ToString() + " " + DR.GetValue(1).ToString() + ",";}else{AccSql += DR.GetValue(0).ToString() + " " + DR.GetValue(1).ToString() + "(" + DR.GetValue(2).ToString() + "),";}}}catch{ }finally{con.Close();}AccSql = AccSql.Substring(0, AccSql.Length - 1);string AccConstr = ConfigurationManager.ConnectionStrings["AccessConStr"].ConnectionString.Replace ("data.mdb",newfile );OleDbConnection CON = new OleDbConnection(AccConstr);OleDbCommand CMD = new OleDbCommand();CMD.Connection = CON;try{CON.Open();CMD.CommandText = "create table kh(" + AccSql + ")";CMD.ExecuteNonQuery();}catch{ }finally{CON.Close();}在上述代碼中,SQL語句是比較關鍵的,“select column_name,data_type,character_maximum_length from information_schema.columns where table_name='kh'”,本SQL查詢語句是從把原表的字段名,字段類型,字段大小查詢出來,當然,不同的數據庫,這個語句不近相同。復制數據到Access文件中到現在,我們已創建好了數據表格式,接下來,就是要把數據導到Access中。代碼如下:SqlDataAdapter DA = new SqlDataAdapter("select * from kh", SqlConstr);DataTable DT = new DataTable();DA.Fill(DT);foreach (DataRow DRR in DT.Rows){DRR.SetAdded();}OleDbDataAdapter ODA = new OleDbDataAdapter("select * from kh", AccConstr);OleDbCommandBuilder cmb = new OleDbCommandBuilder(ODA);ODA.Update(DT);這里用到了Adapter的一個方法,Update,可以把DataTable中RowState為Add的數據提交會數據庫,這樣做起來相對要省力些。在里,要把有數據的Access文件,移動到DownLoad文件夾下File.Move(Server.MapPath("~") + @"/App_Data/"+newfile , Server.MapPath("~") + @"/DownLoad/" + newfile);實現下載Response.Clear();Response.ClearHeaders();Response.Charset = "utf-8";Response.Buffer = false ;this.EnableViewState = false;Response.ContentType = "application/vnd.openxmlformats-officedocument.Wordprocessingml.document";Response.ContentEncoding = System.Text.Encoding.UTF8;Response.AppendHeader("Content-Disposition", "attachment;filename=" + newfile);Response.WriteFile(Server.MapPath("~") + @"/DownLoad/" + newfile ,true );Response.Flush();Response.Close();Response.End();下載代碼是通用的代碼,這里不作說明。整個解決方案就是把文件操作,數據操作,文件下載有機的結合在一起,實現這個用戶下載Access文件的需求。其實有時候我們去實現一個問題的時候,總體是有一定難度的,但當我們想辦法,通過分解問題來實現的時候,相對來說就比較簡單的實現了。
新聞熱點
疑難解答