问题描述
我想用C#实现将excel表中的数据导入到access数据库的a表中.在导入时,我想让数据库中接受excel数据的那张表(a表)的列名自动创建,而不用手动创建.请问上述问题的实现思路.谢谢.
解决方案
解决方案二:
在access里写脚本。access除了数据库,还内含VB的脚本功能,可惜我们大多数人都没研究过,里面可以实现一切access菜单里的功能,包括你想要的导入。
解决方案三:
usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Data.OleDb;usingSystem.Data;usingSystem.Windows.Forms;usingMicrosoft.Office.Interop.Excel;namespaceLandaControl7_ValidateExcel{///<summary>///读取Excel///</summary>classExcelForCheck{#region通用读取Excel(多表读取,一次读取,集中处理)/**http://www.qudong.com/soft/program/asp/asp-netshili/20080317/1169.html*对于MicrosoftExcel8.0(97)、9.0(2000)、10.0(2002)和11.0(2003)工作簿,请使用Excel8.0。*对于MicrosoftExcel5.0和7.0(95)工作簿,请使用Excel5.0。*对于MicrosoftExcel4.0工作簿,请使用Excel4.0。*对于MicrosoftExcel3.0工作簿,请使用Excel3.0。*Provider=Microsoft.Jet.OLEDB.4.0;ExtendedProperties="Excel8.0;HDR=NO";datasource="+xlsPath;*如果希望第一行作为数据显示,而非列名,可以在连接串的ExtendedProperties属性指定:HDR=NO,*注意:Excel8.0;HDR=NO需要使用双引号(这里的反斜扛,是C#中的转义)*可以通过ExtendedProperties中指定IMEX=1,"IMEX=1;"通知驱动程序始终将“互混”数据列作为文本读取*有网友说,将每个单元都加上引号,这固然是个方案,但是工作量何其大啊,又不零活,庆幸找到"治本药方"**这里我们就不需要对SELEC语句进行“硬编码”,可以根据需要动态的构造FROM字句的“表名”。*不仅可以,获取表明,还可以获取每张表内的字段名、字段类型等信息:*tblSchema=conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,newobject[]{null,null,null,null});*在ADO.nET1.x时候只有OleDb提供了GetOleDbSchemaTable方法,而SqlClient或者OrcaleClient没有对应的方法,*因为对应数据库已经提供了类似功能的存储过程或者系统表供应用程序访问,比如对于SqlServer:*SELECT*FROMNorthwind.INFORMATION_SCHEMA.COLUMNSWHERETABLE_NAME=N'Customers'**HDR用来设置是否将Excel表中第一行作为字段名,“YES”代表是,“NO”代表不是即也为数据内容;*IMEX是用来告诉驱动程序使用Excel文件的模式,其值有0、1、2三种,分别代表导出、导入、混合模式**HKEY_LOCAL_MACHINESOFTWAREMicrosoftJet4.0EnginesExcel”下的该注册表值来更改采样行数。*但是这种改进还是没有根本上解决问题,即使我们把IMEX设为“1”,TypeGuessRows设得再大,例如1000,假设数据表有1001行,某列前1000行全为纯数字,*该列的第1001行又是一个文本,ISAM驱动的这种机制还是让这列的数据变成空**/publicDataSetExcelReader(stringexcelName){DataSetds=newDataSet();OleDbConnectionconn=null;try{//拼写连接字符串,打开连接stringstrConn="Provider=Microsoft.Jet.OleDb.4.0;"+"datasource="+excelName+";ExtendedProperties='Excel8.0;HDR=YES;IMEX=1'";conn=newOleDbConnection(strConn);conn.Open();//取得Excel工作簿中所有工作表System.Data.DataTableschemaTable=conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,null);//获取Excel中的对应表名称//System.Data.DataTablecolTable=conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,null);//获取Excel中的对应列名称OleDbDataAdaptersqlada=newOleDbDataAdapter();//遍历工作表取得数据并存入Datasetforeach(DataRowdrinschemaTable.Rows){stringstrSql="Select*From["+dr[2].ToString().Trim()+"]";OleDbCommandobjCmd=newOleDbCommand(strSql,conn);sqlada.SelectCommand=objCmd;sqlada.Fill(ds,dr[2].ToString().Trim());}}catch{returnnull;}finally{if(conn.State!=ConnectionState.Closed&&conn!=null){conn.Close();//KillProcess("excel");}}returnds;}#endregion#region指定文件名[Sheet1$]导出publicDataSetGetDataFromExcel(stringfilePath){//DataSetmyDataSet=newDataSet();////创建一个数据链接////stringstrCon="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=c:\sample.xls;ExtendedProperties=Excel8.0";//stringstrCon="Provider=Microsoft.Jet.OLEDB.4.0;DataSource="+filePath+";ExtendedProperties=Excel8.0;HDR=NO;IMEX=1";//OleDbConnectionmyConn=newOleDbConnection(strCon);//stringstrCom="SELECT*FROM[Sheet1$]";////myConn.Open();////打开数据链接,得到一个数据集//OleDbDataAdaptermyCommand=newOleDbDataAdapter(strCom,myConn);////创建一个DataSet对象//myDataSet=newDataSet();////得到自己的DataSet对象//myCommand.Fill(myDataSet);////myCommand.Fill(myDataSet,"[Sheet1$]");////关闭此数据链接////myConn.Close();//returnmyDataSet;stringstrCon="Provider=Microsoft.Jet.OLEDB.4.0;DataSource="+filePath+";ExtendedProperties=Excel8.0";System.Data.OleDb.OleDbConnectionconn=newSystem.Data.OleDb.OleDbConnection(strCon);stringsql="Select*FROM[Sheet1$]";System.Data.OleDb.OleDbDataAdapteradp=newSystem.Data.OleDb.OleDbDataAdapter(sql,conn);DataSetdss=newDataSet();adp.Fill(dss,"[Sheet1$]");returndss;}#endregion#region从指定行处读取ExcelpublicvoidReadExcel(stringsExcelFile,System.Windows.Forms.DataGridViewdgBom){System.Data.DataTableExcelTable;DataSetds=newDataSet();//Excel的连接OleDbConnectionobjConn=newOleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;DataSource="+sExcelFile+";"+"ExtendedProperties=Excel8.0;");objConn.Open();System.Data.DataTableschemaTable=objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables,null);stringtableName=schemaTable.Rows[0][2].ToString().Trim();//获取Excel的表名,默认值是sheet1stringstrSql="select*from["+tableName+"]";OleDbCommandobjCmd=newOleDbCommand(strSql,objConn);OleDbDataAdaptermyData=newOleDbDataAdapter(strSql,objConn);myData.Fill(ds,tableName);//填充数据dgBom.DataSource=ds;objConn.Close();ExcelTable=ds.Tables[tableName];intiColums=ExcelTable.Columns.Count;//列数intiRows=ExcelTable.Rows.Count;//行数//定义二维数组存储Excel表中读取的数据string[,]storedata=newstring[iRows,iColums];for(inti=0;i<ExcelTable.Rows.Count;i++)for(intj=0;j<ExcelTable.Columns.Count;j++){//将Excel表中的数据存储到数组storedata[i,j]=ExcelTable.Rows[i][j].ToString();}intexcelBom=0;//记录表中有用信息的行数,有用信息是指除去表的标题和表的栏目,本例中表的用用信息是从第三行开始//确定有用的行数for(intk=2;k<ExcelTable.Rows.Count;k++)if(storedata[k,1]!="")excelBom++;if(excelBom==0){//Response.Write("<scriptlanguage=javascript>alert('您导入的表格不合格式!')</script>");}else{//LoadDataToDataBase(storedata,excelBom)//该函数主要负责将storedata中有用的数据写入到数据库中,在此不是问题的关键省略}}#endregion#region杀死Excel进程,okprivatevoidKillProcess(stringprocessName){System.Diagnostics.Processmyproc=newSystem.Diagnostics.Process();//得到所有打开的进程try{foreach(System.Diagnostics.ProcessthisprocinSystem.Diagnostics.Process.GetProcessesByName(processName)){thisproc.Kill();}}catch(ExceptionExc){thrownewException("",Exc);}}#endregion}}
解决方案四:
到网上搜ADOX,ADODB,有源码,直接拿来使用,建库建表不需几行代码即可实现都是COM组件,要添加引用
解决方案五:
感谢楼上的代码提示针对代码,我有一个问题就是楼上省略的部分:LoadDataToDataBase(storedata,excelBom)//该函数主要负责将storedata中有用的数据写入到数据库中,在此不是问题的关键省略我想明白如何操作,能把数组storedata中的数据放入到数据库当中呢?谢谢!
解决方案六:
引用1楼bwangel的回复:
在access里写脚本。access除了数据库,还内含VB的脚本功能,可惜我们大多数人都没研究过,里面可以实现一切access菜单里的功能,包括你想要的导入。
这个是VBAAccess可以写,excel也可以写。
解决方案七:
我现在不是很明白在C#中如何将Dataset中得到的excel表数据放入数据库的相应表中.就是上面例子中的用数组storedata取得的有效数据导入数据库的具体过程.请高手指点一下.谢谢!