直接读取Excel文件数据

前言

由于种种需要直接进行读取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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值