How To Determine the Version of a Microsoft Excel Workbook

Summary

This article demonstrates how to determine the version of a Microsoft Excel Workbook (.xls).

More Information

Microsoft Excel saves data using structured storage. In particular, it creates a data stream called "Workbook" (previously just "Book") where it saves the contents starting with a BOF (beginning of file) record. This record contains useful attributes of the workbook, as well as the version. The following Microsoft Visual C++ code demonstrates how to open the file, read it, and return the version number based on the BOF.

  1. Create a new "Win32 Console Application" in Microsoft Developer Studio.
  2. Add a C++ Source File (.cpp) to the project and add the following code to the source file:
    #include <windows.h>
    #include <iostream.h> // My additions

    // BOF record from Microsoft Excel
    typedef struct _xlbof
    {
    char bofMarker; // Should be 0x09

    char vers; // Version indicator for biff2, biff3, and biff4
    // = 0x00 -> Biff2
    // = 0x02 -> Biff3
    // = 0x04 -> Biff4
    // = 0x08 -> Biff5/Biff7/Biff8

    char skip[2]; // Unspecified

    short int vers2; // Version number
    // 0x0500 -> Biff5/Biff7
    // 0x0600 -> Biff8

    short int dt; // Substream type (not used in this example)

    short int rupBuild; // Internal build identifier
    short int rupYear; // Internal Build year
    } XLBOF;



    //* XLVersionFromFile() ******************************************
    //* Returns
    //* n for BiffN
    //* i.e. 8 for Biff8 (Microsoft Excel 97, Excel 2000, Excel 2002)
    //*
    //* Negative if an error occurs
    //****************************************************************

    int XLVersionFromFile(char *filename) {
    // Translate filename to Unicode
    WCHAR wcFilename[1024];
    int i = mbstowcs(wcFilename, filename, strlen(filename));
    wcFilename[i] = 0;

    IStorage *pStorage;
    HRESULT hr;
    XLBOF xlbof;

    // Open the document as an OLE compound document
    hr = ::StgOpenStorage(wcFilename, NULL,
    STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);

    if(!FAILED(hr)) {
    // Open the data-stream where Microsoft Excel stores the data
    IStream *pStream;
    hr = pStorage->OpenStream(L"Workbook", NULL,
    STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);

    // If "Workbook" does not exist, try "Book"
    if(FAILED(hr)) {
    hr = pStorage->OpenStream(L"Book", NULL,
    STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
    }
    if(!FAILED(hr)) {
    // Read the relevant BOF information
    DWORD dwCount; // bytes read
    pStream->Read(&xlbof, sizeof(XLBOF), &dwCount);

    // Let go of the IStream pointer
    pStream->Release();
    }
    else return -2;

    // Let go of the IStorage pointer
    pStorage->Release();
    }
    else return -1;

    // Determine which version to return
    if(xlbof.vers != 0x08) return (xlbof.vers + 4) / 2;
    else {
    switch(xlbof.vers2) {
    case 0x0500: // Either Biff5 or Biff7
    // Biff7's rupYear is at least 1994
    if(xlbof.rupYear < 1994) return 5;

    // Check for specific builds of Microsoft Excel 5
    switch(xlbof.rupBuild) {
    case 2412: // XL5a
    case 3218: // XL5c
    case 3321: // NT XL5
    return 5;
    default:
    return 7;
    }

    case 0x0600: return 8;
    }
    }

    // Version not recognized. Perhaps there is a newer version.
    return -3;
    }

    void main()
    {
    int iretVal = 0;
    iretVal = XLVersionFromFile("C:\\Test.xls");
    //Adapt the filename to your example
    cout << "The Excel Version is " << iretVal << "\n\n\r";
    return;
    }
  3. In the main()function, you may need to modify the path and filename of the Microsoft Excel workbook in the following line of code:
     iretVal = XLVersionFromFile("C:\\Test.xls");

References

Microsoft Visual C++ Help, version 5.0; search on "structured storage"


Microsoft Developers Network (MSDN); search on "structured storage", "Microsoft Excel file format", "BOF", "beginning of file"


Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2); search on "Microsoft Excel file format", "BOF", "beginning of file"
Propiedades

Id. de artículo: 178605 - Última revisión: 03/23/2009 - Revisión: 1

Comentarios