Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8182764
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-03-18 14:15:02

下载本文示例代码
前言
  由于种种需要直接进行读取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
下载本文示例代码
阅读(3874) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-03-27 10:39:55

怎么才可以下载源码撒