纯粹的C语言,不依赖任何库,生成最小的xls(2003版)文件

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char byte;

struct Compound_Binary_File_Header
{
    byte compound_file_id[8]; //0 8 Compound document file identifier: D0 CF 11 E0 A1 B1 1A E1 
    byte class_id[16]; //8 16 Unique identifier (UID) of this file, class id (set with WriteClassStg, retrieved with GetClassFile/ReadClassStg)
    byte minor_version[2]; //24 2 minor version number of the file format (most used is 003EH)
    byte major_version[2]; //26 2 major version number of the file format (most used is 0003H)
    byte byte_order[2]; //28 2 Byte order identifier :FEH FFH = Little-Endian FFH FEH = Big-Endian 
    byte size_of_a_master_sector[2]; //30 2 Size of a sector in the compound document file in power-of-two (ssz), real sector size is sec_size = 2ssz bytes (most used value is 9 which means 512 bytes, minimum value is 7 which means 128 bytes) 
    byte size_of_a_short_sector[2]; //32 2 Size of a short-sector in the short-stream container stream in power-of-two (sssz), real short-sector size is short_sec_size = 2sssz bytes (most used value is 6 which means 64 bytes, maximum value is sector size ssz, see above)
    byte reserved[2]; //34 2 Not used
    byte reserved1[4]; //36 4 Not used
    byte reserved2[4]; //40 4 Not used
    byte number_of_sector_SAT[4]; //44 4 Total number of sectors used for the sector allocation table
    byte first_sector_of_directory_stream[4]; //48 4 SID of first sector of the directory stream, first sector in the Directory chain
    byte signature[4]; //52 4 Not used, signature used for transactionin: must be zero. The reference implementation does not support transactioning
    byte min_size_of_a_standard_stream[4]; //56 4 Minimum size of a standard stream (in bytes, most used size is 4096 bytes), streams smaller than this value are stored as short-streams 
    byte first_sector_of_short_sector_SSAT[4]; //60 4 SID of first sector of the short-sector allocation table, or –2 (End Of Chain SID) if not extant 
    byte total_number_of_short_sector_SSAT[4]; //64 4 Total number of sectors used for the short-sector allocation table
    byte first_sector_of_master_sector_MSAT[4]; //68 4 SID of first sector of the master sector allocation table, or –2 (End Of Chain SID) if no additional sectors used 
    byte total_number_of_master_sector_MSAT[4]; //72 4 Total number of sectors used for the master sector allocation table
    byte first_109_master_sector_MSAT[436]; //76 436 First part of the master sector allocation table containing 109 SIDs
} ;

typedef enum tagSTGTY
{
    TGTY_INVALID = 0,
    STGTY_STORAGE = 1,
    STGTY_STREAM = 2,
    STGTY_LOCKBYTES = 3,
    STGTY_PROPERTY = 4,
    STGTY_ROOT = 5
} STGTY;

typedef enum tagDECOLOR //red-black tree 红黑树的颜色
{
    DE_RED = 0,
    DE_BLACK = 1
} DECOLOR;


struct Storage_Directory_Entry
{
    byte name_of_entry[64]; // [000H,64] 64 bytes. The Element name in Unicode, like: "Root Entry"
    byte length_of_entry[2]; // [040H,02] Length of the Element name in characters, not bytes 
    byte type_of_entry[1]; // [042H,01] Type of the entry: value taken from the STGTY enumeration   
    byte node_colour_of_entry[1]; // [043H,01] Value taken from DECOLOR enumeration. Node colour of the entry:00H = Red 01H = Black
    byte did_of_left_sibling[4]; // [044H,04] SID of the left-sibling of this entry in the directory tree, DID of the left child node inside the red-black tree of all direct members of the parent storage (if this entry is a user storage or stream), –1 if there is no left child 
    byte did_of_right_sibling[4]; // [048H,04] SID of the right-sibling of this entry in the directory tree   
    byte did_of_child[4]; // [04CH,04] SID of the child acting as the root of all the children of this element (if _mse=STGTY_STORAGE) 
    byte class_id[16]; // [050H,16] CLSID of this storage (if _mse=STGTY_STORAGE)   
    byte user_flag[4]; // [060H,04] User flags of this storage (if _mse=STGTY_STORAGE)   
    byte time_st[8]; // [064H,16] Create/Modify time-stamps (if _mse=STGTY_STORAGE)
    byte time_ed[8]; // [064H,16] Create/Modify time-stamps (if _mse=STGTY_STORAGE)    
    byte sid_of_first_sector[4]; // [074H,04] starting SECT of the stream (if _mse=STGTY_STREAM), SID of first sector or short-sector, if this entry refers to a stream, SID of first sector of the short-stream container stream, if this is the root storage entry, 0 otherwise
    byte total_stream_size[4]; // [078H,04] size of stream in bytes (if _mse=STGTY_STREAM), Total stream size in bytes,
    byte reserved[4]; // [07CH,04] Reserved for future use. Must be zero.
};

void _tmain(int argc, _TCHAR* argv[])
{
    int i;
    FILE *fd;
    char *filename="test.xls";
    char *testString[]={"order","gsdm","amount","1","6124","20180000.00"};
    if( (fd=fopen(filename,"wb+"))==NULL )
    {
        printf("write file err\n");
        exit(-1);
    }
    
    /*
    struct Compound_Binary_File_Header xlsHeader;
    memset(&xlsHeader,0,sizeof(struct Compound_Binary_File_Header));
    unsigned char id[8]={0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1};
    memcpy(xlsHeader.compound_file_id,id,8);
    fwrite(&xlsHeader,sizeof(struct Compound_Binary_File_Header),1,fd);
    */
    
    unsigned char XLSHEADER[8] = {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}; //0x00:复合文档的标识
    unsigned char XLSHEADER2={0x00}; //0x8:16位:未定义
    unsigned short int XLSSLAVEVERSION={0x3E}; //0x18:修订号 2位
    unsigned short int XLSMAINVERSION={0x03}; //0x1A:版本号 2位
    unsigned short int XLSCODINGL={0xFFFE}; //0x1C:字节排序方式 2位
    unsigned short int XLSSectorSize={0x9}; //0x1E:扇区的大小:512字节 2位
    unsigned short int XLSShortSectorSize={0x06}; //0x20:短扇区的大小:64字节 2位
    unsigned char XLSUndefined1={0x00};  //0x22: 10位:未定义
    unsigned int XLSSectorCount={0x1};   //0x2c: Sector总数 4位
    unsigned int XLSFirstSectorId={0x19}; //0x30: Directory Sector的SID 4位  
    unsigned int XLSUndefined2={0x00};  //0x34: 4位:未定义
    unsigned int XLSStreamSize={0x1000}; //0x38: 标准流大小:4096字节 4位 //暂定为512字节
    unsigned int XLSShortSectorId={-2}; //0x3C:第一个短扇区Sector的SID 4位
    unsigned int XLSShortSectorCount={0x00}; //0x40:短扇区Sector总数 4位
    unsigned int XLSMSATID={-2};            //0x44:主扇区第一个Sector的SID 4位
    unsigned int XLSMSATCount={0x00};        //0x48:主扇区Sector的总数 4位
    unsigned int onlyBlockChainStartPos={0x18}; //0x4C:
    int XLSZero2={-1};
    unsigned char blockZero[512];
    memset(blockZero,0,512);

    fwrite(&XLSHEADER,8,1,fd);//复合文档的标识
    for(int x=0;x<16;x++) fwrite(&XLSHEADER2,1,1,fd);//16位:未定义
    fwrite(&XLSSLAVEVERSION,2,1,fd); //修订号
    fwrite(&XLSMAINVERSION,2,1,fd);  //版本号
    fwrite(&XLSCODINGL,2,1,fd); //字节排序方式
    fwrite(&XLSSectorSize,2,1,fd);    //扇区的大小:512字节
    fwrite(&XLSShortSectorSize,2,1,fd); //短扇区的大小:64字节
    for(int x=0;x<10;x++) fwrite(&XLSUndefined1,1,1,fd); //10位:未定义
    fwrite(&XLSSectorCount,4,1,fd); //Sector总数 4位
    fwrite(&XLSFirstSectorId,4,1,fd); //第一个Sector的SID 4位
    fwrite(&XLSUndefined2,4,1,fd); //4位:未定义
    fwrite(&XLSStreamSize,4,1,fd); //标准流大小:4096字节 4位 
    fwrite(&XLSShortSectorId,4,1,fd); //第一个短扇区Sector的SID 4位
    fwrite(&XLSShortSectorCount,4,1,fd); //短扇区Sector总数 4位
    fwrite(&XLSMSATID,4,1,fd);  //主扇区第一个Sector的SID 4位
    fwrite(&XLSMSATCount,4,1,fd);  //主扇区Sector的总数 4位
    fwrite(&onlyBlockChainStartPos,4,1,fd);      //blockChain开始位置,暂设为0x3:实际为(0x3+1)*512
    for(i=0;i<108;i++) fwrite(&XLSZero2,4,1,fd);
    

    unsigned short int streamFlag={0x809}; //stream开始标志
    unsigned short int streamLen={0x10};
    unsigned short int biffVersion={0x600};
    unsigned short int workBookStreamVersion={0x5};
    unsigned short int workSheetStreamVersion={0x10};
    unsigned char xlsZero3={0x00};
    unsigned short int xlsEOF={0x0a};
    fwrite(&streamFlag,2,1,fd);
    fwrite(&streamLen,2,1,fd);
    fwrite(&biffVersion,2,1,fd);
    fwrite(&workBookStreamVersion,2,1,fd);
    for(int x=0;x<streamLen-4;x++) fwrite(&xlsZero3,1,1,fd);

    unsigned short int userInter[8]={0xe1,0x2,0x4b0,0xc1,0x2,0x0,0xe2,0x0};
    fwrite(&userInter,16,1,fd);

    unsigned short int xlsBoundSheetFlag={0x85}; //sheet标志
    unsigned short int xlsBoundSheetLen={0xe}; //暂设为0xe
    unsigned int rec_offset={0x200}; //暂设为0x200
    unsigned short int unknownOption={0x0};
    char sheetName1[]="Sheet1";
    unsigned short int sheetName1_len=strlen(sheetName1);
    fwrite(&xlsBoundSheetFlag,2,1,fd);
    fwrite(&xlsBoundSheetLen,2,1,fd);
    fwrite(&rec_offset,4,1,fd);
    fwrite(&unknownOption,2,1,fd);
    fwrite(&sheetName1_len,2,1,fd);
    fwrite(sheetName1,6,1,fd);

    unsigned short int xlsSstFlag={0xfc}; //字符串sst标志
    unsigned short int xlsSstLen=0;
    unsigned int xlsZero4={0x0};
    unsigned int uniqStrCount={0x6};  //length of testString[]
    unsigned char option1={0x4};   ///[1]:1-Ascii,0-Unicode [4]:1-ExtendChars
    unsigned int extendCharNum={0x10};
    for(int x=0;x<6;x++) 
    {
        //printf("%d:%s\n",strlen(testString[x]),testString[x]);
        xlsSstLen+=(7+strlen(testString[x])+extendCharNum);
        
    }
    xlsSstLen+=8;
    printf("%x\n",xlsSstLen);
    fwrite(&xlsSstFlag,2,1,fd);
    fwrite(&xlsSstLen,2,1,fd);
    //fwrite(&xlsZero4,4,1,fd);
    fwrite(&uniqStrCount,4,1,fd);
    fwrite(&uniqStrCount,4,1,fd);
    
    for(int x=0;x<6;x++) 
    {
        unsigned short int charNums=0;
        
        charNums=strlen(testString[x]);

        fwrite(&charNums,2,1,fd);
        fwrite(&option1,1,1,fd);
        fwrite(&extendCharNum,4,1,fd);
        fwrite(testString[x],strlen(testString[x]),1,fd);
        for(int x=0;x<extendCharNum;x++) fwrite(&xlsZero4,1,1,fd);
        
    }
    
    /*
    unsigned short int extSst[7]={0xff,0xa,0x8,0x0,0x6c8,0xc,0x0};
    fwrite(&extSst,14,1,fd);
    
    unsigned short int xlsBookInfo={0x863}; //Extra Book Info
    unsigned short int xlsBookInfoLen={0x15};
    unsigned short int xlsBookInfo2={0x863};
    unsigned int xlsBookInfoCB={0x15}; 
    unsigned char xlsBookInfoOpt={0xFE}; 

    fwrite(&xlsBookInfo,2,1,fd);
    fwrite(&xlsBookInfoLen,2,1,fd);
    fwrite(&xlsBookInfo2,2,1,fd);
    for(unsigned int x=0;x<10;x++) fwrite(&xlsZero4,1,1,fd);
    fwrite(&xlsBookInfoCB,4,1,fd);
    fwrite(&xlsZero4,4,1,fd);
    fwrite(&xlsBookInfoOpt,1,1,fd);
    */


    fwrite(&xlsEOF,2,1,fd);
    int byteWrote=ftell(fd)%512;
    for(int x=0;x<512-byteWrote;x++) fwrite(&xlsZero4,1,1,fd);
    
    
    fwrite(&streamFlag,2,1,fd);   //第一个sheet开始
    fwrite(&streamLen,2,1,fd);
    fwrite(&biffVersion,2,1,fd);
    fwrite(&workSheetStreamVersion,2,1,fd);
    //fwrite(&xlsZero4,4,1,fd);
    for(int x=0;x<streamLen-4;x++) fwrite(&xlsZero3,1,1,fd);

    /*
    unsigned short int indexRecordFlag[2]={0x20B,0x14};  //0x20b
    unsigned int indexRecord[5]={0x00,0x00,0x5,0x7E6,0x82E};
    fwrite(&indexRecordFlag,4,1,fd);
    fwrite(&indexRecord,20,1,fd);
            
    unsigned short int defColWidthArea[3] ={0x55,0x2,0x8};  //宽度?
    fwrite(defColWidthArea,6,1,fd);
    */

    unsigned short int xlsDimensions={0x200};  //维度
    unsigned short int xlsDimenLen={0xe}; 
    unsigned  int firstRow=0;
    unsigned  int lastRow=6;
    unsigned short int firstCol=0;
    unsigned short int lastCol=1;

    fwrite(&xlsDimensions,2,1,fd);
    fwrite(&xlsDimenLen,2,1,fd);
    fwrite(&firstRow,4,1,fd);
    fwrite(&lastRow,4,1,fd);
    fwrite(&firstCol,2,1,fd);
    fwrite(&lastCol,2,1,fd);
    fwrite(&xlsZero4,2,1,fd);

    unsigned short int sstLabel={0xfd}; //行、列字符串信息
    unsigned short int sstLabelLen={0xa};
    unsigned short int rowNum=0;
    unsigned short int colNum=0;
    unsigned short int xfIdx=0;
    unsigned  int sstIdx=0;
    for(int x=0;x<uniqStrCount;x++)
    {
        fwrite(&sstLabel,2,1,fd);
        fwrite(&sstLabelLen,2,1,fd);
        rowNum=x;
        fwrite(&rowNum,2,1,fd);
        fwrite(&colNum,2,1,fd);
        fwrite(&xfIdx,2,1,fd);
        sstIdx=x;
        fwrite(&sstIdx,4,1,fd);
    }
    fwrite(&xlsEOF,2,1,fd);
    byteWrote=ftell(fd)%512;
    for(int x=0;x<512-byteWrote;x++) fwrite(&xlsZero4,1,1,fd);

    //workbook区,凑够8个block:
    for(i=0;i<6;i++) fwrite(&blockZero,512,1,fd);
    //SummaryInformation区,凑够8个block:
    for(i=0;i<8;i++) fwrite(&blockZero,512,1,fd);
    //DocumentSummaryInformation区,凑够8个block:
    for(i=0;i<8;i++) fwrite(&blockZero,512,1,fd);
    //blockChain:
    unsigned int chain1=-3;
    unsigned int chainEOF=-2;

    char xlsFree=-1;
    unsigned int chainTotal=0x1b;
    chainTotal=chainTotal-3;
    unsigned short int bl=512;

    for(unsigned int x=1;x<chainTotal;x++)     
    {
        
        if(x%8==0) fwrite(&chainEOF,4,1,fd);
        else fwrite(&x,4,1,fd);
        bl=bl-4;
    }
    fwrite(&chainEOF,4,1,fd);
    fwrite(&chain1,4,1,fd);
    fwrite(&chainEOF,4,1,fd);
    
    for(int x=0;x<bl-12;x++) fwrite(&xlsFree,1,1,fd);

    /* Storage_Directory_Entry : */
    //Root:
    wchar_t dir_root[64];
    memset(dir_root,0,64);
    wcscpy(dir_root,L"Root Entry");
    fwrite(dir_root,64,1,fd);
    unsigned short int dir_root_len=0x16;
    unsigned char type_of_root=0x5;
    unsigned char node_colour_of_entry=0x1;
    unsigned int did_root[3]={-1,-1,2};
    unsigned int rootSecPos=-2;
    unsigned int rootSecSize=0x0;

    fwrite(&dir_root_len,2,1,fd);
    fwrite(&type_of_root,1,1,fd);
    fwrite(&node_colour_of_entry,1,1,fd);
    
    fwrite(&did_root,12,1,fd);
    for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
    fwrite(&rootSecPos,4,1,fd);
    fwrite(&rootSecSize,4,1,fd);
    fwrite(&xlsZero4,4,1,fd);

    //Workbook:
    wchar_t dir_wb[64];
    memset(dir_wb,0,64);
    wcscpy(dir_wb,L"Workbook");
    fwrite(dir_wb,64,1,fd);    
    unsigned short int dir_wb_len=0x12;
    unsigned char type_of_wb=0x2;
    //unsigned char node_colour_of_entry=0x1;
    unsigned int did_wb[3]={-1,-1,-1};
    unsigned int wbSecPos=0;
    unsigned int wbSecSize=0x1000;

    fwrite(&dir_wb_len,2,1,fd);
    fwrite(&type_of_wb,1,1,fd);
    fwrite(&node_colour_of_entry,1,1,fd);
    
    fwrite(&did_wb,12,1,fd);
    for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
    fwrite(&wbSecPos,4,1,fd);
    fwrite(&wbSecSize,4,1,fd);
    fwrite(&xlsZero4,4,1,fd);

    //Summary:
    wchar_t dir_sinfo[64];
    memset(dir_sinfo,0,64);
    wcscpy(dir_sinfo,L"\x5SummaryInformation");
    fwrite(dir_sinfo,64,1,fd);
    unsigned short int dir_sum_len=0x28;
    unsigned char type_of_sum=0x2;
    //unsigned char node_colour_of_entry=0x1;
    unsigned int did_sum[3]={1,3,-1};
    unsigned int sumSecPos=0x8;
    unsigned int sumSecSize=0x1000;

    fwrite(&dir_sum_len,2,1,fd);
    fwrite(&type_of_sum,1,1,fd);
    fwrite(&node_colour_of_entry,1,1,fd);
    
    fwrite(&did_sum,12,1,fd);
    for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
    fwrite(&sumSecPos,4,1,fd);
    fwrite(&sumSecSize,4,1,fd);
    fwrite(&xlsZero4,4,1,fd);

    //DocumentSummary:
    wchar_t dir_dsinfo[64];
    memset(dir_dsinfo,0,64);
    wcscpy(dir_dsinfo,L"DocumentSummaryInformation");
    fwrite(L"\x5",2,1,fd);
    fwrite(dir_dsinfo,62,1,fd);
    unsigned short int dir_dsum_len=0x38;
    unsigned char type_of_dsum=0x2;
    //unsigned char node_colour_of_entry=0x1;
    unsigned int did_dsum[3]={-1,-1,-1};
    unsigned int dsumSecPos=0x10;
    unsigned int dsumSecSize=0x1000;

    fwrite(&dir_dsum_len,2,1,fd);
    fwrite(&type_of_dsum,1,1,fd);
    fwrite(&node_colour_of_entry,1,1,fd);
    
    fwrite(&did_dsum,12,1,fd);
    for(int x=0;x<36;x++) fwrite(&xlsZero4,1,1,fd);
    fwrite(&dsumSecPos,4,1,fd);
    fwrite(&dsumSecSize,4,1,fd);
    fwrite(&xlsZero4,4,1,fd);

    
    
    fflush(fd);
    fclose(fd);

    system("pause");
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值