test_xl.c is a simple demonstration and diagnostic tool for the Excel (.xls) file format.This sample code provides an example of:
Here is another example. Note that this earlier version (Excel 3.0) format does not use the CFBF container, so no information is provided for the first three entries.
For more information, or to aid with debugging, you can specify a -verbose flag, as shown in this example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int
main (int argc, char *argv[])
{
const void *handle;
int ret;
unsigned int info;
unsigned int fat_count;
unsigned int sst_count;
unsigned int worksheet_count;
unsigned int format_count;
unsigned int xf_count;
unsigned int idx;
unsigned int next_sector;
int biff_v8 = 0;
const char *utf8_string;
int verbose = 0;
if (argc == 2 || argc == 3)
{
if (argc == 3)
{
if (strcmp (argv[2], "-verbose") == 0)
verbose = 1;
}
}
else
{
fprintf (stderr, "usage: text_xl path.xls [-verbose]\n");
return -1;
}
{
fprintf (stderr, "OPEN ERROR: %d\n", ret);
return -1;
}
printf ("\nExcel document: %s\n", argv[1]);
printf ("==========================================================\n");
{
fprintf (stderr, "GET-INFO [FREEXL_CFBF_VERSION] Error: %d\n", ret);
goto stop;
}
switch (info)
{
printf ("CFBF Version ........: 3\n");
break;
printf ("CFBF Version ........: 4\n");
break;
printf ("CFBF Version ........: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_CFBF_SECTOR_SIZE] Error: %d\n",
ret);
goto stop;
}
switch (info)
{
printf ("CFBF Sector size ....: 512\n");
break;
printf ("CFBF Sector size ....: 4096\n");
break;
printf ("CFBF Sector size ....: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_CFBF_FAT_COUNT] Error: %d\n", ret);
goto stop;
}
printf ("CFBF FAT entries ....: %u\n", fat_count);
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_VERSION] Error: %d\n", ret);
goto stop;
}
switch (info)
{
printf ("BIFF Version ........: 2 [Excel 2.0]\n");
break;
printf ("BIFF Version ........: 3 [Excel 3.0]\n");
break;
printf ("BIFF Version ........: 4 [Excel 4.0]\n");
break;
printf ("BIFF Version ........: 5 [Excel 5.0 / Excel 95]\n");
break;
printf ("BIFF Version ........: 8 [Excel 98/XP/2003/2007/2010]\n");
biff_v8 = 1;
break;
printf ("BIFF Version ........: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_MAX_RECSIZE] Error: %d\n",
ret);
goto stop;
}
switch (info)
{
printf ("BIFF Max record size : 2080\n");
break;
printf ("BIFF Max record size : 8224\n");
break;
printf ("BIFF Max record size : UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_DATEMODE] Error: %d\n", ret);
goto stop;
}
switch (info)
{
printf ("BIFF DateMode .......: 0 [day#1 = '1900-01-01']\n");
break;
printf ("BIFF DateMode .......: 1 [day#1 = '1904-01-02']\n");
break;
printf ("BIFF DateMode .......: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_PASSWORD] Error: %d\n", ret);
goto stop;
}
switch (info)
{
printf ("BIFF Password/Crypted: YES, obfuscated (not accessible)\n");
break;
printf ("BIFF Password/Crypted: NO, clear data\n");
break;
printf ("BIFF Password/Crypted: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_CODEPAGE] Error: %d\n", ret);
goto stop;
}
switch (info)
{
printf ("BIFF CodePage .......: ASCII\n");
break;
printf ("BIFF CodePage .......: CP437 [OEM United States]\n");
break;
printf ("BIFF CodePage .......: CP720 [Arabic (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP737 [Greek (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP775 [Baltic (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP850 [Western European (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP852 [Central European (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP855 [OEM Cyrillic]\n");
break;
printf ("BIFF CodePage .......: CP857 [Turkish (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP858 [OEM Multilingual Latin I]\n");
break;
printf ("BIFF CodePage .......: CP860 [Portuguese (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP861 [Icelandic (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP862 [Hebrew (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP863 [French Canadian (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP864 [Arabic (864)]\n");
break;
printf ("BIFF CodePage .......: CP865 [Nordic (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP866 [Cyrillic (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP869 [Greek, Modern (DOS)]\n");
break;
printf ("BIFF CodePage .......: CP874 [Thai (Windows)]\n");
break;
printf ("BIFF CodePage .......: CP932 [Japanese (Shift-JIS)]\n");
break;
printf
("BIFF CodePage .......: CP936 [Chinese Simplified (GB2312)]\n");
break;
printf ("BIFF CodePage .......: CP949 [Korean]\n");
break;
printf
("BIFF CodePage .......: CP950 [Chinese Traditional (Big5)]\n");
break;
printf ("BIFF CodePage .......: UTF-16LE [Unicode]\n");
break;
printf ("BIFF CodePage .......: CP1250 [Windows Central Europe]\n");
break;
printf ("BIFF CodePage .......: CP1251 [Windows Cyrillic]\n");
break;
printf ("BIFF CodePage .......: CP1252 [Windows Latin 1]\n");
break;
printf ("BIFF CodePage .......: CP1253 [Windows Greek]\n");
break;
printf ("BIFF CodePage .......: CP1254 [Windows Turkish]\n");
break;
printf ("BIFF CodePage .......: CP1255 [Windows Hebrew]\n");
break;
printf ("BIFF CodePage .......: CP1256 [Windows Arabic]\n");
break;
printf ("BIFF CodePage .......: CP1257 [Windows Baltic]\n");
break;
printf ("BIFF CodePage .......: CP1258 [Windows Vietnamese]\n");
break;
printf ("BIFF CodePage .......: CP1361 [Korean (Johab)]\n");
break;
printf ("BIFF CodePage .......: MacRoman\n");
break;
printf ("BIFF CodePage .......: UNKNOWN\n");
break;
};
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_SHEET_COUNT] Error: %d\n",
ret);
goto stop;
}
printf ("BIFF Worksheets .....: %u\n", worksheet_count);
if (biff_v8)
{
{
fprintf (stderr,
"GET-INFO [FREEXL_BIFF_STRING_COUNT] Error: %d\n",
ret);
goto stop;
}
printf ("BIFF SST entries ....: %u\n", sst_count);
}
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_FORMAT_COUNT] Error: %d\n",
ret);
goto stop;
}
printf ("BIFF Formats ........: %u\n", format_count);
{
fprintf (stderr, "GET-INFO [FREEXL_BIFF_XF_COUNT] Error: %d\n", ret);
goto stop;
}
printf ("BIFF eXtendedFormats : %u\n", xf_count);
printf
("\nWorksheets:\n=========================================================\n");
for (idx = 0; idx < worksheet_count; idx++)
{
unsigned short active;
unsigned int rows;
unsigned short columns;
{
fprintf (stderr, "GET-WORKSHEET-NAME Error: %d\n", ret);
goto stop;
}
if (utf8_string == NULL)
printf ("%3u] NULL (unnamed)\n", idx);
else
printf ("%3u] %s\n", idx, utf8_string);
{
fprintf (stderr, "SELECT-ACTIVE_WORKSHEET Error: %d\n", ret);
goto stop;
}
{
fprintf (stderr, "GET-ACTIVE_WORKSHEET Error: %d\n", ret);
goto stop;
}
printf
("\tok, Worksheet successfully selected: currently active: %u\n",
active);
{
fprintf (stderr, "WORKSHEET-DIMENSIONS Error: %d\n", ret);
goto stop;
}
printf ("\t%u Rows X %u Columns\n\n", rows, columns);
}
if (!verbose)
goto stop;
if (biff_v8)
{
printf
("\nSST [Shared String Table]:\n=========================================================\n");
for (idx = 0; idx < sst_count; idx++)
{
{
fprintf (stderr, "GET-SST-STRING Error: %d\n", ret);
goto stop;
}
if (utf8_string == NULL)
printf ("%8u] NULL (empty string)\n", idx);
else
printf ("%8u] %s\n", idx, utf8_string);
}
}
printf
("\nFAT entries [File Allocation Table]:\n=========================================================\n");
for (idx = 0; idx < fat_count; idx++)
{
{
fprintf (stderr, "GET-FAT-ENTRY Error: %d\n", ret);
goto stop;
}
if (next_sector == 0xffffffff)
printf ("%8u -> 0xffffffff FREESECT\n", idx);
else if (next_sector == 0xfffffffe)
printf ("%8u -> 0xfffffffe ENDOFCHAIN\n", idx);
else if (next_sector == 0xfffffffd)
printf ("%8u -> 0xfffffffe FATSECT\n", idx);
else if (next_sector == 0xfffffffc)
printf ("%8u -> 0xfffffffe DIFSECT\n", idx);
else
printf ("%8u -> %8u\n", idx, next_sector);
}
stop:
{
fprintf (stderr, "CLOSE ERROR: %d\n", ret);
return -1;
}
return 0;
}