WEB开发网
开发学院软件开发VC 直接读取Excel文件数据 阅读

直接读取Excel文件数据

 2006-07-20 11:44:04 来源:WEB开发网   
核心提示:本文示例源代码或素材下载 前言由于种种需要直接进行读取Excel文件数据,然而在网上Search多次也没有找到好的方法,直接读取Excel文件数据,一般就通过ODBC或OLE方式进行读取,但这两种方法都具有局限性...(我相信大家都很清楚),后两位指定记录长度;记录体是存储该记录的实际数据,比如:BOF rec

本文示例源代码或素材下载

前言

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

结束

1 2  下一页

Tags:直接 读取 Excel

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接