前言 由于种种需要直接进行读取Excel文件数据,然而在网上Search多次也没有找到好的方法,一般就通过ODBC或OLE方式进行读取,但这两种方法都具有局限性...(我相信大家都很清楚)。 介绍 MS Excel是众所周知的电子表格处理软件。Excel文件格式是特定的BIFF(Binary Interchange File Format),BIFF里存储了很多记录,第条记录包括记录头和记录体。记录头是4byte,前两位指定记录类型的代码(opcode),后两位指定记录长度;记录体是存储该记录的实际数据。 比如: 1.
BOF record
2.
| Record Header | Record Body |
3.
Byte | 0 1 2 3 | 0 1 2 3 |
4.
-----------------------------------------
5.
Contents | 09 | 00 | 04 | 00 | 02 | 00 | 10 | 00 |
6.
-----------------------------------------
7.
| opcode | length | version | file |
8.
| | | number | type |
记录头: opcode: 09h is BOF; length: 04h record body is 4 bytes long; 记录体: version number:02h is version number (2 for the initial version of Excel) file type:10h is a worksheet file; 具体可参考MS Excel File Format。 描述 以下是对本文程序简单描述。 第一步:打开文件 01.
CFile f;
02.
CFileException e;
03.
04.
// 打开文件
05.
if (!f.Open( "D:\\Book1.xls" , CFile::modeRead, &e))
06.
{
07.
TCHAR szError[1024];
08.
e.GetErrorMessage(szError, 1024);
09.
AfxMessageBox(szError);
10.
return ;
11.
}
12.
第二步:读取版本号
13.
// 读取版本
14.
while (dwPos < dwLen)
15.
{
16.
nRead = f.Read(( void *)&RecNo, 2);
17.
if (RecNo == XL_BOF)
18.
{
19.
WORD Ver, Type;
20.
f.Read(( void *)&RecLen, 2);
21.
f.Read(( void *)&Ver, 2);
22.
f.Read(( void *)&Type, 2);
23.
f.Seek(RecLen, CFile::current);
24.
25.
int ver = 0;
26.
switch (Ver)
27.
{
28.
case BIFF7:
29.
ver = 7;
30.
break ;
31.
case BIFF8:
32.
ver = 8;
33.
AfxMessageBox( "Biff8" );
34.
break ;
35.
}
36.
37.
int type = 0;
38.
switch (Type)
39.
{
40.
case WORKBOOK:
41.
type = 5;
42.
AfxMessageBox( "Workbook" );
43.
break ;
44.
case WORKSHEET:
45.
type = 16;
46.
AfxMessageBox( "Worksheet" );
47.
break ;
48.
case CHART:
49.
type = 32;
50.
AfxMessageBox( "Chart" );
51.
break ;
52.
}
53.
54.
break ;
55.
}
56.
dwPos = f.GetPosition();
57.
}
第三步:读其它数据 01.
f.SeekToBegin();
02.
dwPos = f.GetPosition();
03.
// 读表格数据
04.
while (dwPos < dwLen)
05.
{
06.
nRead = f.Read(( void *)&RecNo, 2);
07.
switch (RecNo)
08.
{
09.
case XL_BOF:
10.
{
11.
f.Read(( void *)&RecLen, 2);
12.
AfxMessageBox( "Bof" );
13.
}
14.
break ;
15.
case XL_BOUNDSHEET:
16.
{
17.
DWORD temp;
18.
BYTE visi;
19.
BYTE type;
20.
TCHAR name;
21.
22.
f.Read(( void *)&RecLen, 2);
23.
f.Read(( void *)&temp, 4);
24.
f.Read(( void *)&visi, 1);
25.
f.Read(( void *)&type, 1);
26.
f.Read(( void *)&StrLen, 2);
27.
f.Read(( void *)&name, StrLen);
28.
29.
char buf[128];
30.
memset (buf, 0x0, 128);
31.
strncpy (buf, &name, StrLen);
32.
33.
AfxMessageBox(buf);
34.
}
35.
break ;
36.
case XL_DIMENSION:
37.
f.Read(( void *)&RecLen, 2);
38.
f.Seek(RecLen, CFile::current);
39.
AfxMessageBox( "Dimension" );
40.
break ;
41.
case 0xE2: // INTERFACED
42.
f.Read(( void *)&RecLen, 2);
43.
AfxMessageBox( "e2" );
44.
break ;
45.
case XL_SST:
46.
f.Read(( void *)&RecLen, 2);
47.
f.Seek(RecLen, CFile::current);
48.
AfxMessageBox( "SST" );
49.
break ;
50.
case XL_NUMBER:
51.
f.Read(( void *)&RecLen, 2);
52.
AfxMessageBox( "Number" );
53.
break ;
54.
case XL_STRING:
55.
f.Read(( void *)&RecLen, 2);
56.
AfxMessageBox( "String" );
57.
break ;
58.
case XL_RK:
59.
f.Read(( void *)&RecLen, 2);
60.
AfxMessageBox( "RK" );
61.
break ;
62.
case XL_LABEL:
63.
{
64.
f.Read(( void *)&RecLen, 2);
65.
AfxMessageBox( "Label" );
66.
}
67.
break ;
68.
case 0xD6:
69.
f.Read(( void *)&RecLen, 2);
70.
AfxMessageBox( "RString" );
71.
break ;
72.
case XL_EOF:
73.
dwPos = dwLen;
74.
AfxMessageBox( "Eof" );
75.
break ;
76.
default :
77.
nRead = f.Read(( void *)&RecLen, 2);
78.
if (nRead == 0)
79.
dwPos = dwLen;
80.
break ;
81.
}
82.
}
第四步:关闭文件 1.
f.Close();
结束 本方讲述的是独立于MS Office系统,分析Excel文件格式并读取其数据。上述程序只读取最基本的信息。若需应用还需更完整的分析(我也在进行中...),当然读取Excel文件方法有多种,在这里只讲述了我使用的方法,希望与各们朋友多交流! 参考文选 1. Microsoft Excel File Format 2. MSDN Library |
直接读取Excel文件数据
最新推荐文章于 2023-08-22 11:18:19 发布