当前位置:首页 >> 机械/仪表 >>

C#操作EXCEL


C#操作 EXCEL 下面代码是几年前初做项目写的代码,没加整理,仅供基础参考呵呵 using System; using System.IO; using System.Reflection; using System.Collections ; using Excel; using System.Data ; using System.Data.OleDb ; using S

ystem.Runtime.InteropServices ; namespace Business.Common { //操作 Excel 的接口 public interface ExcelInterface { //把 Excel 中的数据导入具体的物理表中(单表) bool InDataFromExcelColumns( OleDbConnection conn , string tableName ,string [] tableColsName ,string excelFilePath ,string [] excelColsName ) ; bool DataInTableFromExcel( System.Data.DataTable objDataTable , string excelFilePath ) ; bool DataInTableColsFromExcelCols( System.Data.DataTable objDataTable ,string[] tableColsName ,string excelFilePath, string[] excelColsName ) ; bool DataUpdateTableColsFromExcelCols( OleDbConnection conn , string tableName , string PID , string [] tableColsName , System.Data.DataTable srcDataTable ,string [] srcColsName ) ; bool OutDataToExcel( System.Data.DataTable srcDataTable , string excelFilePath ) ; System.Data.DataTable GetDataFromExcel( string excelFilePath ) ; } //具体的一个实现类 public class ExcelOperate : ExcelInterface { //导入数据 2003.11.28(增添了可设置是否表的第一列是自增长的 id 列) public bool InDataFromExcelColumns( OleDbConnection conn , string tableName ,string [] tableColsName ,string excelFilePath ,string [] excelColsName ,bool hasSysID ) { if( hasSysID ) { return this.InDataFromExcelColumns( conn,tableName ,tableColsName ,excelFilePath ,excelColsName ); } else {

1

//把表的结构全部提取出来 OleDbDataAdapter oleDA = new OleDbDataAdapter( "select * from "+tableName , conn ) ; DataSet ds = new DataSet( ) ; OleDbCommandBuilder oleCmdBlt = new OleDbCommandBuilder( oleDA ) ; if( conn.State == ConnectionState.Closed ) conn.Open( ) ; oleDA.Fill( ds ) ; conn.Close( ) ; System.Data.DataTable objDataTable = ds.Tables[0] ; if( !this.DataInTableColsFromExcelCols( objDataTable ,tableColsName ,excelFilePath, excelColsName , false ) ) return false ; conn.Open( ) ; int addNum = oleDA.Update( ds ) ; conn.Close( ) ; if( addNum != 0 ) return true ; return false ; } } //把 Excel 中的数据导入具体的物理表中(单表) public bool InDataFromExcelColumns( OleDbConnection conn , string tableName ,string [] tableColsName ,string excelFilePath ,string [] excelColsName ) { // try // { //把表的结构全部提取出来 OleDbDataAdapter oleDA = new OleDbDataAdapter( "select * from "+tableName , conn ) ; DataSet ds = new DataSet( ) ; OleDbCommandBuilder oleCmdBlt = new OleDbCommandBuilder( oleDA ) ; if( conn.State == ConnectionState.Closed ) conn.Open( ) ; oleDA.Fill( ds ) ; conn.Close( ) ; System.Data.DataTable objDataTable = ds.Tables[0] ; if( !this.DataInTableColsFromExcelCols( objDataTable ,tableColsName ,excelFilePath, excelColsName ) ) return false ; conn.Open( ) ; int addNum = oleDA.Update( ds ) ;

2

conn.Close( ) ; if( addNum != 0 ) return true ; return false ; // } // catch // { // return false ; // } } //由 Excel 中的数据完全导入到表中 (前提是 excel 的表结构与要导入的表的结构是完全一样 的) public bool DataInTableFromExcel( System.Data.DataTable objDataTable , string excelFilePath ) { //先得到 excel 文件对应的表 System.Data.DataTable excelDataTable = this.GetDataFromExcel( excelFilePath ) ; if( excelDataTable == null || excelDataTable.Rows.Count == 0 || ((excelDataTable.Rows.Count == 1)&&(excelDataTable.Columns.Count == 1)&&(excelDataTable.Rows[0][0].ToString().Equals( "" ) ) )) return false ; if( objDataTable == null ) return false ; if( excelDataTable.Columns.Count != objDataTable.Columns.Count ) return false ; //检测数据类型是否匹配 for( int i = 0 ; i < objDataTable.Columns.Count ; i ++ ) { if( ! this.IsMatchDataType( objDataTable.Columns[i].DataType.ToString( ) , excelDataTable.Columns[i].DataType.ToString( ) ) ) return false ; } //完全添加进去 System.Data.DataRow myDataRow ; for( int i = 0 ; i < excelDataTable.Rows.Count ; i++ ) { myDataRow = objDataTable.NewRow( ) ; for( int j = 0 ; j < objDataTable.Columns.Count ; j ++ ) { myDataRow[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ), excelDataTable.Rows[i][j].ToString().Trim( ) ) ; } objDataTable.Rows.Add( myDataRow ) ;

3

} return true ; } /// <summary> /// 给指定的表的某列更新成 Excel 中某列的数据 /// </summary> /// <param name="conn">对此表有效的连接</param> /// <param name="tableName">物理表的表名</param> /// <param name="PID">此物理表的主键列名称(这里认为主键列只有一个)</param> /// <param name="tableColsName">此物理表中要更新的列集合</param> /// <param name="srcDataTable">更新的数据源</param> /// <param name="srcColsName">对应 tableColsName 中数据源中的列名集合</param> /// <returns></returns> public bool DataUpdateTableColsFromExcelCols( OleDbConnection conn , string tableName ,string ID , string [] tableColsName , System.Data.DataTable srcDataTable , string [] srcColsName ) { //此时认为 objDataTable 与 srcDataTable 的第一列的 id 列是连接关系 OleDbDataAdapter oleDA = new OleDbDataAdapter( "select * from "+tableName , conn ) ; DataSet ds = new DataSet( ) ; OleDbCommandBuilder oleCmdBlt = new OleDbCommandBuilder( oleDA ) ; if( conn.State == ConnectionState.Closed ) conn.Open( ) ; oleDA.Fill( ds ) ; conn.Close( ) ; System.Data.DataTable objDataTable = ds.Tables[0] ; //设主键 DataColumn [] keyCols = new DataColumn[1] ; keyCols[0] = objDataTable.Columns[ID] ; objDataTable.PrimaryKey = keyCols ; //循环检测物理表的每一条记录是不是要更新 for( int i = 0 ; i < objDataTable.Rows.Count ; i ++ ) { string idValue = objDataTable.Rows[i][ID].ToString( ).Trim( ) ; for( int j = 0 ; j < srcDataTable.Rows.Count ; j ++ ) { string tempID = srcDataTable.Rows[j][0].ToString( ).Trim( ) ; if( tempID.Equals( idValue ) ) {

4

objDataTable.Rows[i].BeginEdit( ) ; //================================= for( int k = 0 ; k < objDataTable.Columns.Count ; k ++ ) { int index = this.MatchStringIndex( objDataTable.Columns[k].ColumnName , tableColsName ) ; if( index != -1 ) { objDataTable.Rows[i][ tableColsName[index] ] = this.GetMatchData( objDataTable.Columns[k].DataType.ToString( ).Trim( ) ,srcDataTable.Rows[j ][srcColsName[index]].ToString().Trim( ) ) ; } } //================================= objDataTable.Rows[i].EndEdit( ) ; break ; } } }//for conn.Open( ) ; int affect = oleDA.Update( ds ) ; conn.Close( ) ; if( affect == 0 ) return false ; return true ; } //2003.11.28 To (增添了可设置是否表的第一列是自增长的 id 列) public bool DataInTableColsFromExcelCols( System.Data.DataTable objDataTable ,string[] tableColsName ,string excelFilePath, string[] excelColsName , bool hasID ) { //此时认为 objDataTable 是都有自动增长的 id 列 if( tableColsName == null || excelColsName == null || tableColsName.Length != excelColsName.Length ) return false ; //先得到 excel 文件对应的表 System.Data.DataTable excelDataTable = this.GetDataFromExcel( excelFilePath ) ; if( excelDataTable == null || excelDataTable.Rows.Count == 0 || ((excelDataTable.Rows.Count == 1)&&(excelDataTable.Columns.Count == 1)&&(excelDataTable.Rows[0][0].ToString().Equals( "" ) ) )) return false ; if( objDataTable == null )

5

return false ; //把相应的数据添加到目标表中 //首先验证要添加的数据与源数据的类型是否匹配 // for( int i = 0 ; i < excelColsName.Length ; i++ ) // { // string srcDataType = excelDataTable.Columns[ excelColsName[i] ].DataType.ToString( ).Trim( ) ; // string objDataType = objDataTable.Columns[ tableColsName[i] ].DataType.ToString( ).Trim( ) ; // // if( ! this.IsMatchDataType( objDataType , srcDataType ) ) // return false ; // } //System.Data.DataRow myDataRow ; //添加(一次添加一行) //myDataRow = objDataTable.NewRow( ) ; int colNum = objDataTable.Columns.Count ; //object [] colValues = new Object[ colNum ] ; int dataRow = excelDataTable.Rows.Count ; for( int k = 0 ; k < dataRow ; k ++ ) { //int colNum = objDataTable.Columns.Count ; object [] colValues = new Object[ colNum ] ; //认为第一列是自动增长的 id 列,不添加任何值,由系统自动生成 //colValues[0] = Guid.NewGuid( ) ; int addIndex = 0 ; int j = 0 ; if( hasID ) j = 1 ; for( ; j < colNum ; j++ ) { if( this.NumberInSource( objDataTable.Columns[j].ColumnName , tableColsName ) != 1 ) { colValues[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) , "") ; //myDataRow[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) , "") ; } else//是要添加数据的列时 { //找到与此列对应的 tableColsName 中的项索引 int index = MatchStringIndex( objDataTable.Columns[j].ColumnName , tableColsName ) ;

6

colValues[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) ,excelDataTable.Rows[k][exc elColsName[index]].ToString().Trim() ); //myDataRow[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) ,excelDataTable.Rows[k][exc elColsName[addIndex++]].ToString().Trim() ); } } objDataTable.Rows.Add( colValues ) ; } return true ; } //给指定的表的某列导入 Excel 中某列的数据 public bool DataInTableColsFromExcelCols( System.Data.DataTable objDataTable ,string[] tableColsName ,string excelFilePath, string[] excelColsName ) { //此时认为 objDataTable 是都有自动增长的 id 列 if( tableColsName == null || excelColsName == null || tableColsName.Length != excelColsName.Length ) return false ; //先得到 excel 文件对应的表 System.Data.DataTable excelDataTable = this.GetDataFromExcel( excelFilePath ) ; if( excelDataTable == null || excelDataTable.Rows.Count == 0 || ((excelDataTable.Rows.Count == 1)&&(excelDataTable.Columns.Count == 1)&&(excelDataTable.Rows[0][0].ToString().Equals( "" ) ) )) return false ; if( objDataTable == null ) return false ; //把相应的数据添加到目标表中 //首先验证要添加的数据与源数据的类型是否匹配 // for( int i = 0 ; i < excelColsName.Length ; i++ ) // { // string srcDataType = excelDataTable.Columns[ excelColsName[i] ].DataType.ToString( ).Trim( ) ; // string objDataType = objDataTable.Columns[ tableColsName[i] ].DataType.ToString( ).Trim( ) ; // // if( ! this.IsMatchDataType( objDataType , srcDataType ) ) // return false ; // }

7

//System.Data.DataRow myDataRow ; //添加(一次添加一行) //myDataRow = objDataTable.NewRow( ) ; int colNum = objDataTable.Columns.Count ; //object [] colValues = new Object[ colNum ] ; int dataRow = excelDataTable.Rows.Count ; for( int k = 0 ; k < dataRow ; k ++ ) { //int colNum = objDataTable.Columns.Count ; object [] colValues = new Object[ colNum ] ; //认为第一列是自动增长的 id 列,不添加任何值,由系统自动生成 //colValues[0] = Guid.NewGuid( ) ; int addIndex = 0 ; for( int j = 1 ; j < colNum ; j++ ) { if( this.NumberInSource( objDataTable.Columns[j].ColumnName , tableColsName ) != 1 ) { colValues[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) , "") ; //myDataRow[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) , "") ; } else//是要添加数据的列时 { //找到与此列对应的 tableColsName 中的项索引 int index = MatchStringIndex( objDataTable.Columns[j].ColumnName , tableColsName ) ; colValues[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) ,excelDataTable.Rows[k][exc elColsName[index]].ToString().Trim() ); //myDataRow[j] = this.GetMatchData( objDataTable.Columns[j].DataType.ToString( ) ,excelDataTable.Rows[k][exc elColsName[addIndex++]].ToString().Trim() ); } } objDataTable.Rows.Add( colValues ) ; } return true ; }

8

//把数据表的内容导出到 Excel 文件中:method1 public bool OutDataToExcel( System.Data.DataTable srcDataTable , string excelFilePath ) { if( srcDataTable == null ) return false ; Excel.Application myExcel=new Excel.Application ( ) ; try { object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ; Excel._Workbook xBk; Excel._Worksheet xSt; xBk = myExcel.Workbooks.Add(true); xSt = (Excel._Worksheet)xBk.ActiveSheet;

int rowIndex = 1; int colIndex = 1 ; //写标题 foreach(DataColumn col in srcDataTable.Columns) { xSt.Cells[ rowIndex ,colIndex ] = col.ColumnName.Trim(); ++colIndex; } rowIndex = 2 ; foreach( DataRow row in srcDataTable.Rows ) { colIndex = 1 ; foreach( DataColumn col in srcDataTable.Columns ) { xSt.Cells[ rowIndex,colIndex] = row[ col.ColumnName ] .ToString().Trim(); ++colIndex ; } ++rowIndex ; } Marshal.ReleaseComObject( myExcel ) ; return true ; } catch{

9

Marshal.ReleaseComObject( myExcel ) ; return false ; } } //从 Excel 中的 workBook[1]中的全部的 sheet 选取全部的数据 public System.Data.DataTable GetDataFromExcel( string excelFilePath ) { Excel.Application myExcel=new Excel.Application ( ) ; try { //取得 Excel 文件中共有的 sheet 的数目 object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ; Excel.Workbook myBook = myExcel.Workbooks[1] ; int sheetNum = myBook.Worksheets.Count ; //===========2003.11.28============= string [] sheetName = new String[ sheetNum ] ; int sheetIndex = 0 ; foreach( Excel.Worksheet xlsheet in myBook.Worksheets ) { sheetName[sheetIndex++] = xlsheet.Name ; } //===========#2003.11.28============ myExcel.Application.Workbooks.Close( ) ; string strConn = String.Format(" Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = {0};Extended Properties=Excel 8.0" ,excelFilePath ); OleDbConnection conn = new OleDbConnection( strConn ) ; string selSqlStr = "" ; //循环取完所有的 sheet 中的数据 // System.Data.DataTable totalDataTable = new System.Data.DataTable( ) ; for( int i = 1 ; i <= sheetNum ; i ++ ) {

10

selSqlStr = "select * from [" + sheetName[i-1] + "$]" ; //selSqlStr = "select * from [Sheet3$]" ;//==================right OleDbDataAdapter oleDa = new OleDbDataAdapter( selSqlStr,conn ) ; DataSet ds = new DataSet( ) ; conn.Open( ) ; oleDa.Fill( ds ,"dataTable" ) ; conn.Close( ) ; if( ds.Tables.Count != 0 ) { totalDataTable = this.AddDataTable( totalDataTable , ds.Tables["dataTable"] ) ; } } Marshal.ReleaseComObject( myExcel ) ; return totalDataTable ; } catch { Marshal.ReleaseComObject( myExcel ) ; return null ; } } /// <summary> /// /// </summary> /// <param name="excelFilePath"></param> /// <param name="index">sheet 的索引号,从 1 开始</param> /// <returns></returns> public string [] GetColumnsNameList( string excelFilePath ,int index ) { //string [] returnList = new string[ dataTable.Columns.Count ] ; Excel.Application myExcel=new Excel.Application ( ) ; try { //取得 Excel 文件中共有的 sheet 的数目 object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ;

11

Excel.Workbook myBook = myExcel.Workbooks[1] ; Excel.Sheets sheets = myBook.Worksheets; Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item( index ); Excel.Range range = worksheet.get_Range("A1", "CZ1" ); System.Array myvalues = (System.Array)range.Cells.Value; System.Collections.ArrayList array = this.ConvertToStringArray( myvalues ); //int colName = myBook.Worksheets.Count ; //===========2003.11.28============= // string [] sheetName = new String[ sheetNum ] ; // int sheetIndex = 0 ; // foreach( Excel.Worksheet xlsheet in myBook.Worksheets ) // { // sheetName[sheetIndex++] = xlsheet.Name ; // } string [] colName = new string[ array.Count ] ; //myExcel.get_Range( for( int i = 0 ; i < array.Count ; i ++ ) { colName[i] = array[i].ToString().Trim() ; } myExcel.Application.Workbooks.Close( ) ; Marshal.ReleaseComObject( myExcel ) ; return colName; } catch { Marshal.ReleaseComObject( myExcel ) ; return null ; } } /// <summary> /// 获取有指定的 colList 的页的名称 /// </summary> /// <param name="excelFilePath"></param> /// <returns></returns> public string [] GetSheetNameList( string excelFilePath , string[] colList ) { Excel.Application myExcel=new Excel.Application ( ) ; try{ //取得 Excel 文件中共有的 sheet 的数目

12

object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ; Excel.Workbook myBook = myExcel.Workbooks[1] ; int sheetNum = myBook.Worksheets.Count ; string [] col = null ; ArrayList totalName = new ArrayList(); for( int i = 1 ; i <= sheetNum ; i ++ ){ col = this.GetColumnsNameList( excelFilePath , i ) ; if( col==null || col.Length == 0 || col.Length != colList.Length ) continue ; for( int j = 0 ; j < col.Length ; j ++ ) { if( col[j].Trim() != colList[j].Trim() ) continue ; } Excel.Worksheet xlsheet = (Excel.Worksheet)myBook.Worksheets[i] ; totalName.Add( xlsheet.Name ) ; } //===========2003.11.28============= string [] sheetName = new String[ totalName.Count ] ; for( int i = 0 ; i < totalName.Count ; i ++ ) { sheetName[i] = totalName[i].ToString().Trim(); } myExcel.Application.Workbooks.Close( ) ; Marshal.ReleaseComObject( myExcel ) ; return sheetName; } catch{ Marshal.ReleaseComObject( myExcel ) ; return null ; } } /// <summary> /// /// </summary>

13

/// <param name="excelFilePath"></param> /// <returns></returns> public bool DelSheetColumnData( string excelFilePath , System.Collections.ArrayList colName ) { Excel.Application myExcel=new Excel.Application ( ) ; try { if( colName == null && colName.Count == 0 ) return true; //取得 Excel 文件中共有的 sheet 的数目 object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ; Excel.Workbook myBook = myExcel.Workbooks[1] ; Excel.Sheets sheets = myBook.Worksheets; Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1); Excel.Range range = worksheet.get_Range("A1", "Z1" ); System.Array myvalues = (System.Array)range.Cells.Value; Excel.Range delRange ; for (int i = 1; i <= myvalues.Length ; i ++ ) { if( ISDelCol( myvalues.GetValue( 1,i) .ToString().Trim() , colName ) != -1 ) { delRange = worksheet.get_Range( i, i ); delRange.Delete(i); } // if (values.GetValue(1, i) != null && values.GetValue(1,i).ToString().Trim() != "" ) // theArray.Add( values.GetValue( 1, i ).ToString().Trim() ); } myExcel.Application.Workbooks.Close( ) ; Marshal.ReleaseComObject( myExcel ) ; return true; } catch { Marshal.ReleaseComObject( myExcel ) ; return false ;

14

} } /// <summary> /// /// </summary> /// <param name="oldColName"></param> /// <param name="newColName"></param> /// <returns></returns> public void SetColumnName( string excelFilePath ,ArrayList oldColName , ArrayList newColName ){ Excel.Application myExcel=new Excel.Application ( ) ; try { if( oldColName == null || oldColName.Count == 0 ) return ; //取得 Excel 文件中共有的 sheet 的数目 object oMissing = System.Reflection.Missing.Value ; myExcel.Application.Workbooks.Open(excelFilePath,oMissing,oMissing,oMissing,oMissing,oMi ssing, oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing ) ; Excel.Workbook myBook = myExcel.Workbooks[1] ; Excel.Sheets sheets = myBook.Worksheets; Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1); Excel.Range range = worksheet.get_Range("A1", "Z1" ); System.Array myvalues = (System.Array)range.Cells.Value; Excel._Workbook xBk; Excel._Worksheet xSt; xBk = myExcel.Workbooks[1] ; xSt = (Excel._Worksheet)xBk.ActiveSheet; //Excel.Range delRange ; for (int i = 1; i <= myvalues.Length ; i ++ ) { int index = ISDelCol( myvalues.GetValue( 1,i) .ToString().Trim() , oldColName ); if( index != -1 ) { xSt.Cells[1,i] = newColName[i].ToString().Trim() ; } }

15

myExcel.Application.Workbooks.Close() ; Marshal.ReleaseComObject( myExcel ) ; } catch { Marshal.ReleaseComObject( myExcel ) ; } } /// <summary> /// /// </summary> public void ReleaseComExcel(){ }

#region 内部接口 //在表中追加与此表结构相同的表中的记录 System.Data.DataTable AddDataTable( System.Data.DataTable oldDataTable ,System.Data.DataTable srcDataTable ) { if( srcDataTable == null ) return oldDataTable ; System.Data.DataTable returnDataTable = new System.Data.DataTable( ) ; System.Data.DataRow myDataRow ; // if( oldDataTable != null ) { if( oldDataTable.Columns.Count != srcDataTable.Columns.Count ) { if( oldDataTable.Columns.Count >= srcDataTable.Columns.Count ) return oldDataTable ; return srcDataTable ; } //给表格添加列 for(int i = 0 ; i < srcDataTable.Columns.Count ; i++ ) { returnDataTable.Columns.Add( new

16

System.Data.DataColumn( srcDataTable.Columns[i].ColumnName ,srcDataTable.Columns[i].Dat aType ) ); } int rowNum = oldDataTable.Rows.Count ; //添加每一行的数据到目标数据表中 for( int i = 0 ; i < rowNum ; i++ ) { myDataRow = returnDataTable.NewRow( ) ; int colNum = oldDataTable.Columns.Count ; for( int j = 0 ; j < colNum ; j++ ) { myDataRow[j] = oldDataTable.Rows[i].ItemArray[j] ; } returnDataTable.Rows.Add( myDataRow ) ; } rowNum = srcDataTable.Rows.Count ; for( int i = 0 ; i < rowNum ; i++ ) { myDataRow = returnDataTable.NewRow( ) ; int colNum = srcDataTable.Columns.Count ; if( colNum > 0 ) { if( ((srcDataTable.Rows[i].ItemArray[0]).ToString( ) == null || (srcDataTable.Rows[i].ItemArray[0]).ToString( ).Equals( "" )) &&( rowNum == 1 ) && ( colNum == 1 ) ) return oldDataTable ; for( int j = 0 ;j < colNum ; j ++ ) { myDataRow[j] = this.GetMatchData( srcDataTable.Columns[j].DataType.ToString( ) , srcDataTable.Rows[i][j].ToString( ) ) ; } returnDataTable.Rows.Add( myDataRow ) ; } } }

17

return returnDataTable ; } //取得对应数据类型的数据 object GetMatchData( string dataType , string data ) { switch( dataType ) { case "System.Double" : if( data.Equals("") ) return 0 ; return Convert.ToDouble( data ) ; case "System.Decimal" : if( data.Equals("") ) return 0 ; return Convert.ToDecimal( data ) ; case "System.DateTime" : if( data.Equals("") ) { return Convert.ToDateTime( System.DateTime.Now.ToLongDateString( ) ) ; } return Convert.ToDateTime( data ) ; case "System.Int64" : if( data.Equals("") ) return 0 ; return Convert.ToInt64( data ) ; case "System.Int32" : if( data.Equals("") ) return 0 ; return Convert.ToInt32( data ) ; case "System.Int16" : if( data.Equals("") ) return 0 ; return Convert.ToInt16( data ) ; case "System.Boolean" : if( data.Equals("") ) return 0 ; return Convert.ToInt16( data ) ; }

18

return data ; } //验证数据类型的匹配 public bool IsMatchDataType( string objDataType , string srcDataType ) { if( objDataType.Equals( srcDataType ) ) return true ; if( (!objDataType.Equals( "System.String" ))&&( !objDataType.Equals( "System.DateTime" ) )) { switch( srcDataType ) { case "System.Int32" : case "System.Int16" : case "System.Double" : case "System.Decimal": return true ; } return false ; } if( objDataType.Equals( "System.DateTime" ) ) { switch( srcDataType ) { case "System.DateTime" : case "System.String" : return true ; } return false ; } return false ; } //获取在字符串集合中与目标字符串值相同的字符串的个数 private int NumberInSource(string str,string [] source) { if(source == null) return 0; if(str == null) return 0; int num = 0 ;

19

for(int i=0;i<source.Length;i++) { if(str.Equals(source[i])) num++; } return num ; } private int MatchStringIndex( string objStr , string [] srcStr ) { if( srcStr != null ) { for( int i = 0 ; i < srcStr.Length ; i ++ ) { if( objStr.Trim( ).Equals( srcStr[i].Trim( ) ) ) return i ; } } return -1 ; } System.Collections.ArrayList ConvertToStringArray(System.Array values) { System.Collections.ArrayList theArray = new System.Collections.ArrayList(); for (int i = 1; i <= values.Length; i++) { if (values.GetValue(1, i) != null && values.GetValue(1,i).ToString().Trim() != "" ) theArray.Add( values.GetValue( 1, i ).ToString().Trim() ); } return theArray; } int ISDelCol( string objColName , System.Collections.ArrayList colName ){ if( colName == null ) return -1 ; for( int i = 0 ; i < colName.Count ; i ++ ) { if( objColName.Trim() == colName[i].ToString().Trim() ) return i ; } return -1 ; } #endregion } }

20

C#实现数据高效率导入 EXCEL(适用于导入到指定特定模板) 本来各种数据库导入 EXCEL 都提供有操作接口(有的是 COM 组件,还有可以利用自带工 具等) , 但是当要把数据写入到一定格式的 EXCEL,利用这些就很不方便了,而且非要利用,实现 起来 过程也有点麻烦,效率上也就打了折扣, 如果用 EXCEL 组件逐个单元格写的话,效率更低,这个我已经在实际应用中体验到了, 在没有性能方面的要求下,这样还能过得去的。 下面就举例说明另外一中实现方法,实现思路来源于模拟 Window 上操作 EXCEL,从文本 拷贝到 EXCEL 文件中。 首先搞清楚的是 EXCEL 文件中的数据拷贝到文本文件中是什么样子的: 比如 EXCEL 的 sheet 中有三列数据 TEST1 TEST2 TEST3 TEST4 TEST5 TEST6 拷贝到文本文件中后(用 EmEditor) ,发现各列数据之间是用‘\t’来区分开的, 换行当然是‘\r\n’了。 OK,下面就用代码来试验下把如上的数据写入到 EXCEL 文件中: view plaincopy to clipboardprint? string fileName = @"d:\模板文件.xls"; Microsoft.Office.Interop.Excel.Application app = null; Microsoft.Office.Interop.Excel.Workbooks wbs = null; Microsoft.Office.Interop.Excel.Workbook wb = null; Microsoft.Office.Interop.Excel.Worksheet s = null; try { app = new Microsoft.Office.Interop.Excel.Application(); app.DisplayAlerts = false; wbs = app.Workbooks;

21

//wb = wbs.Add(fileName); wb = wbs.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); s = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1]; int recordCount = 1692; // 假设模板中是从第 5 行开始写,写入三列 Microsoft.Office.Interop.Excel.Range rangeMonth = s.get_Range("A5", "C6"); System.Windows.Forms.Clipboard.SetDataObject("TEST1\tTEST2\tTEST3\r\nTEST4\tTEST5\tT EST6"); s.Paste(rangeMonth, false); } catch (Exception ex) { throw ex; } finally { try { if (wb != null) wb.Close(true, Type.Missing, false); if (wbs != null) wbs.Close(); if (app != null) app.Quit(); wb = null; wbs = null; app = null; } catch { } GC.Collect(); } string fileName = @"d:\模板文件.xls";

22

Microsoft.Office.Interop.Excel.Application app = null; Microsoft.Office.Interop.Excel.Workbooks wbs = null; Microsoft.Office.Interop.Excel.Workbook wb = null; Microsoft.Office.Interop.Excel.Worksheet s = null; try { app = new Microsoft.Office.Interop.Excel.Application(); app.DisplayAlerts = false; wbs = app.Workbooks; //wb = wbs.Add(fileName); wb = wbs.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); s = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1]; int recordCount = 1692; // 假设模板中是从第 5 行开始写,写入三列 Microsoft.Office.Interop.Excel.Range rangeMonth = s.get_Range("A5", "C6"); System.Windows.Forms.Clipboard.SetDataObject("TEST1\tTEST2\tTEST3\r\nTEST4\tTEST5\tT EST6"); s.Paste(rangeMonth, false); } catch (Exception ex) { throw ex; } finally { try { if (wb != null) wb.Close(true, Type.Missing, false); if (wbs != null) wbs.Close(); if (app != null) app.Quit(); wb = null; wbs = null;

23

app = null; } catch { } GC.Collect(); } 测试结果 OK!

24

Visual C#的 Excel 编程
Excel 是微软公司办公自动化套件中的一个软件,他主要是用来处理电 子表格。Excel 以其功能强大,界面友好等受到了许多用户的欢迎。在 办公的时候,正是由于 Excel 的这么多的优点,许多重要的数据,往往 以 Excel 电子表格的形式存储起来。这样就给程序员带来了一个问题, 虽然 Excel 功能比较强大,但毕竟不是数据库,在程序中处理数据库中 的数据比其处理 Excel 表格中的数据容易许多。那么如何用 Visual C# 读取 Excel 表格中的数据?在以前用 Delphi 编程的时候, 对于不同的用 户,他们对于打印的需求是不一样的,如果要使得程序中的打印功能适 用于每一个用户,可以想象程序设计是十分复杂的。这时想到 Excel, 由于 Excel 表格的功能强大,又由于几乎每一台机器都安装了它,如果 把程序处理的结果放到 Excel 表格中,这样每一个用户就可以根据自己 的需要在 Excel 中定制自己的打印。这样不仅使得程序设计简单,而且 又满足了诸多用户的要求,更加实用了。那么用 Visual C#如何调用 E xcel,如何又把数据存放到 Excel 表格中?本文就来探讨一下上述问题 的解决办法。 一.程序设计及运行环境 (1).微软视窗 2000 服务器版 (2)..Net Framework SDK Beta 2 (3) .Microsoft Data Access Component 2.6 以上版本(MDAC2. 6) (4).Office 2000 套件 二.Visual C#读取 Excel 表格中的数据: 本节将通过一个程序来介绍 Visual C#读取 Excel 表格中的数据, 并把数据以 DataGrid 的形式显示出来。 (1).如何读取数据: 其实读取 Excel 表格中的数据和读取数据库中的数据是非常类似 的,因为在某种程度上 Excel 表格可以看成是一张一张的数据表。其二 者的主要区别在于所使用的数据引擎不一样。在本文的程序中,通过下 列代码实现读取 Excel 表格数据,具体如下:

//创建一个数据链接
25

string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data So urce = c:\\sample.xls;Extended Properties=Excel 8.0" ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; string strCom = " SELECT * FROM [Sheet1$] " ; myConn.Open ( ) ; file://打开数据链接,得到一个数据集 OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , m yConn ) ; file://创建一个 DataSet 对象 myDataSet = new DataSet ( ) ; file://得到自己的 DataSet 对象 myCommand.Fill ( myDataSet , "[Sheet1$]" ) ; file://关闭此数据链接 myConn.Close ( ) ;

怎么样读取 Excel 表格中的数据其实和读取数据库中的数据没有什 么实质上的区别。 注释:这里读取的是 C 盘根目录下的"Sample.xls"文件。 (2).用 DataGrid 来显示得到的数据集: 在得到 DataSet 对象后,只需要通过下列二行代码,就可以把数据 集用 DataGrid 显示出来了:

DataGrid1.DataMember= "[Sheet1$]" ; DataGrid1.DataSource = myDataSet ; (3).用 Visual C#读取 Excel 表格,并用 DataGrid 显示出来的 程序代码(Read.cs)和程序运行的界面: 掌握了上面二点,水到渠成就可以得到以下代码:

using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using System.Data ; using System.Data.OleDb ; public class Form1 : Form {
26

private private private private

Button button1 ; System.Data.DataSet myDataSet ; DataGrid DataGrid1 ; System.ComponentModel.Container components = null ;

public Form1 ( ) { file://初始化窗体中的各个组件 InitializeComponent ( ) ; file://打开数据链接,得到数据集 GetConnect ( ) ; } file://清除程序中使用过的资源 protected override void Dispose ( bool disposing ) { if ( disposing ) { if ( components != null ) { components.Dispose ( ) ; } } base.Dispose ( disposing ) ; } private void GetConnect ( ) { file://创建一个数据链接 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data So urce = c:\\sample.xls;Extended Properties=Excel 8.0" ; OleDbConnection myConn = new OleDbConnection ( strCon ) ; string strCom = " SELECT * FROM [Sheet1$] " ; myConn.Open ( ) ; file://打开数据链接,得到一个数据集 OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , m yConn ) ; file://创建一个 DataSet 对象 myDataSet = new DataSet ( ) ; file://得到自己的 DataSet 对象 myCommand.Fill ( myDataSet , "[Sheet1$]" ) ; file://关闭此数据链接 myConn.Close ( ) ; } private void InitializeComponent ( )

27

{ DataGrid1 = new DataGrid ( ) ; button1 = new Button ( ) ; SuspendLayout ( ) ; DataGrid1.Name = "DataGrid1"; DataGrid1.Size = new System.Drawing.Size ( 400 , 200 ) ; button1.Location = new System.Drawing.Point ( 124 , 240 ) ; button1.Name = "button1" ; button1.TabIndex = 1 ; button1.Text = "读取数据" ; button1.Size = new System.Drawing.Size (84 , 24 ) ; button1.Click += new System.EventHandler ( this.button1_Click ) ; this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ; this.ClientSize = new System.Drawing.Size ( 400 , 280 ) ; this.Controls.Add ( button1 ) ; this.Controls.Add ( DataGrid1 ) ; this.Name = "Form1" ; this.Text = "读取 Excle 表格中的数据,并用 DataGrid 显示出来!" ; this.ResumeLayout ( false ) ; } private void button1_Click ( object sender , System.EventArgs e ) { DataGrid1.DataMember= "[Sheet1$]" ; DataGrid1.DataSource = myDataSet ; } static void Main ( ) { Application.Run ( new Form1 ( ) ) ; } }

下图是程序编译后,运行结果: http://www.yesky.com/20020313/jt-2002-3-13-image001.jpg 图 01:用 Visual C#读取"c:\sample.xls"的运行界面

28

(4).总结: 以上只是读取了 Excel 表格中"Sheet1"中的数据,对于其他"Sheet "中的内容,可以参照读取"Sheet1"中的程序,只作一点修改就可以了, 譬如要读取"Sheet2"中的内容,只需要把"Read.cs"程序中的"Sheet1$" 改成"Sheet2$"就可以了。 三.Visual C#调用 Excel 表格,并在 Excel 表格中存储数据: 在 Visual C#中调用 Excel 表格,并不像读取 Excel 表格中的数据 那么容易了,因为在 Visual C#中调用 Excel 表格要使用到 Excel 的 C OM 组件。如果你安装 Office 套件在"C"盘,那么在"C:\Program Files\ Microsoft Office\Office"可以找到这个 COM 组件"EXCEL9.OLB",在《V isual C#如何使用 Active X 组件》一文中,这些 COM 组件都是非受管 代码的,要在 Visual C#中使用这些非受管代码的 COM 组件,就必须把 他们转换成受管代码的类库。 所以在用 Visual C#调用 Excel 表格之前, 必须完成从 COM 组件的非受管代码到受管代码的类库的转换。 (1).非受管代码 COM 组件转换成受管代码的类库: 首先把 COM 组件"EXCEL9.OLB"拷贝到 C 盘的根目录下,然后输入下 列命令:

tlbimp excel9.olb 这样在 C 盘的根目录下面就产生了三个 DLL 文件:"Excel.dll"、" Office.dll"、"VBIDE.dll"。在产生了上面的三个文件后,这种转换就 成功完成了。在下面的程序中,就可以利用这转换好的三个类库编写和 Excel 表格相关的各种操作了。 (2).Visual C#打开 Excel 表格: 在"Excel.dll"中定义了一个命名空间"Excel",在差命名空间中封 装了一个类"Application",这个类和启动 Excel 表格有非常重要的关 系,在 Visual C#中,只需要下列三行代码就可以完成打开 Excel 表格 的工作,具体如下:

Excel.Application excel = new Excel.Application ( ) ; excel.Application.Workbooks.Add ( true ) ; excel.Visible = true ; 但此时的 Excel 表格是一个空的表格,没有任何内容,下面就来介

29

绍如何往 Excel 表格中输入数据。 (3).往 Excel 表格中输入数据: 在命名空间"Excel"中,还定义了一个类"Cell",这个类所代表的就 是 Excel 表格中的一个下单元。通过给差"Cell"赋值,从而实现往 Exce l 表格中输入相应的数据,下列代码功能是打开 Excel 表格,并且往表 格输入一些数据。

Excel.Application excel = new Excel.Application ( ) ; excel.Application.Workbooks.Add ( true ) ; excel.Cells[ 1 , 1 ] = "第一行第一列" ; excel.Cells[ 1 , 2 ] = "第一行第二列" ; excel.Cells[ 2 , 1 ] = "第二行第一列" ; excel.Cells[ 2 , 2 ] = "第二行第二列" ; excel.Cells[ 3 , 1 ] = "第三行第一列" ; excel.Cells[ 3 , 2 ] = "第三行第二列" ; excel.Visible = true ; (4). Visual C#调用 Excel 表格,并在 Excel 表格中存储数据的 程序代码(Excel.cs): 了解了上面的这些知识,得到完成上述功能的程序代码就显得比较 容易了,具体如下:

using System ; using System.Drawing ; using System.Collections ; using System.ComponentModel ; using System.Windows.Forms ; using System.Data ; using System.Data.SqlClient ; public class Form1 : Form { private Button button1 ; private System.ComponentModel.Container components = null ; public Form1 ( ) { file://初始化窗体中的各个组件 InitializeComponent ( ) ; } file://清除程序中使用的各个资源 protected override void Dispose ( bool disposing )
30

{ if ( disposing ) { if ( components != null ) { components.Dispose ( ) ; } } base.Dispose( disposing ) ; } private void InitializeComponent ( ) { button1 = new Button ( ) ; SuspendLayout ( ) ; button1.Location = new System.Drawing.Point ( 32 , 72 ) ; button1.Name = "button1" ; button1.Size = new System.Drawing.Size ( 100 , 30 ) ; button1.TabIndex = 0 ; button1.Text = "调用 Excel 文件!" ; button1.Click += new System.EventHandler ( button1_Click ) ; AutoScaleBaseSize = new System.Drawing.Size ( 5 , 13 ) ; this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ; this.Controls.Add ( button1 ) ; this.Name = "Form1" ; this.Text = "如何用 Visual C#调用 Excel 表格!" ; this.ResumeLayout ( false ) ; } static void Main ( ) { Application.Run ( new Form1 ( ) ) ; } private void button1_Click ( object sender , System.EventArgs e ) { Excel.Application excel = new Excel.Application ( ) ; excel.Application.Workbooks.Add ( true ) ; excel.Cells[ 1 , 1 ] = "第一行第一列" ; excel.Cells[ 1 , 2 ] = "第一行第二列" ; excel.Cells[ 2 , 1 ] = "第二行第一列" ; excel.Cells[ 2 , 2 ] = "第二行第二列" ; excel.Cells[ 3 , 1 ] = "第三行第一列" ; excel.Cells[ 3 , 2 ] = "第三行第二列" ;
31

excel.Visible = true ; } }

(5).编译源程序和程序运行界面: 在经过了下列命令编译后:

Csc.exe /r:system.dll /r:system.windows.forms.dll /r:system.dr awing.dll /r:excel.dll /r:office.dll /r:vbide.dll excel.cs 就可以得到"Excel.exe",运行后界面如下 http://www.yesky.com/20020313/jt-2002-3-13-image003.jpg 图 02:Visual C#调用 Excel 表格,并存储数据的程序运行界面 四.Visual C#处理 Office 套件中的其他成员程序: 本文虽然只介绍了 Visual C#在处理 Excel 表格中经常遇到的一些 问题的解决方法,但其实对 Office 套件的其他成员也有很强的借鉴意 义,譬如 Visual C#来处理 Word 文档,在调用 Word 文档的时候,必须 先完成 COM 组件从非受管代码到受管代码的转换,Word 的 COM 组件位"M SWORD9.OLB",经过转换后也会产生三个 DLL 文件,但分别是"Word.dll "、"Office.dll"、"VBIDE.dll"。其实在 Visual C#中调用 Word,也非 常容易。 只需要把调用 Excel 表格中的代码换成调用 Word 的代码就可以 了,具体如下:

Word.Application word = new Word.Application ( ) ; word.Application.Visible = true ; 不信你试一下,看看是否达到你的要求。对于针对 Word 的其他的操 作,总体来说和对 Excel 表格的操作相类似。由于针对 Word 只是一个文 档,程序对 Word 进行的操作是比较少的,所以就不一一介绍了。 五.总结: 本文介绍 Visual C#来处理 Excel 表格的几种最常遇到的情况,虽 然针对的只是 Excel 表格, 但对其他 Office 套件中的成员也具有十分的 借鉴意义。

32

C#取 Excel 合并单元格的对应数据 怎么取 private DataSet BindDsFromExcel(string strFileDir, string strDataName) { string strConn; strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFileDir + ";Extended Properties='Excel 8.0;HDR=False;IMEX=1'"; OleDbConnection OleConn = new OleDbConnection(strConn); OleConn.Open(); String sql = "SELECT * FROM [" + strDataName + "$]";//如果不知道名字就用 Sheets[1] OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn); DataSet OleDsExcle = new DataSet(); OleDaExcel.Fill(OleDsExcle, strDataName); OleConn.Close(); return OleDsExcle; }

ADO.NET 如何读取 Excel (上) 经常需要在数据库与 Execl 之间互导数据。net 时代,ADO.NET 可以使用使用 Microsoft.Jet.OleDb 访问访问 Excel,网上已经有很多类似的资源,最典型也是最简单的可 能如下: (asp.net 环境) // 连接字符串 string xlsPath = Server.MapPath("~/app_data/somefile.xls"); // 绝对物理路径 string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Extended Properties=Excel 8.0;" + "data source=" + xlsPath; // 查询语句 string sql = "SELECT * FROM [Sheet1$]"; DataSet ds = new DataSet(); OleDbDataAdapter da = new OleDbDataAdapter(sql, connStr); da.Fill(ds); // 填充 DataSet // 在这里对 DataSet 中的数据进行操作 // 输出,绑定数据 GridView1.DataSource = ds.Tables[0]; GridView1.DataBind(); 很简单吧?!一切就像操作数据库一样,只是需要注意的是: 1。数据提供程序使用 Jet,同时需要指定 Extended Properties 关键字设置 Excel 特定的属

33

性,不同版本的 Excel 对应不同的属性值: 用于 Extended Properties 值的有效 Excel 版 本。 对于 Microsoft Excel 8.0 (97)、9.0 (2000) 和 10.0 (2002) 工作簿,请使用 Excel 8.0。 对于 Microsoft Excel 5.0 和 7.0 (95) 工作簿,请使用 Excel 5.0。 对于 Microsoft Excel 4.0 工作簿,请使用 Excel 4.0。 对于 Microsoft Excel 3.0 工作簿,请使用 Excel 3.0。 ref: http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/dv_vbcode/html/vbtskc odeexamplereadingexceldataintodataset.asp 2。数据源路径使用物理绝对路径(同 Access) 3。如何引用表名? 对 Excel 工作簿中表(或范围)的有效引用。 若要引用完全使用的工作表的范围,请指定后面跟有美元符号的工作表名称。例如: select * from [Sheet1$] 若要引用工作表上的特定地址范围,请指定后面跟有美元符号和该范围的工作表名称。例 如: select * from [Sheet1$A1:B10] 若要引用指定的范围,请使用该范围的名称。例如: select * from [MyNamedRange] ref: http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/dv_vbcode/html/vbtskc odeexamplereadingexceldataintodataset.asp 说明: 可以引用 Excel 工作簿中的三种对象: ? 整张工作表:[Sheet1$] ,Sheet1 就是工作表的名称 ? 工作表上的命名单元格区域:[MyNamedRange] (不需要指定工作表,因为整个 xls 中 命名区域只能唯一) XLS 命名方法:选中单元格范围》插入》名称》定义 ? 工作表上的未命名单元格区域 :[Sheet1$A1:B10] (在关系数据库提供的各种对象中(表、视图、存储过程等) ,Excel 数据源仅提供相当于 表的对象,它由指定工作簿中的工作表和定义的命名区域组成。命名区域被视为“表” ,而 工作表被视为“系统表” ) 注意: ?必须使用[](方括号) ,否将报:

34

FROM 子句语法错误 ?必须跟$(美元符号) ,否则报: Microsoft Jet 数据库引擎找不到对象'Sheet2'。请确定对象是否存在,并正确地写出它的名 称和路径。 ?如果工作表名称不对,或者不存在,将报: 'Sheet2$' 不是一个有效名称。请确认它不包含无效的字符或标点,且名称不太长。 ?在 如何在 Visual Basic 或 VBA 中使用 ADO 来处理 Excel 数据 中提到可以使用 ~ 和 '(波浪线和单引号)代替[],使用 ADO。NET 测试没有成功,报: FROM 子句语法错误 ?当引用工作表明名([Sheet1$])时,数据提供程序认为数据表从指定工作表上最左上方的 非空单元格开始。比如,工作表从第 3 行,C 列开始,第 3 行,C 列之前以及第 1、2 行 全为空,则只会显示从第 3 行,C 列开始的数据;以最后表最大范围内的非空单元结束; ?因此,如需要精确读取范围,应该使用命名区域 [NamedRange],或者指定地址: [Sheet1$A1:C10] 4。如何引用列名? ?根据默认连接字符串中,数据提供程序会将有效区域内的第一行作为列名,如果此行某单 元格为空则用 F1、F2 表示,其中序数,跟单元格的位置一致,从 1 开始; ?如果希望第一行作为数据显示,而非列名,可以在连接串的 Extended Properties 属性指 定:HDR=NO 默认值为:HDR=NO (应该为 HDR=YES,即默认将第一行作为列名,竟然一直没有发 现这个错误,汗 upadted 2007 年 8 月 18 日)格式如下: string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Extended Properties=\"Excel 8.0;HDR=NO\";" + "data source=" + xlsPath; 注意: Excel 8.0;HDR=NO 需要使用双引号(这里的反斜扛,是 C#中的转义) ref: ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/WD_ADONET/html/745c 5f95-2f02-4674-b378-6d51a7ec2490.htm 中 《连接 Excel》节(说明:在我自己的 MSDN 中,它的例子使用了两个双引号是错的,测试没有通过,原文这样说的: 注意,Extended Properties 所需的双引号必须还要加双引号。 ) 在这种情况下,所有的列名都是以 F 开头,然后跟索引,从 F1 开始,F2,F3。。。。 。。。 5。为什么有效单元格数据不显示出来? 出现这种情况的可能原因是,默认连接中,数据提供程序根据前面单元格推断后续单元个 的数据类型。 可以通过 Extended Properties 中指定 IMEX=1 “IMEX=1;”通知驱动程序始终将“互混”数据列作为文本读取

35

ref:同 4 PS:在 baidu 这个问题的时候,有网友说,将每个单元都加上引号,这固然是格方案,但 是工作量何其大啊,又不零活,庆幸自己找到”治本药方“ more ref: 如何在 Visual Basic 或 VBA 中使用 ADO 来处理 Excel 数据 http://dotnet.aspx.cc/ShowDetail.aspx?id=C673E2CD-3F1E-4919-8CE0-D69B894A0599

ADO.NET 如何读取 Excel (下) 应用程序经常需要与 Excel 进行数据交互, 在上一篇文章 ADO.NET 如何读取 Excel (上) 阐述了基于 ADO.NET 读取 Excel 的基本方法与技巧。今天这里要介绍是如何动态的读取 Excel 数据,这里的动态指的是事先不知道 Excel 文件的是什么样的结构,或者无法预测, 比如一张.xls 文件有多少张 sheet,而且每张 sheet 的结构可能都不一样等等。 其实我们可以通过获取 Excel 的“架构信息”来动态的构造查询语句。这里的“架构信息” 与数据库领域的“数据库架构信息”意义相同(也称“元数据”,对于整个数据库,这些 ) “元数据”通常包括数据库或可通过数据库中的数据源、表和视图得到的目录以及所存在 的约束等;而对于数据库中的表,架构信息包括主键、列和自动编号字段等。 在 ADO.NET 如何读取 Excel (上)提到 在关系数据库提供的各种对象中(表、视图、存储过程等) ,Excel 数据源仅提供相当于表 的对象,它由指定工作簿中的工作表和定义的命名区域组成。命名区域被视为“表” ,而工 作表被视为“系统表” ) 这里我们将 Excel 也当作一个“数据库”来对待,然后利用 OleDbConnection.GetOleDbSchemaTable 方法 要获取所需的架构信息,该方法获取的架构信息与 ANSI SQl-92 是兼容的: 注意:对于那些不熟悉 OLE DB 架构行集的人而言,它们基本上是由 ANSI SQL-92 定义 的数据库构造的标准化架构。每个架构行集具有为指定构造提供定义元数据的一组列(称 作 .NET 文档中的“限制列”。这样,如果请求架构信息(例如,列的架构信息或排序规 ) 则的架构信息) ,则您会明确知道可以得到哪种类型的数据。如果希望了解更多信息,请访 问 Appendix B:Schema Rowsets。ref: http://www.microsoft.com/china/msdn/library/office/office/odatanet2.mspx?mfr=true 以下是读取 Excel 文件内“表”定义元数据,并显示出来的的程序片断: // 读取 Excel 数 据,填充 DataSet // 连接字符串 string xlsPath = Server.MapPath("~/app_data/somefile.xls"); string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";" + // 指定扩展属性为 Microsoft Excel 8.0 (97) 9.0 (2000) 10.0 (2002),并且第一行作为数据返回,且以文本方式读取 "data source=" + xlsPath;

36

string sql_F = "SELECT * FROM [{0}]"; OleDbConnection conn = null; OleDbDataAdapter da = null; DataTable tblSchema = null; IList<string> tblNames = null; // 初始化连接,并打开 conn = new OleDbConnection(connStr); conn.Open(); // 获取数据源的表定义元数据 //tblSchema = conn.GetSchema("Tables"); tblSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); GridView1.DataSource = tblSchema; GridView1.DataBind(); // 关闭连接 conn.Close();GetOleDbSchemaTable 方法的详细说明可以参考: http://msdn2.microsoft.com/zh-CN/library/system.data.oledb.oledbconnection.getoledbsche matable.aspx 接着是一段利用“架构信息”动态读取 Excel 内部定义的表单或者命名区域的程序片断: // 读取 Excel 数据,填充 DataSet // 连接字符串 string xlsPath = Server.MapPath("~/app_data/somefile.xls"); string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";" + // 指定扩展属性为 Microsoft Excel 8.0 (97) 9.0 (2000) 10.0 (2002),并且第一行作为数据返回,且以文本方式读取 "data source=" + xlsPath; string sql_F = "SELECT * FROM [{0}]"; OleDbConnection conn = null; OleDbDataAdapter da = null; DataTable tblSchema = null; IList<string> tblNames = null; // 初始化连接,并打开 conn = new OleDbConnection(connStr); conn.Open(); // 获取数据源的表定义元数据

37

//tblSchema = conn.GetSchema("Tables"); tblSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); //GridView1.DataSource = tblSchema; //GridView1.DataBind(); // 关闭连接 //conn.Close(); tblNames = new List<string>(); foreach (DataRow row in tblSchema.Rows) { tblNames.Add((string)row["TABLE_NAME"]); // 读取表名 } // 初始化适配器 da = new OleDbDataAdapter(); // 准备数据,导入 DataSet DataSet ds = new DataSet(); foreach (string tblName in tblNames) { da.SelectCommand = new OleDbCommand(String.Format(sql_F, tblName), conn); try { da.Fill(ds, tblName); } catch { // 关闭连接 if (conn.State == ConnectionState.Open) { conn.Close(); } throw; } } // 关闭连接 if (conn.State == ConnectionState.Open) { conn.Close(); } // 对导入 DataSet 的每张 sheet 进行处理 // 这里仅做显示 GridView1.DataSource = ds.Tables[0]; GridView1.DataBind();

38

GridView2.DataSource = ds.Tables[1]; GridView2.DataBind(); // more codes // . 这里我们就不需要对 SELEC 语句进行“硬编码” ,可以根据需要动态的构造 FROM 字句 的“表名” 。 不仅可以,获取表明,还可以获取每张表内的字段名、字段类型等信息: tblSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, null, null }); 在 ADO.nET 1.x 时候只有 OleDb 提供了 GetOleDbSchemaTable 方法,而 SqlClient 或者 OrcaleClient 没有对应的方法, 因为对应数据库已经提供了类似功能的存储过程或者系统表 供应用程序访问,比如对于 Sql Server: SELECT * FROM Northwind.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'Customers' 而在 ADO.NET 2.0 中每个 xxxConnenction 都实现了基类 System.Data.Common.DbConnection 的 GetSchemal 方法 来获取数据源的架构信息。

39

C# excel using System; using System.IO; using System.Text; using System.Data; using System.Reflection; using System.Diagnostics; using System.Collections; //using cfg = System.Configuration; namespace GDBI.Common { /// <summary> /// 说 明:Excel 输出打印模块 /// 暂时不提供操作 Excel 对象样式方法,样式可以在 Excel 模板中设置好 /// 作 者:lingyun_k /// 创建日期:2005-7-12 /// </summary> public class ExcelHelper { #region 成员变量 private string templetFile = null; private string outputFile = null; private object missing = Missing.Value; private DateTime beforeTime; //Excel 启动之前时间 private DateTime afterTime; //Excel 启动之后时间 Excel.Application app; Excel.Workbook workBook; Excel.Worksheet workSheet; Excel.Range range; Excel.Range range1; Excel.Range range2; Excel.TextBox textBox; private int sheetCount = 1; //WorkSheet 数量 private string sheetPrefixName = "页"; #endregion #region 公共属性 /// <summary> /// WorkSheet 前缀名,比如:前缀名为“页” ,那么 WorkSheet 名称依次为“页-1, 页-2...” /// </summary>

40

public string SheetPrefixName { set { this.sheetPrefixName = value; } } /// <summary> /// WorkSheet 数量 /// </summary> public int WorkSheetCount { get { return workBook.Sheets.Count; } } /// <summary> /// Excel 模板文件路径 /// </summary> public string TempletFilePath { set { this.templetFile = value; } } /// <summary> /// 输出 Excel 文件路径 /// </summary> public string OutputFilePath { set { this.outputFile = value; } } #endregion #region 公共方法 #region ExcelHelper /// <summary> /// 构造函数,将一个已有 Excel 工作簿作为模板,并指定输出路径 /// </summary> /// <param name="templetFilePath">Excel 模板文件路径</param> /// <param name="outputFilePath">输出 Excel 文件路径</param> public ExcelHelper(string templetFilePath,string outputFilePath) { if(templetFilePath == null) throw new Exception("Excel 模板文件路径不能为空!"); if(outputFilePath == null)

41

throw new Exception("输出 Excel 文件路径不能为空!"); if(!File.Exists(templetFilePath)) throw new Exception("指定路径的 Excel 模板文件不存在!"); this.templetFile = templetFilePath; this.outputFile = outputFilePath; //创建一个 Application 对象并使其可见 beforeTime = DateTime.Now; app = new Excel.ApplicationClass(); app.Visible = true; afterTime = DateTime.Now; //打开模板文件,得到 WorkBook 对象 workBook = app.Workbooks.Open(templetFile,missing,missing,missing,missing,missing, missing,missing,missing,missing,missing,missing,missing); //得到 WorkSheet 对象 workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1); } /// <summary> /// 构造函数,打开一个已有的工作簿 /// </summary> /// <param name="fileName">Excel 文件名</param> public ExcelHelper(string fileName) { if(!File.Exists(fileName)) throw new Exception("指定路径的 Excel 文件不存在!"); //创建一个 Application 对象并使其可见 beforeTime = DateTime.Now; app = new Excel.ApplicationClass(); app.Visible = true; afterTime = DateTime.Now; //打开一个 WorkBook workBook = app.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

42

//得到 WorkSheet 对象 workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1); } /// <summary> /// 构造函数,新建一个工作簿 /// </summary> public ExcelHelper() { //创建一个 Application 对象并使其可见 beforeTime = DateTime.Now; app = new Excel.ApplicationClass(); app.Visible = true; afterTime = DateTime.Now; //新建一个 WorkBook workBook = app.Workbooks.Add(Type.Missing); //得到 WorkSheet 对象 workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1); } #endregion #region Data Export Methods /// <summary> /// 将 DataTable 数据写入 Excel 文件(自动分页) /// </summary> /// <param name="dt">DataTable</param> /// <param name="rows">每个 WorkSheet 写入多少行数据</param> /// <param name="top">表格数据起始行索引</param> /// <param name="left">表格数据起始列索引</param> public void DataTableToExcel(DataTable dt,int rows,int top,int left) { int rowCount = dt.Rows.Count; //DataTable 行数 int colCount = dt.Columns.Count; //DataTable 列数 sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet 个数 StringBuilder sb; //复制 sheetCount-1 个 WorkSheet 对象 for(int i=1;i<sheetCount;i++)

//

43

{ workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Copy(missing,workBook.Worksheets[i]); } for(int i=1;i<=sheetCount;i++) { int startRow = (i - 1) * rows; int endRow = i * rows;

//记录起始行索引 //记录结束行索引

//若是最后一个 WorkSheet,那么记录结束行索引为源 DataTable 行数 if(i == sheetCount) endRow = rowCount; //获取要写入数据的 WorkSheet 对象,并重命名 workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Name = sheetPrefixName + "-" + i.ToString(); //将 dt 中的数据写入 WorkSheet for(int j=0;j<endRow-startRow;j++) { for(int k=0;k<colCount;k++) { workSheet.Cells[top + j,left + k] = dt.Rows[startRow + }

// // // // // j][k].ToString(); // // }

//利用二维数组批量写入 int row = endRow-startRow; string[,] ss = new string[row,colCount]; for(int j=0;j<row;j++) { for(int k=0;k<colCount;k++) { ss[j,k] = dt.Rows[startRow + j][k].ToString(); } } range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(row,colCount); range.Value = ss;

44

#region 利用 Windwo 粘贴板批量拷贝数据(在 Web 下面行不通) /*sb = new StringBuilder(); for(int j=0;j<endRow-startRow;j++) { for(int k=0;k<colCount;k++) { sb.Append( dt.Rows[startRow + j][k].ToString() ); sb.Append("\t"); } sb.Append("\n"); } System.Windows.Forms.Clipboard.SetDataObject(sb.ToString()); range = (Excel.Range)workSheet.Cells[top,left]; workSheet.Paste(range,false);*/ #endregion } }

/// <summary> /// 将 DataTable 数据写入 Excel 文件(不分页) /// </summary> /// <param name="dt">DataTable</param> /// <param name="top">表格数据起始行索引</param> /// <param name="left">表格数据起始列索引</param> public void DataTableToExcel(DataTable dt,int top,int left) { int rowCount = dt.Rows.Count; //DataTable 行数 int colCount = dt.Columns.Count; //DataTable 列数 //利用二维数组批量写入 string[,] arr = new string[rowCount,colCount]; for(int j=0;j<rowCount;j++) { for(int k=0;k<colCount;k++) { arr[j,k] = dt.Rows[j][k].ToString(); }

45

} range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(rowCount,colCount); range.Value = arr; }

/// <summary> /// 将 DataTable 数据写入 Excel 文件(自动分页,并指定要合并的列索引) /// </summary> /// <param name="dt">DataTable</param> /// <param name="rows">每个 WorkSheet 写入多少行数据</param> /// <param name="top">表格数据起始行索引</param> /// <param name="left">表格数据起始列索引</param> /// <param name="mergeColumnIndex">DataTable 中要合并相同行的列索引,从 0 开始</param> public void DataTableToExcel(DataTable dt,int rows,int top,int left,int mergeColumnIndex) { int rowCount = dt.Rows.Count; //源 DataTable 行数 int colCount = dt.Columns.Count; //源 DataTable 列数 sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet 个数 // StringBuilder sb; //复制 sheetCount-1 个 WorkSheet 对象 for(int i=1;i<sheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Copy(missing,workBook.Worksheets[i]); } for(int i=1;i<=sheetCount;i++) { int startRow = (i - 1) * rows; int endRow = i * rows;

//记录起始行索引 //记录结束行索引

//若是最后一个 WorkSheet,那么记录结束行索引为源 DataTable 行数 if(i == sheetCount) endRow = rowCount; //获取要写入数据的 WorkSheet 对象,并重命名 workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Name = sheetPrefixName + "-" + i.ToString();

46

// // // // // j][k].ToString(); // // }

//将 dt 中的数据写入 WorkSheet for(int j=0;j<endRow-startRow;j++) { for(int k=0;k<colCount;k++) { workSheet.Cells[top + j,left + k] = dt.Rows[startRow + }

//利用二维数组批量写入 int row = endRow-startRow; string[,] ss = new string[row,colCount]; for(int j=0;j<row;j++) { for(int k=0;k<colCount;k++) { ss[j,k] = dt.Rows[startRow + j][k].ToString(); } } range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(row,colCount); range.Value = ss; //合并相同行 this.MergeRows(workSheet,left+mergeColumnIndex,top,rows); } }

/// <summary> /// 将二维数组数据写入 Excel 文件(自动分页) /// </summary> /// <param name="arr">二维数组</param> /// <param name="rows">每个 WorkSheet 写入多少行数据</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> public void ArrayToExcel(string[,] arr,int rows,int top,int left) { int rowCount = arr.GetLength(0); //二维数组行数(一维长度)

47

int colCount = arr.GetLength(1); //二维数据列数(二维长度) sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet 个数 //复制 sheetCount-1 个 WorkSheet 对象 for(int i=1;i<sheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Copy(missing,workBook.Worksheets[i]); } //将二维数组数据写入 Excel for(int i=sheetCount;i>=1;i--) { int startRow = (i - 1) * rows; int endRow = i * rows;

//记录起始行索引 //记录结束行索引

//若是最后一个 WorkSheet,那么记录结束行索引为源 DataTable 行数 if(i == sheetCount) endRow = rowCount; //获取要写入数据的 WorkSheet 对象,并重命名 workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Name = sheetPrefixName + "-" + i.ToString(); //将二维数组中的数据写入 WorkSheet for(int j=0;j<endRow-startRow;j++) { for(int k=0;k<colCount;k++) { workSheet.Cells[top + j,left + k] = arr[startRow + j,k]; } } //利用二维数组批量写入 int row = endRow-startRow; string[,] ss = new string[row,colCount]; for(int j=0;j<row;j++) { for(int k=0;k<colCount;k++) { ss[j,k] = arr[startRow + j,k]; } }

// // // // // // //

48

range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(row,colCount); range.Value = ss; } }//end ArrayToExcel

/// <summary> /// 将二维数组数据写入 Excel 文件(不分页) /// </summary> /// <param name="arr">二维数组</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> public void ArrayToExcel(string[,] arr,int top,int left) { int rowCount = arr.GetLength(0); //二维数组行数(一维长度) int colCount = arr.GetLength(1); //二维数据列数(二维长度) range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(rowCount,colCount); range.FormulaArray = arr; }//end ArrayToExcel /// <summary> /// 将二维数组数据写入 Excel 文件(不分页) /// </summary> /// <param name="arr">二维数组</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> /// <param name="isFormula">填充的数据是否需要计算</param> public void ArrayToExcel(string[,] arr,int top,int left,bool isFormula) { int rowCount = arr.GetLength(0); //二维数组行数(一维长度) int colCount = arr.GetLength(1); //二维数据列数(二维长度) range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(rowCount,colCount); //注意:使用 range.FormulaArray 写合并的单元格会出问题 if(isFormula) range.FormulaArray = arr;

49

else range.Value = arr; }//end ArrayToExcel /// <summary> /// 将二维数组数据写入 Excel 文件(不分页) ,合并指定列的相同行 /// </summary> /// <param name="arr">二维数组</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> /// <param name="isFormula">填充的数据是否需要计算</param> /// <param name="mergeColumnIndex">需要合并行的列索引</param> public void ArrayToExcel(string[,] arr,int top,int left,bool isFormula,int mergeColumnIndex) { int rowCount = arr.GetLength(0); //二维数组行数(一维长度) int colCount = arr.GetLength(1); //二维数据列数(二维长度) range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(rowCount,colCount); //注意:使用 range.FormulaArray 写合并的单元格会出问题 if(isFormula) range.FormulaArray = arr; else range.Value = arr; this.MergeRows(workSheet,mergeColumnIndex,top,rowCount); }//end ArrayToExcel /// <summary> /// 将二维数组数据写入 Excel 文件(不分页) /// </summary> /// <param name="sheetIndex">工作表索引</param> /// <param name="arr">二维数组</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> public void ArrayToExcel(int sheetIndex,string[,] arr,int top,int left) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess();

50

throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } // 改变当前工作表 this.workSheet = (Excel.Worksheet)this.workBook.Sheets.get_Item(sheetIndex); int rowCount = arr.GetLength(0); int colCount = arr.GetLength(1); //二维数组行数(一维长度) //二维数据列数(二维长度)

range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(rowCount,colCount); range.Value2 = arr; }//end ArrayToExcel /// <summary> /// 将二维数组数据写入 Excel 文件(自动分页,并指定要合并的列索引) /// </summary> /// <param name="arr">二维数组</param> /// <param name="rows">每个 WorkSheet 写入多少行数据</param> /// <param name="top">行索引</param> /// <param name="left">列索引</param> /// <param name="mergeColumnIndex">数组的二维索引, 相当于 DataTable 的列 索引,索引从 0 开始</param> public void ArrayToExcel(string[,] arr,int rows,int top,int left,int mergeColumnIndex) { int rowCount = arr.GetLength(0); //二维数组行数(一维长度) int colCount = arr.GetLength(1); //二维数据列数(二维长度) sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet 个数 //复制 sheetCount-1 个 WorkSheet 对象 for(int i=1;i<sheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Copy(missing,workBook.Worksheets[i]); } //将二维数组数据写入 Excel for(int i=sheetCount;i>=1;i--) {

51

int startRow = (i - 1) * rows; int endRow = i * rows;

//记录起始行索引 //记录结束行索引

//若是最后一个 WorkSheet,那么记录结束行索引为源 DataTable 行数 if(i == sheetCount) endRow = rowCount; //获取要写入数据的 WorkSheet 对象,并重命名 workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); workSheet.Name = sheetPrefixName + "-" + i.ToString(); //将二维数组中的数据写入 WorkSheet for(int j=0;j<endRow-startRow;j++) { for(int k=0;k<colCount;k++) { workSheet.Cells[top + j,left + k] = arr[startRow + j,k]; } } //利用二维数组批量写入 int row = endRow-startRow; string[,] ss = new string[row,colCount]; for(int j=0;j<row;j++) { for(int k=0;k<colCount;k++) { ss[j,k] = arr[startRow + j,k]; } } range = (Excel.Range)workSheet.Cells[top,left]; range = range.get_Resize(row,colCount); range.Value = ss; //合并相同行 this.MergeRows(workSheet,left+mergeColumnIndex,top,rows); } }//end ArrayToExcel #endregion #region WorkSheet Methods

52

/// <summary> /// 改变当前工作表 /// </summary> /// <param name="sheetIndex">工作表索引</param> public void ChangeCurrentWorkSheet(int sheetIndex) { //若指定工作表索引超出范围,则不改变当前工作表 if(sheetIndex < 1) return; if(sheetIndex > this.WorkSheetCount) return; this.workSheet = (Excel.Worksheet)this.workBook.Sheets.get_Item(sheetIndex); } /// <summary> /// 隐藏指定名称的工作表 /// </summary> /// <param name="sheetName">工作表名称</param> public void HiddenWorkSheet(string sheetName) { try { Excel.Worksheet sheet = null; for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); if(workSheet.Name == sheetName) sheet = workSheet; } if(sheet != null) sheet.Visible = Excel.XlSheetVisibility.xlSheetHidden; else { this.KillExcelProcess(); throw new Exception("名称为\"" + sheetName + "\"的工作表不存 在"); } }

53

catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 隐藏指定索引的工作表 /// </summary> /// <param name="sheetIndex"></param> public void HiddenWorkSheet(int sheetIndex) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { Excel.Worksheet sheet = null; sheet = (Excel.Worksheet)workBook.Sheets.get_Item(sheetIndex); sheet.Visible = Excel.XlSheetVisibility.xlSheetHidden; } catch(Exception e) { this.KillExcelProcess(); throw e; } }

/// <summary> /// 在指定名称的工作表后面拷贝指定个数的该工作表的副本,并重命名 /// </summary> /// <param name="sheetName">工作表名称</param> /// <param name="sheetCount">工作表个数</param> public void CopyWorkSheets(string sheetName,int sheetCount) { try {

54

Excel.Worksheet sheet = null; int sheetIndex = 0; for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); if(workSheet.Name == sheetName) { sheet = workSheet; sheetIndex = workSheet.Index; } } if(sheet != null) { for(int i=sheetCount;i>=1;i--) { sheet.Copy(this.missing,sheet); } //重命名 for(int i=sheetIndex;i<=sheetIndex+sheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); workSheet.Name = sheetName + "-" + Convert.ToString(i sheetIndex + 1); } } else { this.KillExcelProcess(); throw new Exception("名称为\"" + sheetName + "\"的工作表不存 在"); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary>

55

/// 将一个工作表拷贝到另一个工作表后面,并重命名 /// </summary> /// <param name="srcSheetIndex">拷贝源工作表索引</param> /// <param name="aimSheetIndex">参照位置工作表索引, 新工作表拷贝在该工作 表后面</param> /// <param name="newSheetName"></param> public void CopyWorkSheet(int srcSheetIndex,int aimSheetIndex,string newSheetName) { if(srcSheetIndex > this.WorkSheetCount || aimSheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { Excel.Worksheet srcSheet = (Excel.Worksheet)workBook.Sheets.get_Item(srcSheetIndex); Excel.Worksheet aimSheet = (Excel.Worksheet)workBook.Sheets.get_Item(aimSheetIndex); srcSheet.Copy(this.missing,aimSheet); //重命名 workSheet = (Excel.Worksheet)aimSheet.Next; 表 workSheet.Name = newSheetName; } catch(Exception e) { this.KillExcelProcess(); throw e; } }

//获取新拷贝的工作

/// <summary> /// 根据名称删除工作表 /// </summary> /// <param name="sheetName"></param> public void DeleteWorkSheet(string sheetName)

56

{ try { Excel.Worksheet sheet = null; //找到名称位 sheetName 的工作表 for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); if(workSheet.Name == sheetName) { sheet = workSheet; } } if(sheet != null) { sheet.Delete(); } else { this.KillExcelProcess(); throw new Exception("名称为\"" + sheetName + "\"的工作表不存 在"); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 根据索引删除工作表 /// </summary> /// <param name="sheetIndex"></param> public void DeleteWorkSheet(int sheetIndex) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于

57

WorkSheet 数量!"); } try { Excel.Worksheet sheet = null; sheet = (Excel.Worksheet)workBook.Sheets.get_Item(sheetIndex); sheet.Delete(); } catch(Exception e) { this.KillExcelProcess(); throw e; } } #endregion #region TextBox Methods /// <summary> /// 向指定文本框写入数据,对每个 WorkSheet 操作 /// </summary> /// <param name="textboxName">文本框名称</param> /// <param name="text">要写入的文本</param> public void SetTextBox(string textboxName,string text) { for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);

try { textBox = (Excel.TextBox)workSheet.TextBoxes(textboxName); textBox.Text = text; } catch { this.KillExcelProcess(); throw new Exception("不存在 ID 为\"" + textboxName + "\"的文本 框!"); } }

58

} /// <summary> /// 向指定文本框写入数据,对指定 WorkSheet 操作 /// </summary> /// <param name="sheetIndex">工作表索引</param> /// <param name="textboxName">文本框名称</param> /// <param name="text">要写入的文本</param> public void SetTextBox(int sheetIndex,string textboxName,string text) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); try { textBox = (Excel.TextBox)workSheet.TextBoxes(textboxName); textBox.Text = text; } catch { this.KillExcelProcess(); throw new Exception("不存在 ID 为\"" + textboxName + "\"的文本框! "); } } /// <summary> /// 向文本框写入数据,对每个 WorkSheet 操作 /// </summary> /// <param name="ht">Hashtable 的键值对保存文本框的 ID 和数据</param> public void SetTextBoxes(Hashtable ht) { if(ht.Count == 0) return; for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); foreach(DictionaryEntry dic in ht) { try { textBox = (Excel.TextBox)workSheet.TextBoxes(dic.Key); textBox.Text = dic.Value.ToString(); }

59

catch { this.KillExcelProcess(); throw new Exception("不存在 ID 为\"" + dic.Key.ToString() + "\"的文本框!"); } } } } /// <summary> /// 向文本框写入数据,对指定 WorkSheet 操作 /// </summary> /// <param name="ht">Hashtable 的键值对保存文本框的 ID 和数据</param> public void SetTextBoxes(int sheetIndex,Hashtable ht) { if(ht.Count == 0) return; if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); foreach(DictionaryEntry dic in ht) { try { textBox = (Excel.TextBox)workSheet.TextBoxes(dic.Key); textBox.Text = dic.Value.ToString(); } catch { this.KillExcelProcess(); throw new Exception("不存在 ID 为\"" + dic.Key.ToString() + "\"的 文本框!"); } } } #endregion

60

#region Cell Methods /// <summary> /// 向单元格写入数据,对当前 WorkSheet 操作 /// </summary> /// <param name="rowIndex">行索引</param> /// <param name="columnIndex">列索引</param> /// <param name="text">要写入的文本值</param> public void SetCells(int rowIndex,int columnIndex,string text) { try { workSheet.Cells[rowIndex,columnIndex] = text; } catch { this.KillExcelProcess(); throw new Exception("向单元格[" + rowIndex + "," + columnIndex + "] 写数据出错!"); } } /// <summary> /// 向单元格写入数据,对指定 WorkSheet 操作 /// </summary> /// <param name="sheetIndex">工作表索引</param> /// <param name="rowIndex">行索引</param> /// <param name="columnIndex">列索引</param> /// <param name="text">要写入的文本值</param> public void SetCells(int sheetIndex,int rowIndex,int columnIndex,string text) { try { this.ChangeCurrentWorkSheet(sheetIndex); //改变当前工作表为指 定工作表 workSheet.Cells[rowIndex,columnIndex] = text; } catch { this.KillExcelProcess(); throw new Exception("向单元格[" + rowIndex + "," + columnIndex + "] 写数据出错!"); } }

61

/// <summary> /// 向单元格写入数据,对每个 WorkSheet 操作 /// </summary> /// <param name="ht">Hashtable 的键值对保存单元格的位置索引 (行索引和列索 引用“,”隔开)和数据</param> public void SetCells(Hashtable ht) { int rowIndex; int columnIndex; string position; if(ht.Count == 0) return; for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); foreach(DictionaryEntry dic in ht) { try { position = dic.Key.ToString(); rowIndex = Convert.ToInt32(position.Split(',')[0]); columnIndex = Convert.ToInt32(position.Split(',')[1]); workSheet.Cells[rowIndex,columnIndex] = dic.Value; } catch { this.KillExcelProcess(); throw new Exception("向单元格[" + dic.Key + "]写数据出错! "); } } } } /// <summary> /// 向单元格写入数据,对指定 WorkSheet 操作 /// </summary> /// <param name="ht">Hashtable 的键值对保存单元格的位置索引 (行索引和列索 引用“,”隔开)和数据</param> public void SetCells(int sheetIndex,Hashtable ht) {

62

int rowIndex; int columnIndex; string position; if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } if(ht.Count == 0) return; workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); foreach(DictionaryEntry dic in ht) { try { position = dic.Key.ToString(); rowIndex = Convert.ToInt32(position.Split(',')[0]); columnIndex = Convert.ToInt32(position.Split(',')[1]); workSheet.Cells[rowIndex,columnIndex] = dic.Value; } catch { this.KillExcelProcess(); throw new Exception("向单元格[" + dic.Key + "]写数据出错!"); } } } /// <summary> /// 设置单元格为可计算的 /// </summary> /// <remarks> /// 如果 Excel 的单元格格式设置为数字,日期或者其他类型时,需要设置这些单 元格的 FormulaR1C1 属性, /// 否则写到这些单元格的数据将不会按照预先设定的格式显示 /// </remarks> /// <param name="arr">保存单元格的位置索引(行索引和列索引用“,”隔开) 和数据</param> public void SetCells(int sheetIndex,string[] arr)

63

{ int rowIndex; int columnIndex; string position; if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } if(arr.Length == 0) return; workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); for(int i=0;i<arr.Length;i++) { try { position = arr[i]; rowIndex = Convert.ToInt32(position.Split(',')[0]); columnIndex = Convert.ToInt32(position.Split(',')[1]); Excel.Range cell = (Excel.Range)workSheet.Cells[rowIndex,columnIndex]; cell.FormulaR1C1 = cell.Text; } catch { this.KillExcelProcess(); throw new Exception(string.Format("计算单元格{0}出错!",arr[i])); } } } /// <summary> /// 向单元格写入数据,对指定 WorkSheet 操作 /// </summary> /// <param name="ht">Hashtable 的键值对保存单元格的位置索引 (行索引和列索 引用“,”隔开)和数据</param> public void SetCells(string sheetName,Hashtable ht) { int rowIndex;

64

int columnIndex; string position; Excel.Worksheet sheet = null; int sheetIndex = 0; if(ht.Count == 0) return; try { for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); if(workSheet.Name == sheetName) { sheet = workSheet; sheetIndex = workSheet.Index; } } if(sheet != null) { foreach(DictionaryEntry dic in ht) { try { position = dic.Key.ToString(); rowIndex = Convert.ToInt32(position.Split(',')[0]); columnIndex = Convert.ToInt32(position.Split(',')[1]); sheet.Cells[rowIndex,columnIndex] = dic.Value; } catch { this.KillExcelProcess(); throw new Exception("向单元格[" + dic.Key + "]写数据出 错!"); } } } else { this.KillExcelProcess(); throw new Exception("名称为\"" + sheetName + "\"的工作表不存

65

在"); } } catch(Exception e) { this.KillExcelProcess(); throw e; } }

/// <summary> /// 合并单元格,并赋值,对每个 WorkSheet 操作 /// </summary> /// <param name="beginRowIndex">开始行索引</param> /// <param name="beginColumnIndex">开始列索引</param> /// <param name="endRowIndex">结束行索引</param> /// <param name="endColumnIndex">结束列索引</param> /// <param name="text">合并后 Range 的值</param> public void MergeCells(int beginRowIndex,int beginColumnIndex,int endRowIndex,int endColumnIndex,string text) { for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i); range = workSheet.get_Range(workSheet.Cells[beginRowIndex,beginColumnIndex],workSheet.Cell s[endRowIndex,endColumnIndex]); range.ClearContents(); //先把 Range 内容清除,合并才不会出错 range.MergeCells = true; range.Value = text; range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; } } /// <summary> /// 合并单元格,并赋值,对指定 WorkSheet 操作 /// </summary> /// <param name="sheetIndex">WorkSheet 索引</param> /// <param name="beginRowIndex">开始行索引</param> /// <param name="beginColumnIndex">开始列索引</param> /// <param name="endRowIndex">结束行索引</param>

66

/// <param name="endColumnIndex">结束列索引</param> /// <param name="text">合并后 Range 的值</param> public void MergeCells(int sheetIndex,int beginRowIndex,int beginColumnIndex,int endRowIndex,int endColumnIndex,string text) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); range = workSheet.get_Range(workSheet.Cells[beginRowIndex,beginColumnIndex],workSheet.Cell s[endRowIndex,endColumnIndex]); range.ClearContents(); //先把 Range 内容清除,合并才不会出错 range.MergeCells = true; range.Value = text; range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; } #endregion #region Row Methods /// <summary> /// 将指定索引列的数据相同的行合并,对每个 WorkSheet 操作 /// </summary> /// <param name="columnIndex">列索引</param> /// <param name="beginRowIndex">开始行索引</param> /// <param name="endRowIndex">结束行索引</param> public void MergeRows(int columnIndex,int beginRowIndex,int endRowIndex) { if(endRowIndex - beginRowIndex < 1) return; for(int i=1;i<=this.WorkSheetCount;i++) { int beginIndex = beginRowIndex; int count = 0; string text1; string text2; workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);

67

for(int j=beginRowIndex;j<=endRowIndex;j++) { range = (Excel.Range)workSheet.Cells[j,columnIndex]; text1 = range.Text.ToString(); range = (Excel.Range)workSheet.Cells[j+1,columnIndex]; text2 = range.Text.ToString(); if(text1 == text2) { ++count; } else { if(count > 0) { this.MergeCells(workSheet,beginIndex,columnIndex,beginIndex+count,columnIndex,text1); } beginIndex = j + 1; //设置开始合并行索引 count = 0; //计数器清 0 } } } }

/// <summary> /// 将指定索引列的数据相同的行合并,对指定 WorkSheet 操作 /// </summary> /// <param name="sheetIndex">WorkSheet 索引</param> /// <param name="columnIndex">列索引</param> /// <param name="beginRowIndex">开始行索引</param> /// <param name="endRowIndex">结束行索引</param> public void MergeRows(int sheetIndex,int columnIndex,int beginRowIndex,int endRowIndex) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess();

68

throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } if(endRowIndex - beginRowIndex < 1) return; int beginIndex = beginRowIndex; int count = 0; string text1; string text2; workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); for(int j=beginRowIndex;j<=endRowIndex;j++) { range = (Excel.Range)workSheet.Cells[j,columnIndex]; text1 = range.Text.ToString(); range = (Excel.Range)workSheet.Cells[j+1,columnIndex]; text2 = range.Text.ToString(); if(text1 == text2) { ++count; } else { if(count > 0) { this.MergeCells(workSheet,beginIndex,columnIndex,beginIndex+count,columnIndex,text1); } beginIndex = j + 1; //设置开始合并行索引 count = 0; //计数器清 0 } } }

/// <summary> /// 插行(在指定行上面插入指定数量行)

69

/// </summary> /// <param name="rowIndex"></param> /// <param name="count"></param> public void InsertRows(int rowIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; range = (Excel.Range)workSheet.Rows[rowIndex,this.missing]; for(int i=0;i<count;i++) { range.Insert(Excel.XlDirection.xlDown); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 插行(在指定 WorkSheet 指定行上面插入指定数量行) /// </summary> /// <param name="sheetIndex"></param> /// <param name="rowIndex"></param> /// <param name="count"></param> public void InsertRows(int sheetIndex,int rowIndex,int count) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; range = (Excel.Range)workSheet.Rows[rowIndex,this.missing];

70

for(int i=0;i<count;i++) { range.Insert(Excel.XlDirection.xlDown); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 复制行(在指定行下面复制指定数量行) /// </summary> /// <param name="rowIndex"></param> /// <param name="count"></param> public void CopyRows(int rowIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; range1 = (Excel.Range)workSheet.Rows[rowIndex,this.missing]; for(int i=1;i<=count;i++) { range2 = (Excel.Range)workSheet.Rows[rowIndex + i,this.missing]; range1.Copy(range2); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 复制行(在指定 WorkSheet 指定行下面复制指定数量行)

71

/// </summary> /// <param name="sheetIndex"></param> /// <param name="rowIndex"></param> /// <param name="count"></param> public void CopyRows(int sheetIndex,int rowIndex,int count) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; range1 = (Excel.Range)workSheet.Rows[rowIndex,this.missing]; for(int i=1;i<=count;i++) { range2 = (Excel.Range)workSheet.Rows[rowIndex + i,this.missing]; range1.Copy(range2); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 删除行 /// </summary> /// <param name="rowIndex"></param> /// <param name="count"></param> public void DeleteRows(int rowIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; range = (Excel.Range)workSheet.Rows[rowIndex,this.missing];

72

for(int i=0;i<count;i++) { range.Delete(Excel.XlDirection.xlDown); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 删除行 /// </summary> /// <param name="sheetIndex"></param> /// <param name="rowIndex"></param> /// <param name="count"></param> public void DeleteRows(int sheetIndex,int rowIndex,int count) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; range = (Excel.Range)workSheet.Rows[rowIndex,this.missing]; for(int i=0;i<count;i++) { range.Delete(Excel.XlDirection.xlDown); } } catch(Exception e) { this.KillExcelProcess(); throw e; }

73

} #endregion #region Column Methods /// <summary> /// 插列(在指定列右边插入指定数量列) /// </summary> /// <param name="columnIndex"></param> /// <param name="count"></param> public void InsertColumns(int columnIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; range = (Excel.Range)workSheet.Columns[this.missing,columnIndex]; for(int i=0;i<count;i++) { range.Insert(Excel.XlDirection.xlDown); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 插列(在指定 WorkSheet 指定列右边插入指定数量列) /// </summary> /// <param name="sheetIndex"></param> /// <param name="columnIndex"></param> /// <param name="count"></param> public void InsertColumns(int sheetIndex,int columnIndex,int count) { if(sheetIndex > this.WorkSheetCount) {

74

this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; range = (Excel.Range)workSheet.Columns[this.missing,columnIndex]; for(int i=0;i<count;i++) { range.Insert(Excel.XlDirection.xlDown); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 复制列(在指定列右边复制指定数量列) /// </summary> /// <param name="columnIndex"></param> /// <param name="count"></param> public void CopyColumns(int columnIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; // range1 = (Excel.Range)workSheet.Columns[columnIndex,this.missing]; range1 = (Excel.Range)workSheet.get_Range(this.IntToLetter(columnIndex)+"1",this.IntToLetter(col umnIndex)+"10000"); for(int i=1;i<=count;i++) { // range2 = (Excel.Range)workSheet.Columns[this.missing,columnIndex + i];

75

range2 = (Excel.Range)workSheet.get_Range(this.IntToLetter(columnIndex+i)+"1",this.IntToLetter( columnIndex+i)+"10000"); range1.Copy(range2); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 复制列(在指定 WorkSheet 指定列右边复制指定数量列) /// </summary> /// <param name="sheetIndex"></param> /// <param name="columnIndex"></param> /// <param name="count"></param> public void CopyColumns(int sheetIndex,int columnIndex,int count) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; // range1 = (Excel.Range)workSheet.Columns[Type.Missing,columnIndex]; range1 = (Excel.Range)workSheet.get_Range(this.IntToLetter(columnIndex)+"1",this.IntToLetter(col umnIndex)+"10000"); for(int i=1;i<=count;i++) { // range2 = (Excel.Range)workSheet.Columns[Type.Missing,columnIndex + i]; range2 = (Excel.Range)workSheet.get_Range(this.IntToLetter(columnIndex+i)+"1",this.IntToLetter( columnIndex+i)+"10000");

76

range1.Copy(range2); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 删除列 /// </summary> /// <param name="columnIndex"></param> /// <param name="count"></param> public void DeleteColumns(int columnIndex,int count) { try { for(int n=1;n<=this.WorkSheetCount;n++) { workSheet = (Excel.Worksheet)workBook.Worksheets[n]; range = (Excel.Range)workSheet.Columns[this.missing,columnIndex]; for(int i=0;i<count;i++) { range.Delete(Excel.XlDirection.xlDown); } } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 删除列 /// </summary> /// <param name="sheetIndex"></param> /// <param name="columnIndex"></param> /// <param name="count"></param>

77

public void DeleteColumns(int sheetIndex,int columnIndex,int count) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于 WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets[sheetIndex]; range = (Excel.Range)workSheet.Columns[this.missing,columnIndex]; for(int i=0;i<count;i++) { range.Delete(Excel.XlDirection.xlDown); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } #endregion #region Range Methods /// <summary> /// 将指定范围区域拷贝到目标区域 /// </summary> /// <param name="sheetIndex">WorkSheet 索引</param> /// <param name="startCell">要拷贝区域的开始 Cell 位置 (比如: A10) </param> /// <param name="endCell">要拷贝区域的结束 Cell 位置(比如:F20)</param> /// <param name="targetCell">目标区域的开始 Cell 位置(比如:H10)</param> public void RangeCopy(int sheetIndex,string startCell,string endCell,string targetCell) { if(sheetIndex > this.WorkSheetCount) { this.KillExcelProcess(); throw new Exception("索引超出范围,WorkSheet 索引不能大于

78

WorkSheet 数量!"); } try { workSheet = (Excel.Worksheet)workBook.Worksheets.get_Item(sheetIndex); range1 = workSheet.get_Range(startCell,endCell); range2 = workSheet.get_Range(targetCell,this.missing); range1.Copy(range2); } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 将指定范围区域拷贝到目标区域 /// </summary> /// <param name="sheetName">WorkSheet 名称</param> /// <param name="startCell">要拷贝区域的开始 Cell 位置 (比如: A10) </param> /// <param name="endCell">要拷贝区域的结束 Cell 位置(比如:F20)</param> /// <param name="targetCell">目标区域的开始 Cell 位置(比如:H10)</param> public void RangeCopy(string sheetName,string startCell,string endCell,string targetCell) { try { Excel.Worksheet sheet = null; for(int i=1;i<=this.WorkSheetCount;i++) { workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(i); if(workSheet.Name == sheetName) { sheet = workSheet; } } if(sheet != null)

79

{ for(int i=sheetCount;i>=1;i--) { range1 = sheet.get_Range(startCell,endCell); range2 = sheet.get_Range(targetCell,this.missing); range1.Copy(range2); } } else { this.KillExcelProcess(); throw new Exception("名称为\"" + sheetName + "\"的工作表不存 在"); } } catch(Exception e) { this.KillExcelProcess(); throw e; } } /// <summary> /// 自动填充 /// </summary> public void RangAutoFill() { Excel.Range rng = workSheet.get_Range("B4", Type.Missing); rng.Value2 = "星期一 "; rng.AutoFill(workSheet.get_Range("B4","B9"), Excel.XlAutoFillType.xlFillWeekdays); rng = workSheet.get_Range("C4", Type.Missing); rng.Value = "一月"; rng.AutoFill(workSheet.get_Range("C4","C9"), Excel.XlAutoFillType.xlFillMonths); rng = workSheet.get_Range("D4",Type.Missing); rng.Value2 = "1"; rng.AutoFill(workSheet.get_Range("D4","D9"), Excel.XlAutoFillType.xlFillSeries); rng = workSheet.get_Range("E4",Type.Missing);

80

rng.Value2 = "3"; rng = workSheet.get_Range("E5",Type.Missing); rng.Value2 = "6"; rng = workSheet.get_Range("E4","E5"); rng.AutoFill(workSheet.get_Range("E4","E9"), Excel.XlAutoFillType.xlFillSeries); } /// <summary> /// 应用样式 /// </summary> public void ApplyStyle() { object missingValue = Type.Missing; Excel.Range rng = workSheet.get_Range("B3","L23"); Excel.Style style; try { style = workBook.Styles["NewStyle"]; } // Style doesn't exist yet. catch { style = workBook.Styles.Add("NewStyle", missingValue); style.Font.Name = "Verdana"; style.Font.Size = 12; style.Font.Color = 255; style.Interior.Color = (200 << 16) | (200 << 8) | 200; style.Interior.Pattern = Excel.XlPattern.xlPatternSolid; } rng.Value2 = "'Style Test"; rng.Style = "NewStyle"; rng.Columns.AutoFit(); } #endregion #region ExcelHelper Kit /// <summary> /// 将 Excel 列的字母索引值转换成整数索引值 /// </summary>

81

/// <param name="letter"></param> /// <returns></returns> public int LetterToInt(string letter) { int n = 0; if(letter.Trim().Length == 0) throw new Exception("不接受空字符串!"); if(letter.Length >= 2) { char c1 = letter.ToCharArray(0,2)[0]; char c2 = letter.ToCharArray(0,2)[1]; if(!char.IsLetter(c1) || !char.IsLetter(c2)) { throw new Exception("格式不正确,必须是字母!"); } c1 = char.ToUpper(c1); c2 = char.ToUpper(c2); int i = Convert.ToInt32(c1) - 64; int j = Convert.ToInt32(c2) - 64; n = i * 26 + j; } if(letter.Length == 1) { char c1 = letter.ToCharArray()[0]; if(!char.IsLetter(c1)) { throw new Exception("格式不正确,必须是字母!"); } c1 = char.ToUpper(c1); n = Convert.ToInt32(c1) - 64; } if(n > 256) throw new Exception("索引超出范围,Excel 的列索引不能超过 256!");

82

return n; } /// <summary> /// 将 Excel 列的整数索引值转换为字符索引值 /// </summary> /// <param name="n"></param> /// <returns></returns> public string IntToLetter(int n) { if(n > 256) throw new Exception("索引超出范围,Excel 的列索引不能超过 256!"); int i = Convert.ToInt32(n / 26); int j = n % 26; char c1 = Convert.ToChar( i + 64 ); char c2 = Convert.ToChar( j + 64 ); if(n > 26) return c1.ToString() + c2.ToString(); else if(n == 26) return "Z"; else return c2.ToString(); } #endregion #region Output File(注意:如果目标文件已存在的话会出错) /// <summary> /// 输出 Excel 文件并退出 /// </summary> public void OutputExcelFile() { if(this.outputFile == null) throw new Exception("没有指定输出文件路径!"); try { workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAcces sMode.xlExclusive,missing,missing,missing,missing);

83

} catch(Exception e) { throw e; } finally { this.Dispose(); } } /// <summary> /// 输出指定格式的文件(支持格式:HTML,CSV,TEXT,EXCEL) /// </summary> /// <param name="format">HTML,CSV,TEXT,EXCEL,XML</param> public void OutputFile(string format) { if(this.outputFile == null) throw new Exception("没有指定输出文件路径!"); try { switch(format) { case "HTML": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,E xcel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "CSV": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlCSV,missing,missing,missing,missing,Ex cel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "TEXT": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,E xcel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break;

84

// // // workBook.SaveAs(outputFile,Excel.XlFileFormat.xlXMLSpreadsheet, Type.Missing, Type.Missing, // Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, // Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // break; // // } default: { workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAcces sMode.xlExclusive,missing,missing,missing,missing); break; } } } catch(Exception e) { throw e; } finally { this.Dispose(); } } /// <summary> /// 保存文件 /// </summary> public void SaveFile() { try { workBook.Save(); } catch(Exception e) { throw e;

} case "XML": {

85

} finally { this.Dispose(); } } /// <summary> /// 另存文件 /// </summary> public void SaveAsFile() { if(this.outputFile == null) throw new Exception("没有指定输出文件路径!"); try { workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAcces sMode.xlExclusive,missing,missing,missing,missing); } catch(Exception e) { throw e; } finally { this.Dispose(); } } /// <summary> /// 将 Excel 文件另存为指定格式 /// </summary> /// <param name="format">HTML,CSV,TEXT,EXCEL,XML</param> public void SaveAsFile(string format) { if(this.outputFile == null) throw new Exception("没有指定输出文件路径!"); try { switch(format) {

86

case "HTML": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,E xcel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "CSV": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlCSV,missing,missing,missing,missing,Ex cel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "TEXT": { workBook.SaveAs(outputFile,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,E xcel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } // case "XML": // { // workBook.SaveAs(outputFile,Excel.XlFileFormat.xlXMLSpreadsheet, Type.Missing, Type.Missing, // Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, // Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // break; // } default: { workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAcces sMode.xlExclusive,missing,missing,missing,missing); break; } } } catch(Exception e) { throw e;

87

} finally { this.Dispose(); } } /// <summary> /// 另存文件 /// </summary> /// <param name="fileName">文件名</param> public void SaveFile(string fileName) { try { workBook.SaveAs(fileName,missing,missing,missing,missing,missing,Excel.XlSaveAsAccess Mode.xlExclusive,missing,missing,missing,missing); } catch(Exception e) { throw e; } finally { this.Dispose(); } } /// <summary> /// 将 Excel 文件另存为指定格式 /// </summary> /// <param name="fileName">文件名</param> /// <param name="format">HTML,CSV,TEXT,EXCEL,XML</param> public void SaveAsFile(string fileName,string format) { try { switch(format) { case "HTML": { workBook.SaveAs(fileName,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,Ex

88

cel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "CSV": { workBook.SaveAs(fileName,Excel.XlFileFormat.xlCSV,missing,missing,missing,missing,Exc el.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } case "TEXT": { workBook.SaveAs(fileName,Excel.XlFileFormat.xlHtml,missing,missing,missing,missing,Ex cel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing); break; } // case "XML": // { // workBook.SaveAs(fileName,Excel.XlFileFormat.xlXMLSpreadsheet, Type.Missing, Type.Missing, // Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, // Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // break; // } default: { workBook.SaveAs(fileName,missing,missing,missing,missing,missing,Excel.XlSaveAsAccess Mode.xlExclusive,missing,missing,missing,missing); break; } } } catch(Exception e) { throw e; } finally { this.Dispose();

89

} } #endregion #endregion #region 私有方法 /// <summary> /// 合并单元格,并赋值,对指定 WorkSheet 操作 /// </summary> /// <param name="beginRowIndex">开始行索引</param> /// <param name="beginColumnIndex">开始列索引</param> /// <param name="endRowIndex">结束行索引</param> /// <param name="endColumnIndex">结束列索引</param> /// <param name="text">合并后 Range 的值</param> private void MergeCells(Excel.Worksheet sheet,int beginRowIndex,int beginColumnIndex,int endRowIndex,int endColumnIndex,string text) { if(sheet == null) return; range = sheet.get_Range(sheet.Cells[beginRowIndex,beginColumnIndex],sheet.Cells[endRowIndex,e ndColumnIndex]); range.ClearContents(); //先把 Range 内容清除,合并才不会出错 range.MergeCells = true; range.Value = text; range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter; range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter; } /// <summary> /// 将指定索引列的数据相同的行合并,对指定 WorkSheet 操作 /// </summary> /// <param name="columnIndex">要合并的列索引</param> /// <param name="beginRowIndex">合并开始行索引</param> /// <param name="rows">要合并的行数</param> private void MergeRows(Excel.Worksheet sheet,int columnIndex,int beginRowIndex,int rows) { int beginIndex = beginRowIndex; int count = 0;

90

string text1; string text2; if(sheet == null) return; for(int j=beginRowIndex;j<beginRowIndex+rows;j++) { range1 = (Excel.Range)sheet.Cells[j,columnIndex]; range2 = (Excel.Range)sheet.Cells[j+1,columnIndex]; text1 = range1.Text.ToString(); text2 = range2.Text.ToString(); if(text1 == text2) { ++count; } else { if(count > 0) { this.MergeCells(sheet,beginIndex,columnIndex,beginIndex+count,columnIndex,text1); } beginIndex = j + 1; //设置开始合并行索引 count = 0; //计数器清 0 } } }

/// <summary> /// 计算 WorkSheet 数量 /// </summary> /// <param name="rowCount">记录总行数</param> /// <param name="rows">每 WorkSheet 行数</param> public int GetSheetCount(int rowCount,int rows) { int n = rowCount % rows; //余数 if(n == 0)

91

return rowCount / rows; else return Convert.ToInt32(rowCount / rows) + 1; } /// <summary> /// 结束 Excel 进程 /// </summary> public void KillExcelProcess() { Process[] myProcesses; DateTime startTime; myProcesses = Process.GetProcessesByName("Excel"); //得不到 Excel 进程 ID,暂时只能判断进程启动时间 foreach(Process myProcess in myProcesses) { startTime = myProcess.StartTime; if(startTime > beforeTime && startTime < afterTime) { myProcess.Kill(); } } }

private void Dispose() { workBook.Close(null,null,null); app.Workbooks.Close(); app.Quit(); if(range != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(range); range = null; } if(range1 != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(range1); range1 = null; } if(range2 != null)

92

{ System.Runtime.InteropServices.Marshal.ReleaseComObject(range2); range2 = null; } if(textBox != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(textBox); textBox = null; } if(workSheet != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet); workSheet = null; } if(workBook != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook); workBook = null; } if(app != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(app); app = null; } GC.Collect(); this.KillExcelProcess(); }//end Dispose #endregion

}//end class }//end namespace

93

C#操作 EXCEL 全解(代码) 提示:运行之前必须先引用 Interop.Excel.dll 模块 using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.OleDb; using System.Windows.Forms; using System.Reflection; using Excel; namespace AnalysisSystem.DB { public class ExcelOperation { private string _fileName;//保存路径名 public ExcelOperation(string fileName) { _fileName = fileName; } private OleDbConnection GetConnection() { string connectString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0",_fileName); OleDbConnection myConn = new OleDbConnection(connectString);//建立链 接 return myConn; } public System.Data.DataTable ExecuteTableResult(string strSql) { System.Data.DataTable dt = new System.Data.DataTable(); try { OleDbConnection conn = this.GetConnection(); OleDbDataAdapter da = new OleDbDataAdapter(strSql, conn);//执行相 关 SQL 语句 da.Fill(dt); } catch (System.Exception ex)

94

{ //do nothing } return dt; } public DataSet ExecuteSetResult(string strSql,string table_name) { DataSet ds = new DataSet(); string temp_name = "[" + table_name + "$]"; try { OleDbConnection conn = this.GetConnection(); OleDbDataAdapter da = new OleDbDataAdapter(strSql, conn); da.Fill(ds,temp_name); } catch (System.Exception ex) { //do nothing } return ds; } public string ExecuteOneResult(string strSql) { string result = ""; System.Data.DataTable dt = new System.Data.DataTable(); try { OleDbConnection conn = this.GetConnection(); OleDbDataAdapter da = new OleDbDataAdapter(strSql, conn); da.Fill(dt); } catch (System.Exception ex) { //do nothing } if (dt != null && dt.Rows.Count > 0) { result = dt.Rows[0][0].ToString(); } return result; }

95

public void ExecuteNonResult(string strSql) { try { OleDbConnection conn = this.GetConnection(); OleDbCommand cmd = new OleDbCommand(strSql, conn); cmd.ExecuteNonQuery(); } catch (System.Exception ex) { //do nothing } }

private _Workbook W_B(Excel.Application app) { Workbooks workbooks = app.Workbooks; _Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet); return workbook; } private _Worksheet W_S(_Workbook work_book) { Sheets sheets = work_book.Worksheets; _Worksheet worksheet = (_Worksheet)sheets.get_Item(1);//获取选择第一个 表,本身默认名称为 Sheet1 return worksheet; } //从 DataGridView 中导出数据到 Excel 表,单表导出 public void Excel_out(DataGridView dataGridView1) { //建立 Excel 对象 Excel.Application app = new Excel.Application(); try { _Workbook workbook = this.W_B(app); _Worksheet worksheet = this.W_S(workbook); string sLen = ""; //取得最后一列列名 char H = (char)(64 + dataGridView1.ColumnCount / 26); char L = (char)(64 + dataGridView1.ColumnCount % 26);

96

if (dataGridView1.ColumnCount < 26) { sLen = L.ToString(); } else { sLen = H.ToString() + L.ToString(); } //标题 string sTmp = sLen + "1"; Range ranCaption = worksheet.get_Range(sTmp, "A1"); string[] asCaption = new string[dataGridView1.ColumnCount]; for (int i = 0; i < dataGridView1.ColumnCount; i++) { asCaption[i] = dataGridView1.Columns[i].HeaderText; } ranCaption.Value2 = asCaption; //数据 object[] obj = new object[dataGridView1.Columns.Count]; for (int r = 0; r < dataGridView1.RowCount - 1; r++) { for (int l = 0; l < dataGridView1.Columns.Count; l++) { if (dataGridView1[l, r].ValueType == typeof(DateTime)) { obj[l] = dataGridView1[l, r].Value.ToString(); } else { obj[l] = dataGridView1[l, r].Value; } } string cell1 = sLen + ((int)(r + 2)).ToString(); string cell2 = "A" + ((int)(r + 2)).ToString(); Range ran = worksheet.get_Range(cell1, cell2); ran.Value2 = obj; } //保存 workbook.SaveCopyAs(this._fileName); workbook.Saved = true; } finally {

97

//关闭 app.UserControl = false; app.Quit(); } } /// <summary> /// 多表导出 /// </summary> /// <param name="dataGridView">DataGridView 列表集合</param> /// <param name="TableList">表名称集合</param> public void Excel_out_MulTable(List<DataGridView> dataGridView, string[] TableList) { //建立 Excel 对象 Excel.Application app = new Excel.Application(); try { Workbooks workbooks = app.Workbooks;//定义一个工作簿集合 _Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet);//向工作簿添加一个新工作簿 Sheets sheets = workbook.Worksheets;//定义一个工作表集合 _Worksheet worksheet ; int wnumber = 0; while (wnumber++ < (TableList.GetLength(0) - 1)) { sheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);//向一个工作表集合添加一个新工作表 } /*提醒:Missing 类为命名空间 System.Reflection 中的类,所以记得引入 */ wnumber = 0; foreach (DataGridView dataGridView1 in dataGridView) { worksheet = null; worksheet = (_Worksheet)sheets.get_Item(wnumber + 1);//取出需要 进行操作的工作表 worksheet.Name = TableList[wnumber];//设置改工作表名称 if (wnumber != 0) sheets.Select(wnumber);//选中操作表

98

string sLen = ""; //取得最后一列列名 char H = (char)(64 + dataGridView1.ColumnCount / 26); char L = (char)(64 + dataGridView1.ColumnCount % 26); if (dataGridView1.ColumnCount < 26) { sLen = L.ToString(); } else { sLen = H.ToString() + L.ToString(); } //标题 string sTmp = sLen + "1"; Range ranCaption = worksheet.get_Range(sTmp, "A1"); string[] asCaption = new string[dataGridView1.ColumnCount]; for (int i = 0; i < dataGridView1.ColumnCount; i++) { asCaption[i] = dataGridView1.Columns[i].HeaderText; } ranCaption.Value2 = asCaption; //数据 object[] obj = new object[dataGridView1.Columns.Count]; for (int r = 0; r < dataGridView1.RowCount - 1; r++) { for (int l = 0; l < dataGridView1.Columns.Count; l++) { if (dataGridView1[l, r].ValueType == typeof(DateTime)) { obj[l] = dataGridView1[l, r].Value.ToString(); } else { obj[l] = dataGridView1[l, r].Value; } } string cell1 = sLen + ((int)(r + 2)).ToString(); string cell2 = "A" + ((int)(r + 2)).ToString(); Range ran = worksheet.get_Range(cell1, cell2);//设置单元格 ran.Value2 = obj;

99

} wnumber++; } //保存 workbook.SaveCopyAs(this._fileName); workbook.Saved = true; } finally { //关闭 app.UserControl = false; app.Quit(); } } } }

100


相关文章:
c#操作excel文件后如何释放进程
c#操作excel文件后如何释放进程_计算机软件及应用_IT/计算机_专业资料。使用 C#操作 Excel 的 COM 组件的过程中,最后把 EXCEL 进程关闭掉是十分重要的。 首先第一...
在C#中操作excel之excel.dll方法大全
C#操作excel之excel.dll方法大全_计算机软件及应用_IT/计算机_专业资料。在C#操作excel之excel.dll方法大全,提供了方法名和方法作用 ...
C# 操作Excel单元格格式
C# 操作 Excel 单元格格式内容摘要: 内容摘要:range.NumberFormatLocal = "@"; //设置单元格格式为文本 range = (Range)worksheet.get_Range("A1", "E1");...
C#关于excel 操作
C#中创建、打开、读取、写入、保存 Excel 的一般性代码[转] Excel 对象 微软的 Excel 对象模型包括了 128 个不同的对象,从矩形,文本框等简单的 对象到透视表,...
C#操作Excel文件(读取Excel,写入Excel)
C#操作Excel文件(读取Excel,写入Excel)_计算机软件及应用_IT/计算机_专业资料。C#操作Excel文件(读取Excel,写入Excel) 1.加载 Excel(读取 excel 内容)返回值是一个...
C#生成Excel各种操作
C#生成Excel各种操作_计算机软件及应用_IT/计算机_专业资料。C#生成Excel各种操作C#操作 Excel 总结 Posted on 2010-06-03 00:31 wang_yb 阅读(2754) 评论(2)...
最全的C#操作Excel表格技巧
最全的C#操作Excel表格技巧_电脑基础知识_IT/计算机_专业资料 暂无评价|0人阅读|0次下载|举报文档 最全的C#操作Excel表格技巧_电脑基础知识_IT/计算机_专业资料。...
C#读取Excel的三种方式以及比较分析
C#读取 Excel 的三种方式以及比较分析 投稿:mdxy-dxy 字体:[增加 减小] 类型:转载 时间:2015-11-08 我要评论 这篇文章主要介绍了 C#读取 Excel 的三种方式...
C# 操作Excel
C# 操作Excel_计算机软件及应用_IT/计算机_专业资料。C#将数据保存到 Excel 中第一步:首先添加两个组件: 打开解决方案资资源管理器,右键点击“引用” ,选择“...
C#Excel操作
C#Excel操作_IT/计算机_专业资料。C#操作 Excel 电子表格 操作 2011-01-21 12:51:47| 分类: 默认分类 | 标签: |字号大中小 订阅 添加引用:Microsoft Excel ...
更多相关标签:
c 操作excel 类库 | c语言操作excel | c excel操作类 | c对excel的操作 | c excel 操作类库 | c 操作excel文件 | excel里 c 2怎么操作 | c如何操作excel |