针对Excel表格文件操作的编程实现
简介
通过本文及配套示例源码你可以更加灵活的控制Excel表格文件,其中包括创建新Excel文件、写入表格数据、读取表格数据(包括对原建Excel文件自已手工添加的行、列数据的准确读取),删除已有Excel表格,对表格中指定行、列、单元格进行查询、插入、替换等操作,同时还可以将生成的Excel文件转换为按指定分隔符分隔的其它文本格式的文件。下面是把此方法用VC6编写的示例程序运行效果:
基本思路
基础实现方法同上篇文章《直接通过ODBC读、写Excel表格文件》相同,都是通过ODBC来把Excel表格文件当成数据库文件来进行读、写等操作,所以在Excel表格文件中写入的行头名必须是唯一的(不要重名,相当于数据库中的ID值)。本文中对Excel文件的操作都被封装进一个类CSpreadSheet中,通过它我们可以非常简便的实现各种Excel表格数据操作,并且可以对该类进行扩充来满足自己的需求。
具体实现
一、 包含Excel文件操作类头文件
1.
#include "CSpreadSheet.h"
二、 新建Excel文件,并写入默认数据
01.
// 新建Excel文件名及路径,TestSheet为内部表名
02.
CSpreadSheet SS(
"c:\\Test.xls"
,
"TestSheet"
);
03.
04.
CStringArray sampleArray, testRow;
05.
06.
SS.BeginTransaction();
07.
08.
// 加入标题
09.
sampleArray.RemoveAll();
10.
sampleArray.Add(
"姓名"
);
11.
sampleArray.Add(
"年龄"
);
12.
SS.AddHeaders(sampleArray);
13.
14.
// 加入数据
15.
CString strName[] = {
"徐景周"
,
"徐志慧"
,
"郭徽"
,
"牛英俊"
,
"朱小鹏"
};
16.
CString strAge[] = {
"27"
,
"23"
,
"28"
,
"27"
,
"26"
};
17.
for
(
int
i = 0; i <
sizeof
(strName)/
sizeof
(CString); i++)
18.
{
19.
sampleArray.RemoveAll();
20.
sampleArray.Add(strName[i]);
21.
sampleArray.Add(strAge[i]);
22.
SS.AddRow(sampleArray);
23.
}
24.
25.
SS.Commit();
三、 读取Excel文件数据
01.
CSpreadSheet SS(
"c:\\Test.xls"
,
"TestSheet"
);
02.
03.
CStringArray Rows, Column;
04.
05.
//清空列表框
06.
m_AccessList.ResetContent();
07.
for
(
int
i = 1; i <= SS.GetTotalRows(); i++)
08.
{
09.
// 读取一行
10.
SS.ReadRow(Rows, i);
11.
CString strContents =
""
;
12.
for
(
int
j = 1; j <= Rows.GetSize(); j++)
13.
{
14.
if
(j == 1)
15.
strContents = Rows.GetAt(j-1);
16.
else
17.
strContents = strContents +
" --> "
+ Rows.GetAt(j-1);
18.
}
19.
20.
m_AccessList.AddString(strContents);
21.
}
四、 对已存在Excel表格数据进行添加、插入、替换操作
01.
// 初始化测试行数据,进行添加、插入及替换数据操作演示
02.
for
(
int
k = 1; k <= 2; k++)
03.
{
04.
testRow.Add(
"Test"
);
05.
}
06.
07.
SS.AddRow(testRow);
// 添加到尾部
08.
SS.AddRow(testRow, 2);
// 插入新行到第二行
09.
SS.AddRow(testRow, 6,
true
);
// 替换原第四行来新的内容
10.
SS.AddCell(
"徐景周"
, 1,2);
// 添加(不存在)或替换(存在)第二行,第一列单元格内容
11.
12.
SS.Commit();
五、 对已存在Excel表格数据进行行、列、单元格查询
001.
void
CExcelAccessDlg::OnQuery()
002.
{
003.
CSpreadSheet SS(
"c:\\Test.xls"
,
"TestSheet"
);
004.
005.
CStringArray Rows, Column;
006.
CString tempString =
""
;
007.
008.
UpdateData();
009.
010.
if
(m_strRow ==
""
&& m_strColumn ==
""
)
// 查询为空
011.
{
012.
AfxMessageBox(
"行号、列号不能同时为空!"
);
013.
return
;
014.
}
015.
else
if
(m_strRow ==
""
&& m_strColumn !=
""
)
// 查询指定列数据
016.
{
017.
int
iColumn =
atoi
(m_strColumn);
018.
int
iCols = SS.GetTotalColumns();
019.
if
(iColumn > iCols)
// 超出表范围查询时
020.
{
021.
CString str;
022.
str.Format(
"表中总列数为: %d, "
, iCols);
023.
AfxMessageBox(str +
" 查询列数大于Excel表中总列数,请重新输入!"
);
024.
return
;
025.
}
026.
027.
// 读取一列数据,并按行读出
028.
if
(!SS.ReadColumn(Column, iColumn))
029.
{
030.
AfxMessageBox(SS.GetLastError());
031.
return
;
032.
}
033.
034.
CString tmpStr;
035.
for
(
int
i = 0; i < Column.GetSize(); i++)
036.
{
037.
tmpStr.Format(
"行号: %d, 列号: %d ,内容: %s\n"
, i+1,iColumn,Column.GetAt(i));
038.
tempString += tmpStr;
039.
}
040.
041.
AfxMessageBox(tempString);
042.
}
043.
else
if
(m_strRow !=
""
&& m_strColumn ==
""
)
// 查询指定行数数据
044.
{
045.
int
iRow =
atoi
(m_strRow);
046.
int
iRows = SS.GetTotalRows();
047.
048.
if
(iRow > iRows)
// 超出表范围查询时
049.
{
050.
CString str;
051.
str.Format(
"表中总行数为: %d, "
, iRows);
052.
AfxMessageBox(str +
" 查询行数大于Excel表中总行数,请重新输入!"
);
053.
return
;
054.
}
055.
056.
// 读取指定行数据
057.
if
(!SS.ReadRow(Rows, iRow))
058.
{
059.
AfxMessageBox(SS.GetLastError());
060.
return
;
061.
}
062.
063.
CString tmpStr;
064.
for
(
int
i = 0; i < Rows.GetSize(); i++)
065.
{
066.
tmpStr.Format(
"行号: %d, 列号: %d ,内容: %s\n"
, iRow, i+1, Rows.GetAt(i));
067.
tempString += tmpStr;
068.
}
069.
070.
AfxMessageBox(tempString);
071.
}
072.
else
if
(m_strRow !=
""
&& m_strColumn !=
""
)
// 查询指定单元格数据
073.
{
074.
int
iRow =
atoi
(m_strRow), iColumn =
atoi
(m_strColumn);
075.
int
iRows = SS.GetTotalRows(), iCols = SS.GetTotalColumns();
076.
077.
if
(iColumn > iCols)
// 超出表范围查询时
078.
{
079.
CString str;
080.
str.Format(
"表中总列数为: %d, "
, iCols);
081.
AfxMessageBox(str +
" 查询列数大于Excel表中总列数,请重新输入!"
);
082.
return
;
083.
}
084.
else
if
(iRow > iRows)
085.
{
086.
CString str;
087.
str.Format(
"表中总行数为: %d, "
, iRows);
088.
AfxMessageBox(str +
" 查询行数大于Excel表中总行数,请重新输入!"
);
089.
return
;
090.
}
091.
092.
// 读取指定行、列单元格数据
093.
if
(!SS.ReadCell(tempString, iColumn, iRow))
094.
{
095.
AfxMessageBox(SS.GetLastError());
096.
return
;
097.
}
098.
099.
CString str;
100.
str.Format(
"行号: %d, 列号: %d ,内容: %s"
, iRow,iColumn,tempString);
101.
AfxMessageBox(str);
102.
}
103.
104.
}
六、 将存在的Excel转换另存为指定分隔的文本文件
1.
// 将原Excel文件转换为用分号分隔的文本,并另存为同名文本文件
2.
SS.Convert(
";"
);
七、 删除Excel中表格
1.
SS. DeleteSheet();
// 删除Excel文件中所有表格
2.
SS. DeleteSheet(
" TestSheet "
);
// 删除Excel中TextSheet表格
八、 获取Excel中总行数、总列数、当前行
1.
int
iCols = SS.GetTotalColumns();
// 总列数
2.
int
iRows = SS.GetTotalRows();
// 总行数
3.
int
iCurRow = SS.GetCurrentRow();
// 当前所在行号
九、 获取行头数据
01.
CStringArray rowHeader;
02.
SS.GetFieldNames(rowHeader);
03.
CString tmpStr;
04.
for
(
int
i = 0; i < rowHeader.GetSize(); i++)
05.
{
06.
tmpStr.Format(
"行号: %d, 列号: %d ,内容: %s\n"
, 1, i+1, rowHeader.GetAt(i));
07.
tempString += tmpStr;
08.
}
09.
AfxMessageBox(tempString);
最后,如果想知道详细实现细节的话,可以在下载示例源码后,仔细查看源码既可(内有详细注释)。
<linker : http://www.vckbase.com/index.php/wv/494>