totalRows();}size_tworksheet::getTotalCols(){ret" />

读取xls文件的Qt原代码

Biff8.cpp
#include "Biff8.h"
#include
namespace ExceLite
{
bool worksheet::set(Worksheet* psheet)
{
_psheet=psheet;
return true;
}
size_t worksheet::getTotalRows()
{
return _psheet->totalRows();
}

size_t worksheet::getTotalCols()
{
return _psheet->totalCols();
}

BIFF8Reader::BIFF8Reader()
{

}
BIFF8Reader::BIFF8Reader(const char* filename)
{
this->Load(filename);
}
BIFF8Reader::~BIFF8Reader()
{
for(int i=0;i<_sheets.count();i++)
if(_sheets[i]) delete _sheets[i];
}

bool BIFF8Reader::Load(const char* filename)
{
_recIO.LoadCompdDoc(QString::fromLocal8Bit(filename));
_recIO.seekToBegin(0);
_global.readGlobal(_recIO);
_sheets.resize(_global.getSheetCount());
_sheets.fill(NULL);
return true;
}

size_t BIFF8Reader::GetTotalSheets()
{
return _global.getSheetCount();
}

bool BIFF8Reader::GetWorksheet(size_t sheetIndex,worksheet & sheet)
{
if(_sheets[sheetIndex])
{
sheet.set(_sheets[sheetIndex]);
return true;
}

Worksheet* tsheet=new Worksheet;
_recIO.seekToBegin(_global._boundsheets[sheetIndex].lbPlyPos);
//std::cout<<_global._boundsheets[sheetIndex].name.toLocal8Bit() <<"\n";
_sheets[sheetIndex]=tsheet;
tsheet->setGlobal(&_global);
tsheet->readSheet(_recIO);
sheet.set(_sheets[sheetIndex]);
return true;
}
} // End namespace

Biff8.h
#ifndef BIFF8RC_H
#define BIFF8RC_H

#include "Records.h"
#include "Workglobal.h"
#include "Worksheet.h"

using namespace Records;
using namespace global;
using namespace sheet;
namespace ExceLite
{
class worksheet
{
friend class BIFF8Reader;
public:
size_t getTotalRows();
size_t getTotalCols();

private:
bool set(Worksheet* psheet);
Worksheet* _psheet;
//BasicExcelCell* Cell(size_t row, size_t col);
};
class cell
{
//int Type() const;
//int GetInteger() const;
//double GetDouble() const;
//const char* GetString() const;
};
class BIFF8Reader
{
public:
BIFF8Reader();
BIFF8Reader(const char* filename);
~BIFF8Reader();
bool Load(const char* filename);

public:
size_t GetTotalSheets();
bool GetWorksheet(size_t sheetIndex,worksheet & sheet);
// BasicExcelWorksheet* GetWorksheet(const char* name);

private:

RecordIO _recIO;
Workglobal _global;
QVector _sheets;
};
}


#endif // BIFF8RC_H

ByteOrderBuffer.h
#ifndef BYTEORDERBUFFER_H
#define BYTEORDERBUFFER_H


#include

#define UTF16
#ifdef UTF16
#define SIZEOFWCHAR_T 2
#else
#define SIZEOFWCHAR_T sizeof(UChar16)
#endif

using namespace std;
namespace BinBuf
{
enum ByteOrder
{
BIG_ENDIAN_BYTE_ORDER = 1, /

// big-endian (network) byte-order
LITTLE_ENDIAN_BYTE_ORDER = 2, /// little-endian byte-order
};

class BinaryFromBuffer
{
public:
BinaryFromBuffer(vector& buf, ByteOrder byteOrder = LITTLE_ENDIAN_BYTE_ORDER);

template
void FromBuf(Type& retVal, int pos, int bytes)
{
retVal = Type(0);
if (bytes == 0) bytes = sizeof(Type);
if(_isLE)
{
for (int i=0; i{
retVal += ((static_cast(_buf[pos+i])) << 8*i);
}
}
else
{
for (int i=0; i{
//retVal |= ((Type)((unsigned char)_buf[pos+i])) >> 8*i;
}
}
}

template
void StringFromBuf(Type* str, int pos=0, int bytes=0)
{
for (int i=0; i}

private:
vector& _buf;
bool _isLE;
};

BinaryFromBuffer::BinaryFromBuffer(vector& buf, ByteOrder byteOrder):
_buf(buf)
{
_isLE = (byteOrder == LITTLE_ENDIAN_BYTE_ORDER);
}




/* to be revised
struct BinaryWriter
{
template
static void Write(char* buffer, Type val, int pos=0, int bytes=0)
{
if (bytes == 0) bytes = sizeof(Type);
for (size_t i=0; i{
buffer[pos+i] = (unsigned char)val;
val >>= 8;
}
}

template
static void WriteString(char* buffer, Type* str, int pos=0, int bytes=0)
{
for (size_t i=0; i}
template
static void Write(vector& buffer, Type val, int pos=0, int bytes=0)
{
if (bytes == 0) bytes = sizeof(Type);
for (size_t i=0; i{
buffer[pos+i] = (unsigned char)val;
val >>= 8;
}
}

template
static void WriteString(vector& buffer, Type* str, int pos=0, int bytes=0)
{
for (size_t i=0; i}
static void Write(char* buffer, UChar16 val, int pos=0, int bytes=0)
{
if (bytes == 0) bytes = SIZEOFWCHAR_T;
for (int i=0; i{
buffer[pos+i] = (unsigned char)val;
val >>= 8;

}
}

static void WriteString(char* buffer, UChar16* str, int pos=0, int bytes=0)
{
for (int i=0; i}
static void Write(vector& buffer, UChar16 val, int pos=0, int bytes=0)
{
if (bytes == 0) bytes = SIZEOFWCHAR_T;
for (int i=0; i{
buffer[pos+i] = (unsigned char)val;
val >>= 8;
}
}

static void WriteString(vector& buffer, UChar16* str, int pos=0, int bytes=0)
{
for (int i=0; i}
};
*/
}
#endif // BYTEORDERBUFFER_H

CompDoc.cpp
#include "CompDoc.h"
#include

namespace CompoundDoc
{
CompdDoc::CompdDoc():
_fileName(""),
_fat(0),
_dirEntries(0),
_miniFat(0),
_sectFat(0)
{
}

CompdDoc::CompdDoc(QString file):
_fileName(file),
_fat(0),
_dirEntries(0),
_miniFat(0),
_sectFat(0)
{
this->Open(file);
}

CompdDoc::~CompdDoc()
{
this->Close();
}
bool CompdDoc::Open(QString file)
{
_fileName=file;
_file.setFileName(_fileName);
_file.open(QIODevice::ReadOnly);
this->ReadHeader();
this->_loadFatSectorIds();
this->_loadFat();
this->_loadMiniFat();
_loadDirEntries();
return true;
}

void CompdDoc::Close( )
{
if(_file.isOpen()) _file.close();
}
RESULTCODE CompdDoc::ReadHeader()
{
QDataStream _stream(&_file);
_stream.device()->seek(0);
RESULTCODE code=_header.FromStream(_stream);
if(code!=SUCCESS) return code;
_sizeSector = (1 << _header._uSectorShift); // 计算Sector字节数.
_sizeMiniSector = (1<< _header._uMiniSectorShift); // 计算miniSector字节数.
if(_sizeSector%4 || _sizeSector%128) return SECTOR_NOT_SUPPORT;
_csidSector = _sizeSector/4;
_cdeSector = _sizeSector/128;
if(!( _header._uByteOrder == 0xFFFE || _header._uByteOrder == 0xFEFF)) return BYTEORDER_NOT_SUPPORT;
_byteorder = _header._uByteOrder== 0xFFFE?QDataStream::LittleEndian:QDataStream::BigEndian;

return SUCCESS;
}

#ifdef _DEBUGCOMPDOC
void CompdDoc::PRINT_HEADER()
{
QFile _f("C:/doc/header.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
//qs.setByteOrder(_byteorder);
qs << _header._abSig <<'\n'
<< _header._clid <<'\n'
<< _header._uminorVersion <<'\n'
<< _header._uDllVersion <<'\n'
<< _header._uByteOrder

<<'\n'
<< _header._uSectorShift <<'\n'
<< _header._uMiniSectorShift <<'\n'
<< _header._usReserved <<'\n'
<< _header._ulReserved1 <<'\n'
<< _header._ulReserved2 <<'\n'
<< _header._csectFat <<'\n'
<< _header._sectDirStart <<'\n'
<< _header._signature <<'\n'
<< _header._ulMiniSectorCutoff <<'\n'
<< _header._sectMiniFatStart <<'\n'
<< _header._csectMiniFat <<'\n'
<< _header._sectDifStart <<'\n'
<< _header._csectDif <<'\n';
for(int i=0;i<109;i++)
qs << _header._sectFat[i] <<'\n';
}
void CompdDoc::PRINT_SECTOR()
{
QFile _f("C:/doc/sector0.txt");
_f.open(QIODevice::WriteOnly);
QDataStream qs(&_f);

QByteArray _bytes;
//_readSector(0,_bytes);
_readSectorChains(_header._sectDirStart,_bytes);
qs.writeRawData(_bytes.data(),_bytes.count());
}

void CompdDoc::PRINT_FATSECTID()
{
QFile _f("C:/doc/difs.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
// qs.setByteOrder(_byteorder);
for(int i=0;i<_sectFat.count();i++)
qs << _sectFat[i]<<'\n';
qs << "number of difs:" << _sectFat.count();
}
void CompdDoc::PRINT_FAT()
{
QFile _f("C:/doc/fat.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
//qs.setByteOrder(_byteorder);
qint32 p;
//p=_header._sectDirStart;

for(int i=0;i<_fat.count(); i++)
{

p=_fat[i];qs <}
}
void CompdDoc::PRINT_MINIFAT()
{
QFile _f("C:/doc/minifat.txt");
_f.open(QIODevice::WriteOnly);
QDataStream qs(&_f);
qs.setByteOrder(_byteorder);
for(int i=0;i<_miniFat.count(); i++)
qs << _fat[i];
}

void CompdDoc::PRINT_DIRENTRIES()
{
QFile _f("C:/doc/de.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
//qs.setByteOrder(_byteorder);
for(int i=0;i<_dirEntries.count(); i++)
{
qs << _dirEntries[i]._entryName
<< '\n'
<< _dirEntries[i]._nameSize
<< '\n'
<< _dirEntries[i]._mse
<< '\n'
<< _dirEntries[i]._sectStart
<< '\n'
<< _dirEntries[i]._ulSize
<< '\n'
<< _dirEntries[i]._path
<< "\n===========================\n";
}

}
void CompdDoc::PRINT_DATA()
{
QFile _f("C:/doc/data.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
QByteArray data;
R

eadStream(QString::fromAscii("Workbook"),QString::fromAscii("/"),data);
qs << data;
}
#endif

CompdDoc::Header::Header():
_abSig(OLE2MAGICTAG),
_clid(0),
_uminorVersion(0x003E),
_uDllVersion(0x0003),
_uByteOrder(0xFFFE),
_uSectorShift(9),
_uMiniSectorShift(6),
_usReserved(0),
_ulReserved1(0),
_ulReserved2(0),
_csectFat(0),
_sectDirStart(ENDOFCHAIN),
_signature(0),
_ulMiniSectorCutoff(0x1000),
_sectMiniFatStart(ENDOFCHAIN),
_csectMiniFat(0),
_sectDifStart(ENDOFCHAIN),
_csectDif(0)
{
_sectFat.fill(FREESECT,109);
}

RESULTCODE CompdDoc::Header::FromStream(QDataStream& buf)
{
buf.setByteOrder(QDataStream::LittleEndian);
buf >> _abSig
>> _clid
>> _uminorVersion
>> _uDllVersion
>> _uByteOrder
>> _uSectorShift
>> _uMiniSectorShift
>> _usReserved
>> _ulReserved1
>> _ulReserved2
>> _csectFat
>> _sectDirStart
>> _signature
>> _ulMiniSectorCutoff
>> _sectMiniFatStart
>> _csectMiniFat
>> _sectDifStart
>> _csectDif;
for(int i=0;i<109;i++)
buf >> _sectFat[i];
if(_abSig!=OLE2MAGICTAG) return NOT_COMPOUND_FILE;
return SUCCESS;
}

CompdDoc::DirectoryEntry::DirectoryEntry():
_entryName(""),
_nameSize(0),
_mse(STGTY_STORAGE),
_bflags(DE_BLACK),
_sidLeftSib(-1),
_sidRightSib(-1),
_sidChild(-1),
_clsId(0),
_dwUserFlags(0),
_time1(0),
_time2(0),
_sectStart(ENDOFCHAIN),
_ulSize(0),
_dptPropType(0),
_path("")
{

}

RESULTCODE CompdDoc::DirectoryEntry::FromStream(QDataStream& buf)
{
quint16 qc;
for(int i=0;i<32;i++)
{
buf >> qc;
_entryName.append(qc);
}
buf >> _nameSize
>> _mse
>> _bflags
>> _sidLeftSib
>> _sidRightSib
>> _sidChild
>> _clsId
>> _dwUserFlags
>> _time1
>> _time2
>> _sectStart
>> _ulSize
>> _dptPropType;
_entryName=_entryName.left((_nameSize>>1)-1);
return SUCCESS;
}
//Read a single Sector
bool CompdDoc::_readSector(qint32 sectID, QByteArray& bytes)
{
#ifdef _DEBUGCOMPDOC
std::cout << "Read sector From:" << 512 + sectID * _sizeSector <<"\n";
#endif
_file.seek(512 + sectID * _sizeSector);
bytes=_file.read(_sizeSector);
return true;
}

// read a chains of Sectors
int CompdDoc::_readSectorChains(qint32 startSectID,QByteArray& bytes)
{

qint32 next=startSectID;
#ifdef _DEBUGCOMPDOC
QFile _f("C:/doc/chains.txt");
_f.open(QIODevice::WriteOnly);
QTextStream qs(&_f);
int count=0;
#endif
QByteArray tmparray;

int count=0;
while(next >=0)
{
#ifdef _DEBUGCOMPDOC
// qs << next << '\n';

std::cout<<"\nChained sector:"<#endif
_readSector(next,tmparray);
bytes+=tmparray;
count++;
next = _fat[next];
}
#ifdef _DEBUGCOMPDOC
std::cout<<"\nThe last sect of chains:"<#endif
return count*_sizeSector;
}

int CompdDoc::_readSectorChains(qint32 startSectID,QFile& file)
{
QDataStream qs(&file);
qs.setByteOrder(_byteorder);
qint32 next=startSectID;
QByteArray tmparray;
int count=0;
while(next >=0)
{
_readSector(next,tmparray);
qs.writeRawData(tmparray.data(),tmparray.count());
count++;
next = _fat[next];
}
return count*_sizeSector;
}

// load Fat Sector Ids both in header and extend Difs
bool CompdDoc::_loadFatSectorIds()
{
#ifdef _DEBUGCOMPDOC
QFile _logfile("c:/doc/debug.txt");
_logfile.open(QIODevice::ReadWrite);
QDataStream _log(&_logfile);;
_log.setByteOrder(_byteorder);
#endif
for(int i=0;i<109;i++)
{
if(FREESECT == _header._sectFat[i]) break;
_sectFat.push_back(_header._sectFat[i]);
}

qint32 next = _header._sectDifStart; //can't use quint32,if,then compare not working
qint32 id;
while(next >= 0) //in the specification it says,dif chain teminated by ENDOFCHAIN,but some software make FREESECT
{
#ifdef _DEBUGCOMPDOC
_log << next;
#endif
QByteArray difArray;
_readSector(next,difArray);
QDataStream qs(difArray);
qs.setByteOrder(_byteorder);
for(int i=0;i<_csidSector-1;i++)
{
qs >> id;
if(id < 0) break;
_sectFat.push_back(id);
}
qs>>next; // need to test with very big file
}
return true;
}

bool CompdDoc::_loadFat()
{
#ifdef _DEBUGCOMPDOC
std::cout << "Begin to load Fat,fat used sectors:"<< _sectFat.count() <<"\n";
#endif
QByteArray fatArray;
for(int i=0;i<_sectFat.count();i++)
{
#ifdef _DEBUGCOMPDOC
std::cout << "Fat sector Id:"<< _sectFat[i] <<"\n";
#endif
fatArray.clear();
_readSector(_sectFat[i],fatArray);
QDataStream qs(fatArray);
qs.setByteOrder(_byteorder);
qint32 id;
for(int sec=0;sec<_csidSector;sec++)
{
qs >> id;
#ifdef _DEBUGCOMPDOC
std::cout << "Print FAT:"<

+sec <<":"<#endif
_fat.push_back(id);
}
}
return true;
}

bool CompdDoc::_loadMiniFat()
{
#ifdef _DEBUGCOMPDOC
std::cout << "Begin to load MiniFat: \n";
#endif
QByteArray minifatArray;
_readSectorChains(_header._sectMiniFatStart,minifatArray);
QDataStream qs(minifatArray);
qs.setByteOrder(_byteorder);
quint32 id;
while(!qs.atEnd())
{
qs >> id;
_miniFat.push_back(id);
}
return true;
}

bool CompdDoc::_loadDirEntries()
{
#ifdef _DEBUGCOMPDOC
std::cout << "Begin to load Directory Entry: \n";
#endif
QByteArray dirSectors;
_readSectorChains(_header._sectDirStart,dirSectors);
#ifdef _DEBUGCOMPDOC
std::cout << "Read Directory Entry sectors finished: \n";
#endif
_loadDirEntry(0,"",dirSectors);
return true;
}

bool CompdDoc::_loadDirEntry(qint32 did,QString path,QByteArray sectors)
{
QByteArray tArray;
tArray = sectors.mid(did*128,128);

QDataStream qs(tArray);
qs.setByteOrder(_byteorder);
DirectoryEntry de;
de.FromStream(qs);

de._did=did;
de._path=path;

if(de._mse!=STGTY_INVALID)
{
_dirEntries.append(de);
}
if(de._sidLeftSib>0) _loadDirEntry(de._sidLeftSib,path,sectors);
if(de._sidChild>0)
{
if(did == 0)
_loadDirEntry(de._sidChild,"/",sectors);
else
{
QString tpath=path;
tpath.append(de._entryName);

tpath.append("/");
_loadDirEntry(de._sidChild,tpath,sectors);
}
}
if(de._sidRightSib>0) _loadDirEntry(de._sidRightSib,path,sectors);


return true;
}

bool CompdDoc::ReadStream(QString streamName,QString storage, QByteArray& data)
{
DirectoryEntry* de = NULL;

#ifdef _DEBUGCOMPDOC
QFile _f("C:/doc/names.txt");
_f.open(QIODevice::WriteOnly);
QDataStream qs(&_f);
qs.setByteOrder(_byteorder);
#endif
for(int i=0;i<_dirEntries.count();i++)
{
#ifdef _DEBUGCOMPDOC
qs << streamName
<< '\n'
<< _dirEntries[i]._entryName
<< '\n';
std::cout<< streamName.count()<<'\n';
std::cout<< _dirEntries[i]._entryName.count()<<'\n';

#endif
if( _dirEntries[i]._https://www.360docs.net/doc/b67100791.html,pare(streamName) == 0 && _dirEntries[i]._path == storage )
de = &_dirEntries[i];
}

if(de!=NULL)
{
if(de->_ulSize>_sizeMiniSector)
{
#ifdef _DEBUGCOMPDOC
std::cout << "yes,I found it in sector";
#endif
if(de->_ulSize!= _readSectorCh

ains(de->_sectStart,data))
{

std::cout << "Incorrect data size!.....";

return false;
}

}
else
{
#ifdef _DEBUGCOMPDOC
std::cout << "yes,I found it in mini-sector";
#endif
//to be implemented
}
}
else
{
#ifdef _DEBUGCOMPDOC
std::cout << "no,I can't found it";
#endif
}

return true;
}

bool CompdDoc::ReadStream(QString streamName,QString storage,QFile& tFile)
{
DirectoryEntry* de = NULL;

for(int i=0;i<_dirEntries.count();i++)
{

if( _dirEntries[i]._https://www.360docs.net/doc/b67100791.html,pare(streamName) == 0 && _dirEntries[i]._path == storage )
de = &_dirEntries[i];
}

if(de!=NULL)
{
if(de->_ulSize>_sizeMiniSector)
{
_readSectorChains(de->_sectStart,tFile);
}
else
{
//to be implemented
}
}
else
{

}
return true;
}

}//End namespace

CompDoc.h
#ifndef COMPDOC_H
#define COMPDOC_H
#include



namespace CompoundDoc
{
const quint64 OLE2MAGICTAG = 0xE11AB1A1E011CFD0;
const qint32 DIFSECT = 0xFFFFFFFC;
const qint32 FATSECT = 0xFFFFFFFD;
const qint32 ENDOFCHAIN = 0xFFFFFFFE;
const qint32 FREESECT = 0xFFFFFFFF;
typedef quint64 TIME_T;
typedef enum tagSTGTY
{
STGTY_INVALID = 0,
STGTY_STORAGE = 1,
STGTY_STREAM = 2,
STGTY_LOCKBYTES = 3,
STGTY_PROPERTY = 4,
STGTY_ROOT = 5,
} STGTY;
typedef enum tagDECOLOR
{
DE_RED = 0,
DE_BLACK = 1,
} DECOLOR;

typedef enum tagRESULT
{
SUCCESS=1,
FILE_NOT_FOUND = -1,
NOT_COMPOUND_FILE = -2,
STREAM_NAME_TOO_LONG =-3,
STREAM_NOT_FOUND =-4,
DIRECTORY_NOT_EMPTY =-5,
SECTOR_NOT_SUPPORT =-6,
MINISECTOR_NOT_SUPPORT =-7,
BYTEORDER_NOT_SUPPORT =-8,
} RESULTCODE;

class CompdDoc
{
public:
CompdDoc();
CompdDoc(QString file);
~CompdDoc();
bool Open(QString file);
void Close();
bool ReadStream(QString streamName,QString storage, QByteArray& data);
bool ReadStream(QString streamName,QString storage,QFile& tFile);
QDataStream::ByteOrder byteOrder(){return _byteorder;}
#ifdef _DEBUGCOMPDOC
void PRINT_HEADER();
void PRINT_SECTOR();
void PRINT_FATSECTID();
void PRINT_FAT();
void PRINT_MINIFAT();
void PRINT_DIRENTRIES();
void PRINT_DATA();
#endif

protected:
class Header
{
public:
Header();
RESULTCODE FromStream(QDataStream& buf);

quint64 _abSig;
QUui

d _clid;
quint16 _uminorVersion;
quint16 _uDllVersion;
quint16 _uByteOrder;
quint16 _uSectorShift;
quint16 _uMiniSectorShift;
quint16 _usReserved;
quint32 _ulReserved1;
quint32 _ulReserved2;
quint32 _csectFat;
qint32 _sectDirStart;
quint32 _signature;
quint32 _ulMiniSectorCutoff;
qint32 _sectMiniFatStart;
quint32 _csectMiniFat;
qint32 _sectDifStart;
quint32 _csectDif;
QVector _sectFat; // Array of block indices constituting the Block Allocation Table (BAT) (0x004C, 0x0050, 0x0054 ... 0x01FC)

private:
void Initialize();
};
Header _header;
class DirectoryEntry
{
public:
DirectoryEntry();
RESULTCODE FromStream(QDataStream& buf);
QString _entryName;
qint16 _nameSize;
quint8 _mse;
quint8 _bflags;
qint32 _sidLeftSib;
qint32 _sidRightSib;
qint32 _sidChild;
QUuid _clsId;
quint32 _dwUserFlags;
TIME_T _time1;
TIME_T _time2;
qint32 _sectStart;
quint32 _ulSize;
quint32 _dptPropType;
QString _path;
qint16 _did;
};

private:
QString _fileName;
QFile _file;
quint16 _sizeSector;
quint16 _sizeMiniSector;
quint16 _csidSector; //Sectorid per Sector can store
quint16 _cdeSector; //Directory entries per Sector can have
QDataStream::ByteOrder _byteorder; //Byte_Order the CopoundDoc used

QVector _sectFat; //ids of Sectors that used by Fat
QVector _fat; //Fat list
QVector _miniFat;
QVector _dirEntries;
RESULTCODE ReadHeader();
bool _readSector(qint32 sectID, QByteArray& bytes);
int _readSectorChains(qint32 startSectID,QByteArray& bytes);
int _readSectorChains(qint32 startSectID,QFile& file);
bool _loadFatSectorIds();
bool _loadFat();
bool _loadMiniFat();
bool _loadDirEntry(qint32 did,QString path,QByteArray sector);
bool _loadDirEntries();
};
}
#endif // COMPDOC_H

main.cpp
#include
#include
#include "CompDoc.h"
#include "Biff8.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

//CompoundDoc::CompdDoc xls("c:/doc/test1.xls");

//cout << xls._sizeSector << " and " <#ifdef _DEBUGCOMPDOC
xls.PRINT_HEADER();
xls.PRINT_SECTOR();
xls.PRINT_FATSECTID();
xls.PRINT_FAT();
xls.PRINT_MINIFAT();
xls.PRIN

T_DIRENTRIES();
xls.PRINT_DATA();
#endif
/* std::cout<<"Finished!";
QString t=xls.ReadStream(QString::fromAscii("Workbook"),QString::fromAscii("/"));
QFile comoundfile(t);
comoundfile.open(QIODevice::ReadWrite);
QDataStream qs(&comoundfile);
qs.setByteOrder(xls.byteOrder());
quint16 i;
qs >> i;
if(i!=0x0809)
std::cout<< "it's not a biff8 file\n";
else
std::cout<< "it looks like a biff8 file\n";
*/
ExceLite::BIFF8Reader biff8("d:/doc/test6.xls");
ExceLite::worksheet sheet;
std::cout << biff8.GetTotalSheets() << "\n";
biff8.GetWorksheet(0,sheet);
std::cout<<"Finished!oh-yes";
return a.exec();
}

Records.cpp
#include "Records.h"
#include "CompDoc.h"
using namespace CompoundDoc;
namespace Records
{
RecordIO::RecordIO()
: _byteorder(QDataStream::LittleEndian),
_order(0),
_size(0)
{
_tmpDataFile.open();
_tmpDataFile.setAutoRemove(true);
}
RecordIO::~RecordIO()
{
}

qint64 RecordIO::goNext()
{
QDataStream qs(_tmpDataFile.read(4));
qs.setByteOrder(_byteorder);
qs >> _order
>> _size;
return _tmpDataFile.pos();
}

qint64 RecordIO::SkipRecord()
{
_tmpDataFile.seek( _tmpDataFile.pos()+_size);
return _tmpDataFile.pos();
}

qint64 RecordIO::seekToBegin(qint64 beginpos)
{
_tmpDataFile.seek(beginpos);
return _tmpDataFile.pos();
}

bool RecordIO::ReadRawRecord(QByteArray &data)
{
data=_tmpDataFile.read(this->_size);
return true;
}

bool RecordIO::LoadCompdDoc(QString xlsfilename)
{
CompdDoc _xlsFile;
_xlsFile.Open( xlsfilename);
_byteorder=_xlsFile.byteOrder();

_xlsFile.ReadStream(QString::fromAscii("Workbook"),QString::fromAscii("/"),_tmpDataFile);
_xlsFile.Close();
_tmpDataFile.seek(0);
QTemporaryFile test;
test.open();
test.write(QByteArray("testing"));
return true;
}

bool Bof::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs>> vers
>> dt
>> rupBuild
>> rupYear
>> bfh
>> sfo;
return true;
}

biff8String::biff8String():cch(-1),grbit(0),fHighByte(false),fExtSt(false),
fRichSt(false),crun(0),cchExtRst(0),cch_read(0),
innerstr(""),rgSTRUN(0),restbytes(0),isFinished(true)
{
//init
}

void biff8String::reset()
{
//reset to initial values
cch=-1;
grbit=0;
fHighByte=false;
fExtSt=false;
fRichSt=false;
crun=0;
cchExtRst=0;
cch_read=0;
innerstr="";
rgSTRUN.clear();
restbytes=0;
isFinished=true;
}

QString bi

ff8String::ParseString(QDataStream& dqs,bool len2bytes)
{
qint8 zippedchar;
qint16 unzippedchar;
if(!isFinished)
{
if(cch_read{
qint8 reoption=0;
dqs >> reoption;
fHighByte=reoption&0x01;
}
while(cch_read{
if(dqs.atEnd()) break;
if( fHighByte)
{
dqs >>unzippedchar; innerstr.append(QChar(unzippedchar));cch_read++;
}
else
{
dqs >>zippedchar; innerstr.append(QChar(zippedchar));cch_read++;
}
}
if(restbytes > 0)
{
int size2end=dqs.device()->size()-dqs.device()->pos();
if(size2end>=restbytes)
{
dqs.skipRawData(restbytes);
restbytes=0;
}
else
{
dqs.skipRawData( size2end);
restbytes=restbytes-size2end;
}
}
if (cch==cch_read&&restbytes==0)
{
isFinished=true;
// tqs << innerstr<<"\n";
return innerstr;
}
else
{
isFinished=false;return "";
}
}

this->reset();
if(len2bytes) dqs >> cch;
else { qint8 cch8;dqs >> cch8; cch=cch8;}

dqs >> grbit;
//tqs << "begin of String:"<fHighByte = grbit & 0x01;
fExtSt = grbit & 0x04;
fRichSt = grbit & 0x08;
if(fRichSt ) dqs >> crun;
if(fExtSt) dqs >> cchExtRst;
while(!dqs.atEnd()&&cch_read!=cch)
{
if( fHighByte)
{
dqs >>unzippedchar; innerstr.append(QChar(unzippedchar));cch_read++;
}
else
{
dqs >>zippedchar; innerstr.append(QChar(zippedchar));cch_read++;
}
}

int size2end=dqs.device()->size()-dqs.device()->pos();
int size2skip=cchExtRst+4*crun;
if( size2end>=size2skip)
{
dqs.skipRawData(size2skip);
restbytes=0;
}
else
{
dqs.skipRawData(size2end);
restbytes=size2skip-size2end;
}
if(cch==cch_read&&restbytes==0)
{
isFinished=true;
return innerstr;
}
else
{
isFinished=false;return "";
}

}
}//end namespace

Records.h
#ifndef RECORDS_H
#define RECORDS_H
#include

namespace Records
{
struct ORDER
{
typedef enum tagORDER
{
RO_UAV = 0x0000,
RO_ARRAY = 0x0221,
RO_BLANK

= 0x0201,
RO_BOOLERR = 0x0205,
RO_FORMULA = 0x0006,
RO_LABEL = 0x0018,
RO_LABELSST = 0x00FD,
RO_NUMBER = 0x0203,
RO_MULBLANK = 0x00BE,
RO_MULRK = 0x00BD,
RO_RK = 0x027E,
RO_RSTRING = 0x00D6,
RO_SHRFMLA = 0x04BC,
RO_1904 = 0x0022,
RO_BOF = 0x0809,
RO_BOUNDSHEET = 0x0085,
RO_COLINFO = 0x007D,
RO_CONTINUE = 0x003C,
RO_DBCELL = 0x00D7,
RO_DEFCOLWIDTH = 0x0055,
RO_DIMENSIONS = 0x0200,
RO_EOF = 0x000A,
RO_EXTSST = 0x00FF,
RO_FILEPASS = 0x002F,
RO_FONT = 0x0031,
RO_FORMAT = 0x041E,
RO_HLINK = 0x01B8,
RO_INDEX = 0x020B,
RO_MERGECELLS = 0x00E5,
RO_NAME = 0x0218,
RO_NOTE = 0x001C,
RO_PALETTE = 0x0092,
RO_ROW = 0x0208,
RO_SST = 0x00FC,
RO_STANDARDWIDTH= 0x0099,
RO_STRING = 0x0207,
RO_TXO = 0x01B6,
RO_XF = 0x00E0,
RO_WINDOW2 = 0x023E,
RO_SELECTION = 0x001D,
RO_PHONETICPR = 0x00EF,//This record contains default settings for the “Asian Phonetic Settings” dialog and the addresses of all cells which show Asian phonetic text.
RO_FEATHEADR = 0x0867,
}RECORDORDER;
};

struct STREAMTYPE
{
typedef enum _tagStreamType
{
GLOBALS_SUBSTREAM=0x0005,
VBM_SUBSTREAM=0x0006,
WORKSHEET_SUBSTREAM=0x0010,
CHART_SUBSTREAM=0x0020,
}TYPEID;
};

struct CELLTYPE
{
typedef enum _tagCellDataType
{
BLANK=0x00,
INT =0x01,
FLOAT = 0x02,
TEXT = 0x03,
ERROR = 0x04,
BOOL = 0x05,
} typeCELL;
};

struct CELLERROR
{
typedef enum _tagCellError
{
ERR_NULL=0x00,
ERR_DIV =0x07,
ERR_VALUE = 0x0F,
ERR_REF = 0x17,
ERR_NAME = 0x1D,
ERR_NUM = 0x24,
ERR_NA = 0x2A,
} CELLTYPE;
};
class RecordIO
{
public:
RecordIO();
~RecordIO();

qint16 order(){return _order;};
qint16 size(){return _size;};
QDataStream::ByteOrder byteOrder(){return _byteorder;};
qint64 seekToBegin(qint64 beginpos);
qint64 goNext();
qint64 SkipRecord();
bool ReadRawRecord(QByteArray &data);
bool LoadCompdDoc(QString xlsfilename);
private:
QTemporaryFile _tmpDataFile;
qint16 _order;
qint16 _size;
QDataStream::ByteOrder _byteorder;
};

struct Bof
{
qint16

vers;
qint16 dt;
qint16 rupBuild;
qint16 rupYear;
qint32 bfh;
qint32 sfo;
bool ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
};

class biff8String
{
public:
biff8String();
void reset();
QString ParseString(QDataStream& dqs,bool len2bytes=true);
QString innerstr;
bool isFinished;
private:
qint16 cch; //o0s2 Count of characters in the string
qint8 grbit; //o2s1 Option flag
qint16 crun; //o3s2 if fRichSt=1
qint32 cchExtRst; //o3s4 if fRichSt=0,o5s4 fRichSt=1 Length of ExtRst data
qint16 cch_read;
qint16 restbytes;
//QString innerstr;
QVector rgSTRUN;
bool fHighByte;
bool fExtSt;
bool fRichSt;
};
static double ieee754todec(quint64& in)
{
union
{
quint64 _intval;
double _double;
}intdouble;
intdouble._intval=in;
return intdouble._double;
}
}

#endif // RECORDS_H

Workglobal.cpp
#include "Workglobal.h"
#include

namespace global
{
bool Font::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> dyHeight
>> grbit
>> icv
>> bls
>> sss
>> uls
>> bFamily
>> bCharSet
>> Reserved;
biff8String curStr;
fontName = curStr.ParseString(dqs,false);
return true;
}

bool Sst::ParseRecord(QByteArray& rawbytes,QStringList& list,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> cstTotal >> cstUnique;
sharedRead(dqs,list);
return true;
}

bool Sst::sharedRead(QDataStream &dqs,QStringList& list)
{
QString rStr;
while(!dqs.atEnd())
{
rStr=curStr.ParseString(dqs);
if(rStr.count()) list.append(rStr);
}

return true;
}

bool Sst::AppendContinue(QByteArray& continuebytes,QStringList& list,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(continuebytes);
dqs.setByteOrder(byteorder);
QString rStr=curStr.ParseString(dqs);
if(rStr.count()) list.append(rStr);

this->sharedRead(dqs,list);
return true;
}

bool Boundsheet::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> lbPlyPos >> grbit;
biff8String curStr;

name=curStr.ParseString(dqs,false);
return true;
}

bool Format::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> ifmt;
biff8String curStr;
formating=curStr.ParseStri

ng(dqs);
return true;
}


bool Xf::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> ifnt
>> ifmt
>> fLocked
>> alc
>> cIndent
>> dgLeft
>> icvLeft
>> icvTop
>> icvFore;
return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Workglobal::Workglobal():_boundsheets(0)
{
_formats.insert(0x00,"General");
_formats.insert(0x01,"0");
_formats.insert(0x02,"0.00");
_formats.insert(0x03,"#,##0");
_formats.insert(0x04,"#,##0.00");
_formats.insert(0x05,"($#,##0_);($#,##0)");
_formats.insert(0x06,"($#,##0_);[Red]($#,##0)");
_formats.insert(0x07,"($#,##0.00_);($#,##0.00)");
_formats.insert(0x08,"($#,##0.00_);[Red]($#,##0.00)");
_formats.insert(0x09,"0%");
_formats.insert(0x0a,"0.00%");
_formats.insert(0x0b,"0.00E+00");
_formats.insert(0x0c,"# ?/?");
_formats.insert(0x0d,"# ??/??");
_formats.insert(0x0e,"m/d/yy");
_formats.insert(0x0f,"d-mmmm-yy");
_formats.insert(0x10,"d-mmmm");
_formats.insert(0x11,"mmmm-yy");
_formats.insert(0x12,"h:mm AM/PM");
_formats.insert(0x13,"h:mm:ss:AM/PM");
_formats.insert(0x14,"h:mm");
_formats.insert(0x15,"h:mm:ss");
_formats.insert(0x16,"m/d/yy h:mm");
_formats.insert(0x25,"(#,##0_);(#,##0)");
_formats.insert(0x26,"(#,##0_);[Red](#,##0)");
_formats.insert(0x27,"(#,##0.00_);(#,##0.00)");
_formats.insert(0x28,"(#,##0.00_);[Red](#,##0.00)");
_formats.insert(0x29,"_(*#,##0_);_(*(#,##0);_(*\"-\"_);_(@_)");
_formats.insert(0x2a,"_($*#,##0_);_($*(#,##0);_($*\"-\"_);_(@_)");
_formats.insert(0x2b,"_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)");
_formats.insert(0x2c,"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)");
_formats.insert(0x2d,"mm:ss");
_formats.insert(0x2e,"[h]:mm:ss");
_formats.insert(0x2f,"mm:ss.0");
_formats.insert(0x30,"##0.0E+0");
_formats.insert(0x31,"@");
}

qint64 Workglobal::readGlobal(RecordIO& recIO)
{
QFile _f("C:/doc/global.txt");
_f.open(QIODevice::WriteOnly);
QTextStream tqs(&_f);

QByteArray recdata;

Sst sst;

qint16 leadingorder=ORDER::RO_UAV;

recIO.goNext();
while(recIO.order()!=ORDER::RO_EOF)
{
switch(recIO.order())
{
case ORDER::RO_BOF:
{
recIO.ReadRawRecord(recdata);
Bof bof;
bof.ParseRecord(recdata,recIO.byteOrder());
tqs << "BOF Record:";
//tqs << "bof type is: " << bof.dt << "\n";
if(bof.dt==STREAMTYPE::GLOBALS_SUBSTREAM)
tqs << "This is work global sub-stream\n";
} break;
case ORDER::RO_SST:
{
tqs << "begin to read SST Record:

\n";
recIO.ReadRawRecord(recdata);
sst.ParseRecord(recdata,_listString,recIO.byteOrder());
tqs << "Total string in this file:" << sst.cstTotal <<"\n";
tqs << "Unique string in this file:" << sst.cstUnique <<"\n";
tqs << "read SST finished\n";
} break;
case ORDER::RO_BOUNDSHEET:
{
tqs << "begin to read BOUNDSHEET Record:\n";
Boundsheet boundsheet;
recIO.ReadRawRecord(recdata);
boundsheet.ParseRecord(recdata,recIO.byteOrder());
_boundsheets.append(boundsheet);
tqs << https://www.360docs.net/doc/b67100791.html,<<":"<}break;
case ORDER::RO_XF:
{
tqs << "begin to read XF Record:\n";
Xf xf;
recIO.ReadRawRecord(recdata);
xf.ParseRecord(recdata,recIO.byteOrder());
_xf.append(xf);
tqs << _xf.count()-1<<" format:"<}break;
case ORDER::RO_FONT:
{
tqs << "begin to read FONT Record:\n";
Font font;
recIO.ReadRawRecord(recdata);
font.ParseRecord(recdata,recIO.byteOrder());
_fonts.append(font);
tqs << _fonts.count()-1<<" name:"<}break;
case ORDER::RO_FORMAT:
{
tqs << "begin to read FORMAT Record:\n";
Format format;
recIO.ReadRawRecord(recdata);
format.ParseRecord(recdata,recIO.byteOrder());
_formats.insert(format.ifmt,format.formating);
tqs << format.ifmt<<" formating:"<}break;
default:
{
tqs << "UnParsed Record:";
tqs << recIO.order() << ","<< recIO.size() << "\n";
recIO.SkipRecord();
} break;
}
leadingorder=recIO.order();
recIO.goNext();

while(recIO.order()==ORDER::RO_CONTINUE)
{
tqs << "Continued Record:";
tqs << recIO.order() << ","<< recIO.size() << ",";
switch(leadingorder)
{
case ORDER::RO_SST:
{
tqs <<"sst append\n";
recIO.ReadRawRecord(recdata);
sst.AppendContinue(recdata,_listString,recIO.byteOrder());
}break;
default:
{
recIO.SkipRecord();
tqs << "skipped\n";
}break;
}
recIO.goNext();
}

}
tqs <<"The End,welcome back!\n";
for(int i=0;i<_listString.count();i++)
tqs << _listString[i]<<"\n";
return 0;
}

QString& Workglobal::getString(size_t index)
{
return _listString[index];
}
}//end name space

Workglobal.h
#ifndef WORKGLOBAL_H
#define WORKGLOBAL_H
#include


#include "Records.h"
using namespace Records;

namespace global
{
struct Font
{
qint16 dyHeight; //o4s2 height of the font(1/20 of a point)
qint16 grbit; //o6s2 font attributes
qint16 icv; //o8s2 index to color palette
qint16 bls; //o10s2 Bold style
qint16 sss; //o12s2 00=None,01=Superscript,02=subscript
qint8 uls; //o14s1 Underline style 00=None 01=Single 02=Double 21=Single Accounting 22=Double Accounting
qint8 bFamily; //o15s1 font family
qint8 bCharSet; //o16s1 Character Set
qint8 Reserved; //o17s1 must be 0
//qint8 cch; //o18s1 Length of the font name
QString fontName; //o19sv
bool ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
};

struct Sst
{
bool ParseRecord(QByteArray& rawbytes,QStringList& list,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
bool AppendContinue(QByteArray& continuebytes,QStringList& list,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
qint32 cstTotal; //o4s4 Total number of strings in sst and extsst
qint32 cstUnique; //o8s4 Number of unique strings in sst
private:
bool sharedRead(QDataStream &odqs,QStringList& list);
biff8String curStr;
};

struct Boundsheet
{
bool ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
qint32 lbPlyPos;
qint16 grbit;

QString name;
};

struct Format
{
bool ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
qint16 ifmt;
QString formating;
};

struct Xf
{
public:
bool ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder=QDataStream::LittleEndian);
qint16 ifnt; //4
qint16 ifmt; //6
qint16 fLocked; //8
qint16 alc; //10
qint16 cIndent; //12
qint16 dgLeft;//14
qint16 icvLeft; //16
qint32 icvTop; //18
qint16 icvFore;//22
};
////////////////////////////////////////////////////////////////////////////////////////
class Workglobal
{
public:
Workglobal();
QString& getString(size_t index);
size_t appendString(QString str){_listString.append(str);return _listString.count()-1;}
size_t getStringCount(){return _listString.count();}
//private:
qint64 readGlobal(RecordIO& recIO);
size_t getSheetCount(){return _boundsheets.size();}
//bool getSheet(qint16& index,qint32&pos,QString& name);
QVector _boundsheets;
private:
QVector _fonts;
QVector _xf;
QMap _formats;
QStringList _listString;
};
}// end name space


#endif // WORKGLOBAL_H

Worksheet.cpp
#include "Wo

rksheet.h"
#include
namespace sheet
{
bool DIMENSIONS::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>rwMic >> rwMac >> colMic >> colMac >>reserv;
return true;
}
bool LABELSST::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>rw >> col >> ixfe >> isst;
return true;
}

bool RK::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>rw >> col >> ixfe >> rk;
num=NumFromRk(rk);
return true;
}
bool MULRK::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>rw >> colFirst;
qint16 t;
dqs>>t;
while(!dqs.atEnd())
{
RKREC rkrec;
dqs>>rkrec.rk;
rkrec.ixfe=t;
rkrec.num=NumFromRk(rkrec.rk);
rgrkrec.append(rkrec);
dqs>>t;
}
colLast=t;
return true;
}

bool BLANK::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>rw >> col >> ixfe;
return true;
}

bool FORMULA::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
quint64 tnum;
dqs >>rw >> col >> ixfe>>tnum >> grbit >> chn >> cce;

// Parsed expression not implemented
//qint64 Num=qRound64(num);
quint16 twohighbytes=(tnum>>48);

bool isdouble =twohighbytes==0xFFFF;
if(isdouble)
{
result_type=tnum&0xff;
switch (result_type)
{
case 0:
{
//it's a string,see result in following STRING record
}break;
case 1:
{
booleanvalue=(tnum>>16)&0xff;
}break;
case 2:
{
errorvalue=(tnum>>16)&0xff;
}break;
}
}
else
{
result_type=3;
num=ieee754todec(tnum);
}
return true;
}
bool NUMBER::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
quint64 tnum;
dqs >>rw >> col >> ixfe>>tnum;
num=ieee754todec(tnum);
return true;
}
bool MULBLANK::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byte

order);
dqs >>rw >> colFirst;
qint16 t;
while(!dqs.atEnd())
{
dqs >>t;
rgixfe.append(t);
}
colLast=https://www.360docs.net/doc/b67100791.html,st();
rgixfe.pop_back();
return true;
}
bool MERGECELLS::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >>cmcs;
REF ref;
while(!dqs.atEnd())
{
dqs >>ref.rwFirst>>ref.rwLast>>ref.colFirst>>ref.colLast;
rgRef.append(ref);
}
return true;
}
bool ROW::ParseRecord(QByteArray& rawbytes,QDataStream::ByteOrder byteorder)
{
QDataStream dqs(rawbytes);
dqs.setByteOrder(byteorder);
dqs >> rw
>> colMic
>> colMac
>> miyRw
>> irwMac
>> reserv
>> grbit
>> ixfe;
return true;
}
////////////////////////////////////////////////////////////////////////////
Worksheet::Worksheet(){}

bool Worksheet::readSheet(RecordIO& recIO)
{
QFile _f("C:/doc/sheet.txt");
_f.open(QIODevice::WriteOnly);
QTextStream tqs(&_f);
QByteArray recdata;

quint16 cur_row=0,cur_col=0;
bool hasNext=false;
recIO.goNext();
while(recIO.order()!=ORDER::RO_EOF)
{
switch(recIO.order())
{
case ORDER::RO_BOF:
{
recIO.ReadRawRecord(recdata);
Bof bof;
bof.ParseRecord(recdata,recIO.byteOrder());
tqs << "BOF Record:";
if(bof.dt==STREAMTYPE::WORKSHEET_SUBSTREAM)
tqs << "This is work sheet sub-stream\n";
} break;
case ORDER::RO_DIMENSIONS:
{
recIO.ReadRawRecord(recdata);
DIMENSIONS dim;
dim.ParseRecord(recdata,recIO.byteOrder());
_firstRow=dim.rwMic;_lastRow=dim.rwMac;
_firstCol=dim.colMic;_lastCol=dim.colMac;
_cells.resize(this->totalRows());
for(int i=0;i<_cells.count();i++) _cells[i].resize(this->totalCols());
tqs << "Dimensions:row"<<_firstRow<<"-"<<_lastRow<<",col"<<_firstCol<<"-"<<_lastCol<<"\n";
} break;
case ORDER::RO_LABELSST:
{
recIO.ReadRawRecord(recdata);
LABELSST text;
text.ParseRecord(recdata,recIO.byteOrder());
cur_row=text.rw-_firstRow;
cur_col=text.col-_firstCol;
_cells[cur_row][cur_col].type=CELLTYPE::TEXT;
_cells[cur_row][cur_col].ixfe=text.ixfe;
_cells[cur_row][cur_col].data=text.isst;
tqs << "text cell,row:"<<< ",col:" <<<"content:"<<_global->getString(text.isst)

<<",text index:"<} break;

case ORDER::RO_RK:
{
recIO.ReadRawRecord(recdata);
RK rk;
rk.ParseRecord(recdata,recIO.byteOrder());
cur_row=rk.rw-_firstRow;
cur_col=rk.col-_firstCol;
_cells[cur_row][cur_col].type=CELLTYPE::FLOAT;
_cells[cur_row][cur_col].ixfe=rk.ixfe;
_cells[cur_row][cur_col].data=rk.num;

tqs << "rk cell,row:"<<< ",col:" <<<"content:"<} break;
case ORDER::RO_BLANK:
{
recIO.ReadRawRecord(recdata);
BLANK blank;
blank.ParseRecord(recdata,recIO.byteOrder());
cur_row=blank.rw-_firstRow;
cur_col=blank.col-_firstCol;
_cells[cur_row][cur_col].type=CELLTYPE::BLANK;
_cells[cur_row][cur_col].ixfe=blank.ixfe;
_cells[cur_row][cur_col].data="";

tqs << "blank cell,row:"<<< ",col:" <} break;
case ORDER::RO_FORMULA:
{
recIO.ReadRawRecord(recdata);
FORMULA formula;
formula.ParseRecord(recdata,recIO.byteOrder());
cur_row=formula.rw-_firstRow;
cur_col=formula.col-_firstCol;
_cells[cur_row][cur_col].ixfe=formula.ixfe;
switch(formula.result_type)
{
case 0://string
{
recIO.goNext();
hasNext=true;

tqs << "formula cell,row:"<<< ",col:" <continue;
}break;
case 1:
{
_cells[cur_row][cur_col].type=CELLTYPE::BOOL;
_cells[cur_row][cur_col].data=formula.booleanvalue;
}break;
case 2:
{
_cells[cur_row][cur_col].type=CELLTYPE::ERROR;
_cells[cur_row][cur_col].data=formula.errorvalue;
}break;
case 3:
{
_cells[cur_row][cur_col].type=CELLTYPE::FLOAT;
_cells[cur_row][cur_col].data=formula.num;
}break;
}
tqs << "formula cell,row:"<<< ",col:" <} break;

case ORDER::RO_STRING:
{
recIO.ReadRawRecord(recdata);
QDataStream dqs(recdata);

dqs.setByteOrder(recIO.byteOrder());

biff8String curStr;
QString str=curStr.ParseString(dqs);
qint32 index=_global->appendString(str);
if(hasNext)
{
_cells[cur_row][cur_col].data=index;
_cells[cur_row][cur_col].type=CELLTYPE::TEXT;

tqs << "result string of formula,row:"<<< ",col:" <getString(index)<<" count:"<<_global->getStringCount()<<"\n";
}
else
{
//Error
}
hasNext=false;
} break;
case ORDER::RO_NUMBER:
{
recIO.ReadRawRecord(recdata);
NUMBER number;
number.ParseRecord(recdata,recIO.byteOrder());
cur_row=number.rw-_firstRow;
cur_col=number.col-_firstCol;
_cells[cur_row][cur_col].type=CELLTYPE::FLOAT;
_cells[cur_row][cur_col].ixfe=number.ixfe;
_cells[cur_row][cur_col].data=number.num;

tqs << "number cell,row:"<<< ",col:" <} break;
case ORDER::RO_MULBLANK:
{
recIO.ReadRawRecord(recdata);
MULBLANK mulblank;
mulblank.ParseRecord(recdata,recIO.byteOrder());
cur_row=mulblank.rw-_firstRow;
for(int i=mulblank.colFirst;i<=mulblank.colLast;i++)
{
cur_col=i-_firstCol;
_cells[cur_row][cur_col].type=CELLTYPE::BLANK;
_cells[cur_row][cur_col].ixfe=mulblank.rgixfe[i-mulblank.colFirst];
_cells[cur_row][cur_col].data="";
}
tqs << "mulblank cell,row:"<<< ";col,from:" <} break;
case ORDER::RO_MERGECELLS:
{
recIO.ReadRawRecord(recdata);
_mergecells.ParseRecord(recdata,recIO.byteOrder());
//_cells[blank.rw-_firstRow][blank.col-_firstCol].celltype=CELLDATATYPE::BLANK_CELL;

tqs << "mergecells count:"<<_mergecells.cmcs<<" :";
for(int i=0;i<_mergecells.cmcs;i++)
{
tqs<<_mergecells.rgRef[i].rwFirst<<"-"<<_mergecells.rgRef[i].rwLast<<","<<_mergecells.rgRef[i].colFirst<<"-"<<_mergecells.rgRef[i].colLast<<";";
}
tqs<<"\n";
} break;
case ORDER::RO_MULRK:
{
recIO.ReadRawRecord(recdata);
MULRK mulrk;
mulrk.ParseRecord(recdata,recIO.byteOrder());
cur_row=mulrk.rw-_firstRow;
tqs<

相关主题