zoukankan      html  css  js  c++  java
  • 直接读取Excel文件数据

    作者/weigf

    下载源代码

    前言
      由于种种需要直接进行读取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
  • 相关阅读:
    Mybatis入门环境搭建
    sts,eclipse里面配置tomcat
    IDEA-导入本地所需要的jar包
    Java使用poi生成Excel,生成两种表格下拉框
    Java使用poi生成Excel表格
    Java synchronized(this)锁住的是什么
    Java多线程之使用ATM与柜台对同一账户取钱
    Java多线程对同一个对象进行操作
    Java Socket通信实例
    java基本数据类型和引用数据类型的区别
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/717079.html
Copyright © 2011-2022 走看看