Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1267363
  • 博文数量: 960
  • 博客积分: 52560
  • 博客等级: 大将
  • 技术积分: 13131
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-31 14:15
文章分类

全部博文(960)

文章存档

2011年(1)

2008年(959)

我的朋友

分类: C/C++

2008-08-01 16:58:30

下载本文示例代码
下载源代码

前言
由于种种需要直接进行读取Excel文件数据,然而在网上Search多次也没有找到好的方法,
一般就通过ODBC或OLE方式进行读取,但这两种方法都具有局限性...(我相信大家都很清楚)。
怎么办呢?没办法了,只好选择最艰难的路了--分析Excel文件格式。
介绍
MS Excel是众所周知的电子表格处理软件。Excel文件格式是特定的BIFF(Binary Interchange File Format),BIFF里存储了很多记录,第条记录包括记录头和记录体。记录头是4byte,前两位指定记录类型的代码(opcode),后两位指定记录长度;记录体是存储该记录的实际数据。
比如:
BOF record

           |  Record Header    |    Record Body    |

Byte       |  0    1    2    3 |  0    1    2    3 |

           -----------------------------------------

Contents   | 09 | 00 | 04 | 00 | 02 | 00 | 10 | 00 |

           -----------------------------------------

           | opcode  | length  | version |  file   |

           |         |         |  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。

描述
以下是对本文程序简单描述。

      第一步:打开文件

	CFile f;

	CFileException e;



	// 打开文件

	if (!f.Open("D:\\Book1.xls", CFile::modeRead, &e))

	{

		TCHAR szError[1024];

		e.GetErrorMessage(szError, 1024);

		AfxMessageBox(szError);

		return;

	}

	第二步:读取版本号

	// 读取版本

	while (dwPos < dwLen)

	{

		nRead = f.Read((void*)&RecNo, 2);

		if (RecNo == XL_BOF)	

		{

			WORD Ver, Type;

			f.Read((void*)&RecLen, 2);

			f.Read((void*)&Ver, 2);

			f.Read((void*)&Type, 2);

			f.Seek(RecLen, CFile::current);



			int ver = 0;

			switch (Ver)

			{

			case BIFF7:

				ver = 7;

				break;

			case BIFF8:

				ver = 8;

				AfxMessageBox("Biff8");

				break;

			}



			int type = 0;

			switch (Type)

			{

			case WORKBOOK:

				type = 5;

				AfxMessageBox("Workbook");

				break;

			case WORKSHEET:

				type = 16;

				AfxMessageBox("Worksheet");

				break;

			case CHART:

				type = 32;

				AfxMessageBox("Chart");

				break;

			}



			break;

		}

		dwPos = f.GetPosition();

	}	

	第三步:读其它数据

	f.SeekToBegin();

	dwPos = f.GetPosition();

	// 读表格数据

	while (dwPos < dwLen)

	{

		nRead = f.Read((void*)&RecNo, 2);

		switch (RecNo)

		{

		case XL_BOF:

			{

				f.Read((void*)&RecLen, 2);

				AfxMessageBox("Bof");

			}

			break;

		case XL_BOUNDSHEET:

			{

				DWORD	temp;

				BYTE	visi;

				BYTE	type;

				TCHAR	name;

				

				f.Read((void*)&RecLen, 2);

				f.Read((void*)&temp, 4);

				f.Read((void*)&visi, 1);

				f.Read((void*)&type, 1);

				f.Read((void*)&StrLen, 2);

				f.Read((void*)&name, StrLen);

				

				char buf[128];

				memset(buf, 0x0, 128);

				strncpy(buf, &name, StrLen);

				

				AfxMessageBox(buf);

			}

			break;

		case XL_DIMENSION:

			f.Read((void*)&RecLen, 2);

			f.Seek(RecLen, CFile::current);

			AfxMessageBox("Dimension");

			break;

		case 0xE2:	// INTERFACED

			f.Read((void*)&RecLen, 2);

			AfxMessageBox("e2");

			break;

		case XL_SST:

			f.Read((void*)&RecLen, 2);

			f.Seek(RecLen, CFile::current);

			AfxMessageBox("SST");

			break;

		case XL_NUMBER:

			f.Read((void*)&RecLen, 2);

			AfxMessageBox("Number");

			break;

		case XL_STRING:

			f.Read((void*)&RecLen, 2);

			AfxMessageBox("String");

			break;

		case XL_RK:

			f.Read((void*)&RecLen, 2);

			AfxMessageBox("RK");

			break;

		case XL_LABEL:

			{

				f.Read((void*)&RecLen, 2);

				AfxMessageBox("Label");

			}

			break;

		case 0xD6:

			f.Read((void*)&RecLen, 2);

			AfxMessageBox("RString");

			break;

		case XL_EOF:

			dwPos = dwLen;

			AfxMessageBox("Eof");

			break;

		default:

			nRead = f.Read((void*)&RecLen, 2);

			if (nRead == 0)

				dwPos = dwLen;

			break;

		}

	}

	第四步:关闭文件

	f.Close();   
结束
本方讲述的是独立于MS Office系统,分析Excel文件格式并读取其数据。上述程序只读取最基本的信息。若需应用还需更完整的分析(我也在进行中...),当然读取Excel文件方法有多种,在这里只讲述了我使用的方法,
希望与各们朋友多交流!

参考文选
1. Microsoft Excel File Format
2. MSDN Library

下载本文示例代码
阅读(195) | 评论(0) | 转发(0) |
0

上一篇:WTL字体类

下一篇:为你的程序换个皮肤

给主人留下些什么吧!~~