基本思路基础实现方法同上篇文章《直接通过ODBC读、写Excel表格文件》相同,都是通过ODBC来把Excel表格文件当成数据库文件来进行读、写等操作,所以在Excel表格文件中写入的行头名必须是唯一的(不要重名,相当于数据库中的ID值)。
本文中对Excel文件的操作都被封装进一个类CSpreadSheet中,通过它我们可以非常简便的实现各种Excel表格数据操作,并且可以对该类进行扩充来满足自己的需求。具体实现 一、包含Excel文件操作类头文件 #include "CSpreadSheet.h" 二、新建Excel文件,并写入默认数据 // 新建Excel文件名及路径,TestSheet为内部表名CSpreadSheet SS("c:\\Test.xls", "TestSheet");CStringArray sampleArray, testRow;SS.BeginTransaction();// 加入标题sampleArray.RemoveAll();sampleArray.Add("姓名");sampleArray.Add("年龄");SS.AddHeaders(sampleArray);// 加入数据CString strName[] = {"徐景周","徐志慧","郭徽","牛英俊","朱小鹏"};CString strAge[] = {"27","23","28","27","26"};for(int i = 0; i < sizeof(strName)/sizeof(CString); i++){ sampleArray.RemoveAll(); sampleArray.Add(strName[i]); sampleArray.Add(strAge[i]); SS.AddRow(sampleArray);}SS.Commit(); 三、读取Excel文件数据 CSpreadSheet SS("c:\\Test.xls", "TestSheet");CStringArray Rows, Column;//清空列表框m_AccessList.ResetContent();for (int i = 1; i <= SS.GetTotalRows(); i++){ // 读取一行 SS.ReadRow(Rows, i); CString strContents = ""; for (int j = 1; j <= Rows.GetSize(); j++) { if(j == 1) strContents = Rows.GetAt(j-1); else strContents = strContents + " --> " + Rows.GetAt(j-1); } m_AccessList.AddString(strContents);} 四、对已存在Excel表格数据进行添加、插入、替换操作 // 初始化测试行数据,进行添加、插入及替换数据操作演示for (int k = 1; k <= 2; k++){ testRow.Add("Test");}SS.AddRow(testRow); // 添加到尾部SS.AddRow(testRow, 2); // 插入新行到第二行SS.AddRow(testRow, 6, true); // 替换原第四行来新的内容SS.AddCell("徐景周", 1,2); // 添加(不存在)或替换(存在)第二行,第一列单元格内容SS.Commit(); 五、对已存在Excel表格数据进行行、列、单元格查询void CExcelAccessDlg::OnQuery() { CSpreadSheet SS("c:\\Test.xls", "TestSheet"); CStringArray Rows, Column; CString tempString = ""; UpdateData(); if(m_strRow == "" && m_strColumn == "") // 查询为空 { AfxMessageBox("行号、列号不能同时为空!"); return; } else if(m_strRow == "" && m_strColumn != "") // 查询指定列数据 { int iColumn = atoi(m_strColumn); int iCols = SS.GetTotalColumns(); if(iColumn > iCols) // 超出表范围查询时 { CString str; str.Format("表中总列数为: %d, ", iCols); AfxMessageBox(str + " 查询列数大于Excel表中总列数,请重新输入!"); return; } // 读取一列数据,并按行读出 if(!SS.ReadColumn(Column, iColumn)) { AfxMessageBox(SS.GetLastError()); return; } CString tmpStr; for (int i = 0; i < Column.GetSize(); i++) { tmpStr.Format("行号: %d, 列号: %d ,内容: %s\n", i+1,iColumn,Column.GetAt(i)); tempString += tmpStr; } AfxMessageBox(tempString); } else if(m_strRow != "" && m_strColumn == "") // 查询指定行数数据 { int iRow = atoi(m_strRow); int iRows = SS.GetTotalRows(); if(iRow > iRows) // 超出表范围查询时 { CString str; str.Format("表中总行数为: %d, ", iRows); AfxMessageBox(str + " 查询行数大于Excel表中总行数,请重新输入!"); return; } // 读取指定行数据 if(!SS.ReadRow(Rows, iRow)) { AfxMessageBox(SS.GetLastError()); return; } CString tmpStr; for (int i = 0; i < Rows.GetSize(); i++) { tmpStr.Format("行号: %d, 列号: %d ,内容: %s\n", iRow, i+1, Rows.GetAt(i)); tempString += tmpStr; } AfxMessageBox(tempString); } else if(m_strRow != "" && m_strColumn != "") // 查询指定单元格数据 { int iRow = atoi(m_strRow), iColumn = atoi(m_strColumn); int iRows = SS.GetTotalRows(), iCols = SS.GetTotalColumns(); if(iColumn > iCols) // 超出表范围查询时 { CString str; str.Format("表中总列数为: %d, ", iCols); AfxMessageBox(str + " 查询列数大于Excel表中总列数,请重新输入!"); return; } else if(iRow > iRows) { CString str; str.Format("表中总行数为: %d, ", iRows); AfxMessageBox(str + " 查询行数大于Excel表中总行数,请重新输入!"); return; } // 读取指定行、列单元格数据 if(!SS.ReadCell(tempString, iColumn, iRow)) { AfxMessageBox(SS.GetLastError()); return; } CString str; str.Format("行号: %d, 列号: %d ,内容: %s", iRow,iColumn,tempString); AfxMessageBox(str); }} 六、将存在的Excel转换另存为指定分隔的文本文件 // 将原Excel文件转换为用分号分隔的文本,并另存为同名文本文件SS。
基本思路基础实现方法同上篇文章《直接通过ODBC读、写Excel表格文件》相同,都是通过ODBC来把Excel表格文件当成数据库文件来进行读、写等操作,所以在Excel表格文件中写入的行头名必须是唯一的(不要重名,相当于数据库中的ID值)。
本文中对Excel文件的操作都被封装进一个类CSpreadSheet中,通过它我们可以非常简便的实现各种Excel表格数据操作,并且可以对该类进行扩充来满足自己的需求。具体实现 一、包含Excel文件操作类头文件 #include "CSpreadSheet.h" 二、新建Excel文件,并写入默认数据 // 新建Excel文件名及路径,TestSheet为内部表名CSpreadSheet SS("c:\\Test.xls", "TestSheet");CStringArray sampleArray, testRow;SS.BeginTransaction();// 加入标题sampleArray.RemoveAll();sampleArray.Add("姓名");sampleArray.Add("年龄");SS.AddHeaders(sampleArray);// 加入数据CString strName[] = {"徐景周","徐志慧","郭徽","牛英俊","朱小鹏"};CString strAge[] = {"27","23","28","27","26"};for(int i = 0; i " + Rows.GetAt(j-1); } m_AccessList.AddString(strContents);} 四、对已存在Excel表格数据进行添加、插入、替换操作 // 初始化测试行数据,进行添加、插入及替换数据操作演示for (int k = 1; k iCols) // 超出表范围查询时 { CString str; str.Format("表中总列数为: %d, ", iCols); AfxMessageBox(str + " 查询列数大于Excel表中总列数,请重新输入!"); return; } // 读取一列数据,并按行读出 if(!SS.ReadColumn(Column, iColumn)) { AfxMessageBox(SS.GetLastError()); return; } CString tmpStr; for (int i = 0; i iRows) // 超出表范围查询时 { CString str; str.Format("表中总行数为: %d, ", iRows); AfxMessageBox(str + " 查询行数大于Excel表中总行数,请重新输入!"); return; } // 读取指定行数据 if(!SS.ReadRow(Rows, iRow)) { AfxMessageBox(SS.GetLastError()); return; } CString tmpStr; for (int i = 0; i iCols) // 超出表范围查询时 { CString str; str.Format("表中总列数为: %d, ", iCols); AfxMessageBox(str + " 查询列数大于Excel表中总列数,请重新输入!"); return; } else if(iRow > iRows) { CString str; str.Format("表中总行数为: %d, ", iRows); AfxMessageBox(str + " 查询行数大于Excel表中总行数,请重新输入!"); return; } // 读取指定行、列单元格数据 if(!SS.ReadCell(tempString, iColumn, iRow)) { AfxMessageBox(SS.GetLastError()); return; } CString str; str.Format("行号: %d, 列号: %d ,内容: %s", iRow,iColumn,tempString); AfxMessageBox(str); }} 六、将存在的Excel转换另存为指定分隔的文本文件 // 将原Excel文件转换为用分号分隔的文本,并另存为同名文本文件SS.Convert(";"); 七、删除Excel中表格 SS. DeleteSheet(); // 删除Excel文件中所有表格SS. DeleteSheet(" TestSheet "); // 删除Excel中TextSheet表格 八、获取Excel中总行数、总列数、当前行 int iCols = SS.GetTotalColumns(); // 总列数int iRows = SS.GetTotalRows(); // 总行数int iCurRow = SS.GetCurrentRow(); // 当前所在行号 九、获取行头数据 CStringArray rowHeader;SS.GetFieldNames(rowHeader);CString tmpStr;for (int i = 0; i 评论0 0 0。
简单的方法是通过ODBC来实现:
具体实现
一、包含Excel文件操作类头文件
#include "CSpreadSheet.h"
二、新建Excel文件,并写入默认数据// 新建Excel文件名及路径,TestSheet为内部表名
CSpreadSheet SS("c:\\Test.xls", "TestSheet");
CStringArray sampleArray, testRow;
SS.BeginTransaction();// 加入标题
sampleArray.RemoveAll();
sampleArray.Add("姓名");
sampleArray.Add("年龄");
SS.AddHeaders(sampleArray);// 加入数据
CString strName[] = {"徐景周","徐志慧","郭徽","牛英俊","朱小鹏"};
CString strAge[] = {"27","23","28","27","26"};
for(int i = 0; i < sizeof(strName)/sizeof(CString); i++)
{
sampleArray.RemoveAll();
sampleArray.Add(strName[i]);
sampleArray.Add(strAge[i]);
SS.AddRow(sampleArray);
}
SS.Commit();
三、读取Excel文件数据
CSpreadSheet SS("c:\\Test.xls", "TestSheet");
CStringArray Rows, Column;//清空列表框
m_AccessList.ResetContent();
for (int i = 1; i <= SS.GetTotalRows(); i++)
{// 读取一行
SS.ReadRow(Rows, i);
CString strContents = "";
for (int j = 1; j <= Rows.GetSize(); j++)
{
if(j == 1)
strContents = Rows.GetAt(j-1);
else
strContents = strContents + " --> " + Rows.GetAt(j-1);
}
m_AccessList.AddString(strContents);
}
1、Excel中用函数返回行和列交叉位置的值需要使用Index函数。
2、index函数的使用格式为:INDEX(array,row_num,column_num)。 3、其中,Array代表单元格区域或数组常量;Row_num表示指定的行序号(如果省略row_num,则必须有column_num);Column_num表示指定的列序号(如果省略column_num,则必须有row_num)。
4、在函数使用中,需要注意到参数的行序号参数(row_num)和列序号参数(column_num)是相对于所引用的单元格区域而言的,不是Excel工作表中的行或列序号。 5、在图示的例子中,我们输入函数:=INDEX($A$11:$B$15,MATCH(D11,A11:A15,0),2)来查找张3的分数。
6、函数输入后,按下Enter键,即在输入函数的空白单元格中显示找到的张3分数“65”。
//创建一个数据链接 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = 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 , myConn ) ; 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 { private Button button1 ; private System.Data.DataSet myDataSet ; private DataGrid DataGrid1 ; private 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 Source = 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 , myConn ) ; file://创建一个 DataSet对象 myDataSet = new DataSet ( ) ; file://得到自己的DataSet对象 myCommand.Fill ( myDataSet , "[Sheet1$]" ) ; file://关闭此数据链接 myConn.Close ( ) ; } private void InitializeComponent ( ) { 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 ( ) ) ; } } 下图是程序编译后,运行结果:/20020313/jt-2002-3-13-image001.webp 图01:用Visual C#读取"c:\sample.xls"的运行界面 (4).总结: 以上只是读取了Excel表格中"Sheet1"中的数据,对于其他"Sheet"中的内容,可以参照读取"Sheet1"中的程序,只作一点修改就可以了,譬如要读取"Sheet2"中的内容,只需要把"Read.cs"程序中的"Sheet1$"改成"Sheet2$"就可以了。
三.Visual C#调用Excel表格,并在Excel表格中存储数据: 在Visual C#中调用Excel表格,并不像读取Excel表格中的数据那么容易了,因为在Visual C#中调用Excel表格要使用到Excel的COM组件。如果你安装Office套件在"C"盘,那么在"C:\Program Files\Microsoft Office\Office"可以找到这个COM组件"EXCEL9.OLB",在《Visual C#如何使用Active X组件》一文中,这些COM组件都是非受管代码的,要在Visual C#中使用这些非受管代码的COM组件,就必须把他们转换成受管代码的类库。
所以在用Visual C#调用Excel表格之前,必须完成从COM组件的非受管代码到受管代码的类库的转换。 (1).非受管代码COM组件转换成受管代码的类库: 首先把COM组件"EXCEL9.OLB"拷贝到C盘的根目录下,然后输入下列命令:tlbimp excel9.olb 这样在C盘的根目录下面就产生了三个DLL文件。
简单的方法是通过ODBC来实现:具体实现一、包含Excel文件操作类头文件#include"CSpreadSheet.h"二、新建Excel文件,并写入默认数据//新建Excel文件名及路径,TestSheet为内部表名CSpreadSheetSS("c:\\Test.xls","TestSheet");,testRow;SS.BeginTransaction();//加入标题sampleArray.RemoveAll();sampleArray.Add("姓名");sampleArray.Add("年龄");SS.AddHeaders(sampleArray);//加入数据CStringstrName[]={"徐景周","徐志慧","郭徽","牛英俊","朱小鹏"};CStringstrAge[]={"27","23","28","27","26"};for(inti=0;i"+Rows.GetAt(j-1);}m_AccessList.AddString(strContents);}。
(转)
创建、打开、读取、写入、保存的一般性代码:
using System;
using System.Reflection; // 引用这个才能使用Missing字段
namespace CExcel1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{//创建Application对象
Excel.Application xApp=new Excel.ApplicationClass();
xApp.Visible=true; //得到WorkBook对象, 可以用两种方式之一: 下面的是打开已有的文件
Excel.Workbook xBook=xApp.Workbooks._Open(@"D:\Sample.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value
,Missing.Value,Missing.Value,Missing.Value,Missing.Value
,Missing.Value,Missing.Value,Missing.Value,Missing.Value); //xBook=xApp.Workbooks.Add(Missing.Value);//新建文件的代码
//指定要操作的Sheet,两种方式:
Excel.Worksheet xSheet=(Excel.Worksheet)xBook.Sheets[1]; //Excel.Worksheet xSheet=(Excel.Worksheet)xApp.ActiveSheet;
//读取数据,通过Range对象
Excel.Range rng1=xSheet.get_Range("A1",Type.Missing);
Console.WriteLine(rng1.Value2); //读取,通过Range对象,但使用不同的接口得到Range
Excel.Range rng2=(Excel.Range)xSheet.Cells[3,1];
Console.WriteLine(rng2.Value2); //写入数据
Excel.Range rng3=xSheet.get_Range("C6",Missing.Value);
rng3.Value2="Hello";
rng3.Interior.ColorIndex=6; //设置Range的背景色 //保存方式一:保存WorkBook
xBook.SaveAs(@"D:\CData.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,
Excel.XlSaveAsAccessMode.xlNoChange,Missing.Value,Missing.Value,Missing.Value,
Missing.Value,Missing.Value); //保存方式二:保存WorkSheet
xSheet.SaveAs(@"D:\CData2.xls",
Missing.Value,Missing.Value,Missing.Value,Missing.Value,
Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value); //保存方式三
xBook.Save();
xSheet=null;
xBook=null;
xApp.Quit(); //这一句是非常重要的,否则Excel对象不能从内存中退出
xApp=null;
}
}
}