直接读取Excel文件数据

来源:互联网 发布:js date set month 编辑:程序博客网 时间:2024/06/05 17:55

前言

由于种种需要直接进行读取Excel文件数据,然而在网上Search多次也没有找到好的方法,一般就通过ODBC或OLE方式进行读取,但这两种方法都具有局限性...(我相信大家都很清楚)。
怎么办呢?没办法了,只好选择最艰难的路了--分析Excel文件格式。

介绍

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

0 0
原创粉丝点击