TableMng.cpp redeclared a partial, mismatched YExcel API (CompoundDocument
instead of YCompoundFiles::CompoundFile, SetIntegerAlt/SetWStringAlt instead
of BasicExcelCell::Set(int)/Set(const wchar_t*), non-const getters, int
GetTotalRows/GetTotalCols, New(size_t)), so nothing could define it. The
YExcel span was already skipped as runtime_library code.
- ThirdParty/BasicExcel: Yap Chun Wei's public-domain BasicExcel 1.14.
Matches the binary: sizeof(CompoundFile)=0x330, workbook_ at 0x330,
worksheets_ at 0x488, yesheets_ at 0x494, BasicExcelCell 0x28, Workbook()
BOF constants 0x50600/0x7CD19A0/0xC0C9/0x306. Local changes:
- BasicExcel gains unknown_04A0[0x108]: all four operator new calls in
the original allocate 0x5A8, no code reads the tail.
- the default constructor is defined by TableMng.cpp (fn_20498).
- operator<<(wchar_t*) keeps its pre-C++20 overload explicitly.
- TableMng.cpp includes the real header; scores of its 13 functions are
unchanged (td check).
- data/compile.json: shape 4 gets -I ThirdParty/BasicExcel; the library is
shape 11 (shape 8 without the jsoncpp defines/include).
1253 lines
46 KiB
C++
1253 lines
46 KiB
C++
// Created by Yap Chun Wei
|
|
// Version 1.0 (20 April 2006)
|
|
// Version 1.1 (22 April 2006)
|
|
// - Fixed bugs with compound files not being able to write files more than 65535 bytes.
|
|
// - Fixed bugs with reading and writing to Excel files containing many strings.
|
|
// Version 1.2 (30 April 2006)
|
|
// - Added operator<< to pass BasicExcelCell to an output stream.
|
|
// - Added Print() to BasicExcelWorksheet to print the worksheet to an output stream.
|
|
// - Change BasicExcelCell Get functions to const functions.
|
|
// - Rename BasicExcelWorksheet functions RenameWorkSheet() to Rename().
|
|
// Version 1.3 (10 May 2006)
|
|
// - Fixed bugs with reading from Excel files containing Asian characters.
|
|
// Version 1.4 (13 May 2006)
|
|
// - Fixed bugs with reading and writing to Excel files containing many strings.
|
|
// Version 1.5 (15 May 2006)
|
|
// - Remove code for ExtSST because it was causing problems with reading and writing to Excel files containing many strings.
|
|
// Version 1.6 (16 May 2006)
|
|
// - Optimized code for reading and writing.
|
|
// Version 1.7 (22 May 2006)
|
|
// - Fixed code to remove some warnings.
|
|
// - Fixed bug with BasicExcelWorksheet::Cell.
|
|
// - Fixed bug with BasicExcel::UpdateWorksheets().
|
|
// Version 1.8 (23 May 2006)
|
|
// - Fixed bug with reading Excel files containing many unicode strings.
|
|
// - Fixed code to remove some warnings.
|
|
// - Fixed variable code_ duplication in BoolErr.
|
|
// - Minor changes to BasicExcelCell:Set functions.
|
|
// Version 1.9 (24 May 2006)
|
|
// - Changed name_ in Style from SmallString to LargeString.
|
|
// - Fixed bug in BasicExcelCell::GetString and BasicExcelCell::GetWString.
|
|
// - Minor changes to functions in BasicExcel and BasicExcelWorksheet which checks for unicode.
|
|
// - Minor change to SmallString::Read.
|
|
// Version 1.10 (30 May 2006)
|
|
// - Fixed bug with reading Excel files containing many strings.
|
|
// - Remove memory leaks.
|
|
// Version 1.11 (2 June 2006)
|
|
// - Fixed bug with reading and writing Excel files containing many unicode and ANSI strings.
|
|
// Version 1.12 (6 June 2006)
|
|
// - Fixed bug with reading and writing Excel files containing many unicode and ANSI strings.
|
|
// Version 1.13 (1 August 2006)
|
|
// - Changed BasicExcelCell::Get() so that it will get a stored double as an integer or vice versa if necessary.
|
|
// - Changed BasicExcelCell::Get() so that it will not cause any errors if a string is empty.
|
|
// - Changed BasicExcelCell::SetString() and BasicExcelCell::SetWString() so that it will not save an empty string.
|
|
// Version 1.14 (6 August 2006)
|
|
// - Fixed bug with reading Excel files that contain a null string.
|
|
|
|
#ifndef BASICEXCEL_HPP
|
|
#define BASICEXCEL_HPP
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <cstring>
|
|
|
|
#define UTF16
|
|
#ifdef UTF16
|
|
#define SIZEOFWCHAR_T 2
|
|
#else
|
|
#define SIZEOFWCHAR_T sizeof(wchar_t)
|
|
#endif
|
|
|
|
namespace YCompoundFiles
|
|
{
|
|
class Block
|
|
// PURPOSE: In charge of handling blocks of data from a file
|
|
{
|
|
public:
|
|
Block();
|
|
|
|
// File handling functions
|
|
bool Create(const wchar_t* filename);
|
|
bool Open(const wchar_t* filename, std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);
|
|
bool Close();
|
|
bool IsOpen();
|
|
|
|
// Block handling functions
|
|
bool Read(size_t index, char* block);
|
|
bool Write(size_t index, const char* block);
|
|
bool Swap(size_t index1, size_t index2);
|
|
bool Move(size_t from, size_t to);
|
|
bool Insert(size_t index, const char* block);
|
|
bool Erase(size_t index);
|
|
bool Erase(std::vector<size_t>& indices);
|
|
|
|
// Misc functions
|
|
size_t GetBlockSize() const {return blockSize_;}
|
|
void SetBlockSize(size_t size)
|
|
{
|
|
blockSize_ = size;
|
|
indexEnd_ = fileSize_/blockSize_ + (fileSize_ % blockSize_ ? 1 : 0);
|
|
}
|
|
|
|
protected:
|
|
std::vector<char> filename_;
|
|
std::ios_base::openmode mode_;
|
|
std::fstream file_;
|
|
size_t blockSize_;
|
|
size_t indexEnd_;
|
|
size_t fileSize_;
|
|
};
|
|
|
|
struct LittleEndian
|
|
{
|
|
template<typename Type>
|
|
static void Read(const char* buffer, Type& retVal, int pos=0, int bytes=0)
|
|
{
|
|
retVal = Type(0);
|
|
if (bytes == 0) bytes = sizeof(Type);
|
|
for (size_t i=0; i < (size_t)bytes; ++i)
|
|
{
|
|
retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;
|
|
}
|
|
}
|
|
|
|
template<typename Type>
|
|
static void ReadString(const char* buffer, Type* str, int pos=0, int bytes=0)
|
|
{
|
|
for (size_t i = 0; i < (size_t)bytes; ++i) Read(buffer, str[i], pos+i*sizeof(Type));
|
|
}
|
|
|
|
template<typename Type>
|
|
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 < (size_t)bytes; ++i)
|
|
{
|
|
buffer[pos+i] = (unsigned char)val;
|
|
val >>= 8;
|
|
}
|
|
}
|
|
|
|
template<typename Type>
|
|
static void WriteString(char* buffer, Type* str, int pos=0, int bytes=0)
|
|
{
|
|
for (size_t i = 0; i < (size_t)bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type));
|
|
}
|
|
|
|
template<typename Type>
|
|
static void Read(const std::vector<char>& buffer, Type& retVal, int pos=0, int bytes=0)
|
|
{
|
|
retVal = Type(0);
|
|
if (bytes == 0) bytes = sizeof(Type);
|
|
for (size_t i = 0; i < (size_t)bytes; ++i)
|
|
{
|
|
retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;
|
|
}
|
|
}
|
|
|
|
template<typename Type>
|
|
static void ReadString(const std::vector<char>& buffer, Type* str, int pos=0, int bytes=0)
|
|
{
|
|
for (size_t i = 0; i < (size_t)bytes; ++i) Read(buffer, str[i], pos+i*sizeof(Type));
|
|
}
|
|
|
|
template<typename Type>
|
|
static void Write(std::vector<char>& buffer, Type val, int pos=0, int bytes=0)
|
|
{
|
|
if (bytes == 0) bytes = sizeof(Type);
|
|
for (size_t i = 0; i < (size_t)bytes; ++i)
|
|
{
|
|
buffer[pos+i] = (unsigned char)val;
|
|
val >>= 8;
|
|
}
|
|
}
|
|
|
|
template<typename Type>
|
|
static void WriteString(std::vector<char>& buffer, Type* str, int pos=0, int bytes=0)
|
|
{
|
|
for (size_t i = 0; i < (size_t)bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type));
|
|
}
|
|
|
|
|
|
static void Read(const char* buffer, wchar_t& retVal, int pos=0, int bytes=0)
|
|
{
|
|
retVal = wchar_t(0);
|
|
if (bytes == 0) bytes = SIZEOFWCHAR_T;
|
|
for (int i=0; i<bytes; ++i)
|
|
{
|
|
retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
|
|
}
|
|
}
|
|
|
|
static void ReadString(const char* buffer, wchar_t* str, int pos=0, int bytes=0)
|
|
{
|
|
for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
|
|
}
|
|
|
|
static void Write(char* buffer, wchar_t val, int pos=0, int bytes=0)
|
|
{
|
|
if (bytes == 0) bytes = SIZEOFWCHAR_T;
|
|
for (int i=0; i<bytes; ++i)
|
|
{
|
|
buffer[pos+i] = (unsigned char)val;
|
|
val >>= 8;
|
|
}
|
|
}
|
|
|
|
static void WriteString(char* buffer, wchar_t* str, int pos=0, int bytes=0)
|
|
{
|
|
for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
|
|
}
|
|
|
|
static void Read(const std::vector<char>& buffer, wchar_t& retVal, int pos=0, int bytes=0)
|
|
{
|
|
retVal = wchar_t(0);
|
|
if (bytes == 0) bytes = SIZEOFWCHAR_T;
|
|
for (int i=0; i<bytes; ++i)
|
|
{
|
|
retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
|
|
}
|
|
}
|
|
|
|
static void ReadString(const std::vector<char>& buffer, wchar_t* str, int pos=0, int bytes=0)
|
|
{
|
|
for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
|
|
}
|
|
|
|
static void Write(std::vector<char>& buffer, wchar_t val, int pos=0, int bytes=0)
|
|
{
|
|
if (bytes == 0) bytes = SIZEOFWCHAR_T;
|
|
for (int i=0; i<bytes; ++i)
|
|
{
|
|
buffer[pos+i] = (unsigned char)val;
|
|
val >>= 8;
|
|
}
|
|
}
|
|
|
|
static void WriteString(std::vector<char>& buffer, wchar_t* str, int pos=0, int bytes=0)
|
|
{
|
|
for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
|
|
}
|
|
};
|
|
|
|
class CompoundFile
|
|
{
|
|
public:
|
|
enum {DUPLICATE_PROPERTY=-6,
|
|
NAME_TOO_LONG=-5, FILE_NOT_FOUND=-4,
|
|
DIRECTORY_NOT_EMPTY=-3, DIRECTORY_NOT_FOUND=-2,
|
|
INVALID_PATH=-1,
|
|
SUCCESS=1};
|
|
|
|
CompoundFile();
|
|
~CompoundFile();
|
|
|
|
// User accessible functions
|
|
public:
|
|
// Compound File functions
|
|
bool Create(const wchar_t* filename);
|
|
bool Open(const wchar_t* filename, std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);
|
|
bool Close();
|
|
bool IsOpen();
|
|
|
|
// Directory functions
|
|
int ChangeDirectory(const wchar_t* path);
|
|
int MakeDirectory(const wchar_t* path);
|
|
int PresentWorkingDirectory(wchar_t* path);
|
|
int PresentWorkingDirectory(std::vector<wchar_t>& path);
|
|
int RemoveDirectory(const wchar_t* path);
|
|
int DelTree(const wchar_t* path);
|
|
int DirectoryList(std::vector<std::vector<wchar_t> >& list, const wchar_t* path=0);
|
|
|
|
// File functions
|
|
int MakeFile(const wchar_t* path);
|
|
int RemoveFile(const wchar_t* path);
|
|
int FileSize(const wchar_t* path, size_t& size);
|
|
int ReadFile(const wchar_t* path, char* data);
|
|
int ReadFile(const wchar_t* path, std::vector<char>&data);
|
|
int WriteFile(const wchar_t* path, const char* data, size_t size);
|
|
int WriteFile(const wchar_t* path, const std::vector<char>&data, size_t size);
|
|
|
|
|
|
// ANSI char functions
|
|
bool Create(const char* filename);
|
|
bool Open(const char* filename, std::ios_base::openmode mode=std::ios_base::in | std::ios_base::out);
|
|
int ChangeDirectory(const char* path);
|
|
int MakeDirectory(const char* path);
|
|
int PresentWorkingDirectory(char* path);
|
|
int PresentWorkingDirectory(std::vector<char>& path);
|
|
int RemoveDirectory(const char* path);
|
|
int DelTree(const char* path);
|
|
int MakeFile(const char* path);
|
|
int RemoveFile(const char* path);
|
|
int FileSize(const char* path, size_t& size);
|
|
int ReadFile(const char* path, char* data);
|
|
int ReadFile(const char* path, std::vector<char>& data);
|
|
int WriteFile(const char* path, char* data, size_t size);
|
|
int WriteFile(const char* path, std::vector<char>& data, size_t size);
|
|
|
|
// Protected functions and data members
|
|
protected:
|
|
// General functions and data members
|
|
void IncreaseLocationReferences(std::vector<size_t> indices);
|
|
void DecreaseLocationReferences(std::vector<size_t> indices);
|
|
void SplitPath(const wchar_t* path, wchar_t*& parentpath, wchar_t*& propertyname);
|
|
std::vector<char> block_;
|
|
Block file_;
|
|
|
|
// Header related functions and data members
|
|
bool LoadHeader();
|
|
void SaveHeader();
|
|
class Header
|
|
{
|
|
public:
|
|
Header();
|
|
void Write(char* block);
|
|
void Read(char* block);
|
|
|
|
long long fileType_; // Magic number identifying this as a compound file system (0x0000)
|
|
int uk1_; // Unknown constant (0x0008)
|
|
int uk2_; // Unknown constant (0x000C)
|
|
int uk3_; // Unknown constant (0x0010)
|
|
int uk4_; // Unknown constant (0x0014)
|
|
short uk5_; // Unknown constant (revision?) (0x0018)
|
|
short uk6_; // Unknown constant (version?) (0x001A)
|
|
short uk7_; // Unknown constant (0x001C)
|
|
short log2BigBlockSize_; // Log, base 2, of the big block size (0x001E)
|
|
int log2SmallBlockSize_; // Log, base 2, of the small block size (0x0020)
|
|
int uk8_; // Unknown constant (0x0024)
|
|
int uk9_; // Unknown constant (0x0028)
|
|
int BATCount_; // Number of elements in the BAT array (0x002C)
|
|
int propertiesStart_; // Block index of the first block of the property table (0x0030)
|
|
int uk10_; // Unknown constant (0x0034)
|
|
int uk11_; // Unknown constant (0x0038)
|
|
int SBATStart_; // Block index of first big block containing the small block allocation table (SBAT) (0x003C)
|
|
int SBATCount_; // Number of big blocks holding the SBAT (0x0040)
|
|
int XBATStart_; // Block index of the first block in the Extended Block Allocation Table (XBAT) (0x0044)
|
|
int XBATCount_; // Number of elements in the Extended Block Allocation Table (to be added to the BAT) (0x0048)
|
|
int BATArray_[109]; // Array of block indices constituting the Block Allocation Table (BAT) (0x004C, 0x0050, 0x0054 ... 0x01FC)
|
|
|
|
size_t bigBlockSize_;
|
|
size_t smallBlockSize_;
|
|
|
|
private:
|
|
void Initialize();
|
|
};
|
|
Header header_;
|
|
|
|
// BAT related functions and data members
|
|
void LoadBAT();
|
|
void SaveBAT();
|
|
size_t DataSize(size_t startIndex, bool isBig);
|
|
size_t ReadData(size_t startIndex, char* data, bool isBig);
|
|
size_t WriteData(const char* data, size_t size, int startIndex, bool isBig);
|
|
void GetBlockIndices(size_t startIndex, std::vector<size_t>& indices, bool isBig);
|
|
size_t GetFreeBlockIndex(bool isBig);
|
|
void ExpandBATArray(bool isBig);
|
|
void LinkBlocks(size_t from, size_t to, bool isBig);
|
|
void FreeBlocks(std::vector<size_t>& indices, bool isBig);
|
|
std::vector<int> blocksIndices_;
|
|
std::vector<int> sblocksIndices_;
|
|
|
|
// Properties related functions and data members
|
|
class Property
|
|
{
|
|
public:
|
|
Property();
|
|
void Write(char* block);
|
|
void Read(char* block);
|
|
friend bool operator==(const CompoundFile::Property& lhs, const CompoundFile::Property& rhs)
|
|
{
|
|
return (!wcscmp(lhs.name_, rhs.name_));
|
|
}
|
|
friend bool operator< (const CompoundFile::Property& lhs, const CompoundFile::Property& rhs)
|
|
{
|
|
size_t maxLen1 = wcslen(lhs.name_);
|
|
size_t maxLen2 = wcslen(rhs.name_);
|
|
if (maxLen1 < maxLen2) return true;
|
|
else if (maxLen1 > maxLen2) return false;
|
|
else
|
|
{
|
|
int result = wcscmp(lhs.name_, rhs.name_);
|
|
if (result <= 0) return true;
|
|
else return false;
|
|
}
|
|
}
|
|
friend bool operator!=(const CompoundFile::Property& lhs, const CompoundFile::Property& rhs) {return !(lhs == rhs);}
|
|
friend bool operator> (const CompoundFile::Property& lhs, const CompoundFile::Property& rhs) {return (rhs < lhs);}
|
|
friend bool operator<=(const CompoundFile::Property& lhs, const CompoundFile::Property& rhs) {return !(rhs < lhs);}
|
|
friend bool operator>=(const CompoundFile::Property& lhs, const CompoundFile::Property& rhs) {return !(lhs < rhs);}
|
|
|
|
wchar_t name_[32]; // A unicode null-terminated uncompressed 16bit string (lblocke the high bytes) containing the name of the property. (0x00, 0x02, 0x04, ... 0x3E)
|
|
short nameSize_; // Number of characters in the NAME field (0x40)
|
|
unsigned char propertyType_; // Property type (directory, file, or root) Byte 1 (directory), 2 (file), or 5 (root entry) (0x42)
|
|
unsigned char nodeColor_; // Node color (0x43)
|
|
int previousProp_; // Previous property index (0x44)
|
|
int nextProp_; // Next property index (0x48)
|
|
int childProp_; // First child property index (0x4c)
|
|
int uk1_;
|
|
int uk2_;
|
|
int uk3_;
|
|
int uk4_;
|
|
int uk5_;
|
|
int seconds1_; // Seconds component of the created timestamp? (0x64)
|
|
int days1_; // Days component of the created timestamp? (0x68)
|
|
int seconds2_; // Seconds component of the modified timestamp? (0x6C)
|
|
int days2_; // Days component of the modified timestamp? (0x70)
|
|
int startBlock_; // Starting block of the file, used as the first block in the file and the pointer to the next block from the BAT (0x74)
|
|
int size_; // Actual size of the file this property points to. (used to truncate the blocks to the real size). (0x78)
|
|
};
|
|
class PropertyTree
|
|
{
|
|
public:
|
|
PropertyTree();
|
|
~PropertyTree();
|
|
PropertyTree* parent_;
|
|
Property* self_;
|
|
size_t index_;
|
|
std::vector<PropertyTree*> children_;
|
|
};
|
|
void LoadProperties();
|
|
void SaveProperties();
|
|
int MakeProperty(const wchar_t* path, Property* property);
|
|
PropertyTree* FindProperty(size_t index);
|
|
PropertyTree* FindProperty(const wchar_t* path);
|
|
PropertyTree* FindProperty(PropertyTree* parentTree, wchar_t* name);
|
|
void InsertPropertyTree(PropertyTree* parentTree, Property* property, size_t index);
|
|
void DeletePropertyTree(PropertyTree* tree);
|
|
void UpdateChildrenIndices(PropertyTree* parentTree);
|
|
void IncreasePropertyReferences(PropertyTree* parentTree, size_t index);
|
|
void DecreasePropertyReferences(PropertyTree* parentTree, size_t index);
|
|
PropertyTree* propertyTrees_;
|
|
PropertyTree* currentDirectory_;
|
|
std::vector<Property*> properties_;
|
|
std::vector<PropertyTree*> previousDirectories_;
|
|
};
|
|
} // YCompoundFiles namespace end
|
|
|
|
namespace YExcel
|
|
{
|
|
using namespace YCompoundFiles;
|
|
|
|
struct CODE
|
|
{
|
|
enum { FORMULA=0x0006, //Token array and the result of a formula cell.
|
|
YEOF=0x000A, //End of a record block with leading BOF record.
|
|
CALCCOUNT=0x000C, //Maximum number of times the forumlas should be iteratively calculated
|
|
CALCMODE=0x000D, //Calculate formulas manually, automatically, or automatically except for multiple table operations
|
|
PRECISION=0x000E, //Whether formulas use the real cell values for calculation or the values displayed on the screen.
|
|
REFMODE=0x000F, //Method used to show cell addresses in formulas.
|
|
DELTA=0x0010, //Maximum change of the result to exit an iteration.
|
|
ITERATION=0x0011, //Whether iterations are allowed while calculating recursive formulas.
|
|
PROTECT=0x0012, //Whether worksheet or a workbook is protected against modification.
|
|
PASSWORD=0x0013, //16-bit hash value, calculated from the worksheet or workbook protection password.
|
|
HEADER=0x0014, //Page header string for the current worksheet.
|
|
FOOTER=0x0015, //Page footer string for the current worksheet.
|
|
EXTERNSHEET=0x0017, //List with indexes to SUPBOOK records
|
|
NAME=0x0018, //Name and token array of an internal defined name.
|
|
WINDOWPROTECT=0x0019, //Whether the window configuration of the document is protected.
|
|
SELECTION=0x001D, //Addresses of all selected cell ranges and position of the active cell for a pane in the current sheet.
|
|
DATEMODE=0x0022, //Base date for displaying date values.
|
|
EXTERNNAME=0x0023, //Name of an external defined name, name of an add-in function, a DDE item or an OLE object storage identifier.
|
|
LEFTMARGIN=0x0026, //Left page margin of the current worksheet.
|
|
RIGHTMARGIN=0x0027, //Right page margin of the current worksheet.
|
|
TOPMARGIN=0x0028, //Top page margin of the current worksheet.
|
|
BOTTOMMARGIN=0x0029, //Bottom page margin of current worksheet
|
|
PRINTHEADERS=0x002A, //Whether row and column headers (the areas with row numbers and column letters) will be printed.
|
|
PRINTGRIDLINES=0x002B, //Whether sheet grid lines will be printed.
|
|
FILEPASS=0x002F, //Information about the read/write password of the file.
|
|
FONT=0x0031, //Information about a used font, including character formatting.
|
|
TABLE=0x0036, //Information about a multiple operation table in the sheet.
|
|
CONTINUE=0x003C, //Continue from previous record
|
|
WINDOW1=0x003D, //General settings for the workbook global settings.
|
|
BACKUP=0x0040, //Make backup of file while saving?
|
|
PANE=0x0041, //Position of window panes.
|
|
CODEPAGE=0x0042, //Text encoding used to encode byte strings
|
|
DCONREF=0x0051,
|
|
DEFCOLWIDTH=0x0055, //Default column width for columns that do not have a specific width set
|
|
XCT=0x0059, //Number of immediately following CRN records.
|
|
CRN=0x005A, //Contents of an external cell or cell range.
|
|
FILESHARING=0x005B, //Information about write protection, for instance the write protection password.
|
|
WRITEACCESS=0x005C, //Name of the user that has saved the file.
|
|
UNCALCED=0x005E, //Formulas have not been recalculated before the document was saved.
|
|
SAVERECALC=0x005F, //"Recalculate before save" option
|
|
OBJECTPROTECT=0x0063, //Whether objects of the current sheet are protected.
|
|
COLINFO=0x007D, //Width for a given range of columns
|
|
GUTS=0x0080, //Layout of outline symbols.
|
|
WSBOOL=0x0081, //16-bit value with boolean options for the current sheet.
|
|
GRIDSET=0x0082, //Whether option to print sheet grid lines has ever been changed.
|
|
HCENTER=0x0083, //Sheet is centred horizontally when printed.
|
|
VCENTER=0x0084, //Whether sheet is centred vertically when printed.
|
|
BOUNDSHEET=0x0085, //Sheet inside of the workbook
|
|
WRITEPROT=0x0086, //Whether file is write protected.
|
|
COUNTRY=0x008C, //User interface language of the Excel version that has saved the file, system regional settings at the time the file was saved.
|
|
HIDEOBJ=0x008D, //Whether and how to show objects in the workbook.
|
|
SORT=0x0090, //Last settings from the "Sort" dialogue for each sheet.
|
|
PALETTE=0x0092, //Definition of all user-defined colours available for cell and object formatting.
|
|
SETUP=0x00A1, //Page format settings of the current sheet.
|
|
SHRFMLA=0x00BC, //Token array of a shared formula.
|
|
MULRK=0x00BD, //Cell range containing RK value cells. All cells are located in the same row.
|
|
MULBLANK=0x00BE, //Cell range of empty cells. All cells are located in the same row.
|
|
DBCELL=0x00D7, //Relative offsets to calculate stream position of the first cell record for each row.
|
|
BOOKBOOL=0x00DA, //Save values linked from external workbooks records and XCT records?
|
|
SCENPROTECT=0x00DD, //Whether scenarios of the current sheet are protected.
|
|
XF=0x00E0, //Formatting information for cells, rows, columns or styles.
|
|
MERGEDCELLS=0x00E5, //All merged cell ranges of the current sheet.
|
|
SST=0x00FC, //List of all strings used anywhere in the workbook.
|
|
LABELSST=0x00FD, //Cell that contains a string.
|
|
EXTSST=0x00FF, //Create a hash table with stream offsets to the SST record to optimise string search operations.
|
|
LABELRANGES=0x015F, //Addresses of all row and column label ranges in the current sheet.
|
|
USESELFS=0x0160, //Whether formulas in the workbook can use "natural language formulas".
|
|
DSF=0x0161, //Whether file contains an addition BIFF5/BIFF7 workbook stream.
|
|
SUPBOOK=0x01AE, //URL of an external document and a list of sheet names inside this document.
|
|
CONDFMT=0x01B0, //List of cell range addresses for all cells with equal conditional formatting.
|
|
CF=0x01B1, //Condition and the formatting attributes applied to the cells specified in the CONDFMT record, if the condition is met
|
|
DVAL=0x01B2, //List header of the data validity table in the current sheet.
|
|
HLINK=0x01B8, //One cell address or a cell range where all cells contain the same hyperlink.
|
|
DV=0x01BE, //Data validity settings and a list of cell ranges which contain these settings.
|
|
DIMENSIONS=0x0200, //Range address of the used area in the current sheet.
|
|
BLANK=0x0201, //Empty cell, contains cell address and formatting information
|
|
NUMBER=0x0203, //Cell that contains a floating-point value.
|
|
BOOLERR=0x0205, //Error value cell
|
|
STRING=0x0207, //Result of a string formula.
|
|
ROW=0x0208, //Properties of a single row in the sheet.
|
|
INDEX=0x020B, //Range of used rows and stream positions of several records of the current sheet.
|
|
ARRAY=0x0221, //Token array of an array formula
|
|
WINDOW2=0x023E, //Additional settings for the window of a specific worksheet.
|
|
RK=0x027E, //Cell that contains an RK value (encoded integer or floating point value).
|
|
STYLE=0x0293, //Name of a user-defined cell style or specific options for a built-in cell style.
|
|
FORMAT=0x041E, //Number format.
|
|
SHRFMLA1=0x04BC, //Token array of a shared formula (added).
|
|
QUICKTIP=0x0800, //Cell range and text for a tool tip.
|
|
BOF=0x0809, //Beginning of file
|
|
SHEETLAYOUT=0x0862, //Colour of the tab below the sheet containing the sheet name.
|
|
SHEETPROTECTION=0x0867, //Additional options for sheet protection.
|
|
RANGEPROTECTION=0x0868 //Information about special protected ranges in a protected sheet.
|
|
};
|
|
};
|
|
|
|
class Record
|
|
{
|
|
public:
|
|
Record();
|
|
virtual ~Record();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short code_;
|
|
std::vector<char> data_;
|
|
size_t dataSize_;
|
|
size_t recordSize_;
|
|
std::vector<size_t> continueIndices_;
|
|
};
|
|
|
|
struct BOF : public Record
|
|
{
|
|
BOF();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short version_;
|
|
short type_;
|
|
short buildIdentifier_;
|
|
short buildYear_;
|
|
int fileHistoryFlags_;
|
|
int lowestExcelVersion_;
|
|
};
|
|
|
|
struct YEOF : public Record
|
|
{
|
|
YEOF();
|
|
};
|
|
|
|
struct SmallString
|
|
{
|
|
SmallString();
|
|
~SmallString();
|
|
SmallString(const SmallString& s);
|
|
SmallString& operator=(const SmallString& s);
|
|
const SmallString& operator=(const char* str);
|
|
const SmallString& operator=(const wchar_t* str);
|
|
void Reset();
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
size_t StringSize();
|
|
wchar_t* wname_;
|
|
char* name_;
|
|
char unicode_;
|
|
};
|
|
|
|
struct LargeString
|
|
{
|
|
LargeString();
|
|
~LargeString();
|
|
LargeString(const LargeString& s);
|
|
LargeString& operator=(const LargeString& s);
|
|
const LargeString& operator=(const char* str);
|
|
const LargeString& operator=(const wchar_t* str);
|
|
void Reset();
|
|
size_t Read(const char* data);
|
|
size_t ContinueRead(const char* data, size_t size);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
size_t StringSize();
|
|
std::vector<wchar_t> wname_;
|
|
std::vector<char> name_;
|
|
char unicode_;
|
|
short richtext_;
|
|
int phonetic_;
|
|
};
|
|
|
|
class Workbook
|
|
{
|
|
public:
|
|
Workbook();
|
|
|
|
public:
|
|
struct FileProtection;
|
|
struct CodePage;
|
|
struct DSF;
|
|
struct TabID;
|
|
struct FnGroupCount;
|
|
struct WorkbookProtection;
|
|
struct Window1 : public Record
|
|
{
|
|
Window1();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short horizontalPos_;
|
|
short verticalPos_;
|
|
short width_;
|
|
short height_;
|
|
short options_;
|
|
short activeWorksheetIndex_;
|
|
short firstVisibleTabIndex_;
|
|
short selectedWorksheetNo_;
|
|
short worksheetTabBarWidth_;
|
|
};
|
|
struct Backup;
|
|
struct HideObj;
|
|
struct DateMode;
|
|
struct Precision;
|
|
struct RefreshAll;
|
|
struct BookBool;
|
|
struct Font : public Record
|
|
{
|
|
Font();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short height_;
|
|
short options_;
|
|
short colourIndex_;
|
|
short weight_;
|
|
short escapementType_;
|
|
char underlineType_;
|
|
char family_;
|
|
char characterSet_;
|
|
char unused_;
|
|
SmallString name_;
|
|
};
|
|
struct Format;
|
|
struct XF : public Record
|
|
{
|
|
XF();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short fontRecordIndex_;
|
|
short formatRecordIndex_;
|
|
short protectionType_;
|
|
char alignment_;
|
|
char rotation_;
|
|
char textProperties_;
|
|
char usedAttributes_;
|
|
int borderLines_;
|
|
int colour1_;
|
|
short colour2_;
|
|
};
|
|
struct Style : public Record
|
|
{
|
|
Style();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short XFRecordIndex_;
|
|
char identifier_;
|
|
char level_;
|
|
LargeString name_;
|
|
};
|
|
struct Palette;
|
|
struct UseSelfs;
|
|
struct BoundSheet : public Record
|
|
{
|
|
BoundSheet();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
int BOFpos_;
|
|
char visibility_;
|
|
char type_;
|
|
SmallString name_;
|
|
};
|
|
struct Country;
|
|
struct LinkTable;
|
|
struct SharedStringTable : public Record
|
|
{
|
|
SharedStringTable();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
int stringsTotal_;
|
|
int uniqueStringsTotal_;
|
|
std::vector<LargeString> strings_;
|
|
};
|
|
struct ExtSST : public Record
|
|
{
|
|
ExtSST();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short stringsTotal_;
|
|
std::vector<int> streamPos_;
|
|
std::vector<short> firstStringPos_;
|
|
std::vector<short> unused_;
|
|
};
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
|
|
BOF bof_;
|
|
Window1 window1_;
|
|
std::vector<Font> fonts_;
|
|
std::vector<XF> XFs_;
|
|
std::vector<Style> styles_;
|
|
std::vector<BoundSheet> boundSheets_;
|
|
SharedStringTable sst_;
|
|
ExtSST extSST_;
|
|
YEOF eof_;
|
|
};
|
|
|
|
class Worksheet
|
|
{
|
|
public:
|
|
Worksheet();
|
|
|
|
public:
|
|
struct Uncalced;
|
|
struct Index : public Record
|
|
{
|
|
Index();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
int unused1_;
|
|
size_t firstUsedRowIndex_;
|
|
size_t firstUnusedRowIndex_;
|
|
int unused2_;
|
|
std::vector<size_t> DBCellPos_;
|
|
|
|
};
|
|
struct CalculationSettings
|
|
{
|
|
struct CalcCount;
|
|
struct CalcMode;
|
|
struct RefMode;
|
|
struct Delta;
|
|
struct Iteration;
|
|
struct SafeRecalc;
|
|
};
|
|
struct PrintHeaders;
|
|
struct PrintGridlines;
|
|
struct Gridset;
|
|
struct Guts;
|
|
struct DefaultRowHeight;
|
|
struct WSBool;
|
|
struct PageSettings
|
|
{
|
|
struct Header;
|
|
struct Footer;
|
|
struct HCenter;
|
|
struct VCenter;
|
|
struct LeftMargin;
|
|
struct RightMargin;
|
|
struct TopMargin;
|
|
struct BottomMargin;
|
|
struct PLS;
|
|
struct Setup;
|
|
};
|
|
struct WorksheetProtection;
|
|
struct DefColWidth;
|
|
struct ColInfo;
|
|
struct Sort;
|
|
struct Dimensions : public Record
|
|
{
|
|
Dimensions();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
size_t firstUsedRowIndex_;
|
|
size_t lastUsedRowIndexPlusOne_;
|
|
short firstUsedColIndex_;
|
|
short lastUsedColIndexPlusOne_;
|
|
short unused_;
|
|
};
|
|
struct CellTable
|
|
{
|
|
struct RowBlock
|
|
{
|
|
struct Row : public Record
|
|
{
|
|
Row();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short firstCellColIndex_;
|
|
short lastCellColIndexPlusOne_;
|
|
short height_;
|
|
short unused1_;
|
|
short unused2_;
|
|
int options_;
|
|
};
|
|
struct CellBlock
|
|
{
|
|
struct Blank : public Record
|
|
{
|
|
Blank();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
};
|
|
struct BoolErr : public Record
|
|
{
|
|
BoolErr();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
char value_;
|
|
char error_;
|
|
};
|
|
struct LabelSST : public Record
|
|
{
|
|
LabelSST();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
size_t SSTRecordIndex_;
|
|
};
|
|
struct MulBlank : public Record
|
|
{
|
|
MulBlank();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short rowIndex_;
|
|
short firstColIndex_;
|
|
std::vector<short> XFRecordIndices_;
|
|
short lastColIndex_;
|
|
};
|
|
struct MulRK : public Record
|
|
{
|
|
MulRK();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
struct XFRK
|
|
{
|
|
XFRK();
|
|
void Read(const char* data);
|
|
void Write(char* data);
|
|
short XFRecordIndex_;
|
|
int RKValue_;
|
|
};
|
|
short rowIndex_;
|
|
short firstColIndex_;
|
|
std::vector<XFRK> XFRK_;
|
|
short lastColIndex_;
|
|
};
|
|
struct Number : public Record
|
|
{
|
|
Number();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
double value_;
|
|
|
|
private:
|
|
union
|
|
{
|
|
long long intvalue_;
|
|
double doublevalue_;
|
|
} intdouble_;
|
|
};
|
|
struct RK : public Record
|
|
{
|
|
RK();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
int value_;
|
|
};
|
|
|
|
struct Formula : public Record
|
|
{
|
|
struct Array : public Record
|
|
{
|
|
Array();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short firstRowIndex_;
|
|
short lastRowIndex_;
|
|
char firstColIndex_;
|
|
char lastColIndex_;
|
|
short options_;
|
|
int unused_;
|
|
std::vector<char> formula_;
|
|
};
|
|
struct ShrFmla : public Record
|
|
{
|
|
ShrFmla();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short firstRowIndex_;
|
|
short lastRowIndex_;
|
|
char firstColIndex_;
|
|
char lastColIndex_;
|
|
short unused_;
|
|
std::vector<char> formula_;
|
|
};
|
|
struct ShrFmla1 : public Record
|
|
{
|
|
ShrFmla1();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short firstRowIndex_;
|
|
short lastRowIndex_;
|
|
char firstColIndex_;
|
|
char lastColIndex_;
|
|
short unused_;
|
|
std::vector<char> formula_;
|
|
};
|
|
struct Table : public Record
|
|
{
|
|
Table();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short firstRowIndex_;
|
|
short lastRowIndex_;
|
|
char firstColIndex_;
|
|
char lastColIndex_;
|
|
short options_;
|
|
short inputCellRowIndex_;
|
|
short inputCellColIndex_;
|
|
short inputCellColumnInputRowIndex_;
|
|
short inputCellColumnInputColIndex_;
|
|
};
|
|
struct String : public Record
|
|
{
|
|
String();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
std::vector<wchar_t> string_;
|
|
};
|
|
|
|
Formula();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
short rowIndex_;
|
|
short colIndex_;
|
|
short XFRecordIndex_;
|
|
char result_[8];
|
|
short options_;
|
|
int unused_;
|
|
std::vector<char> RPNtoken_;
|
|
short type_;
|
|
|
|
Array array_;
|
|
ShrFmla shrfmla_;
|
|
ShrFmla1 shrfmla1_;
|
|
Table table_;
|
|
String string_;
|
|
};
|
|
|
|
CellBlock();
|
|
~CellBlock();
|
|
void Reset();
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
short RowIndex();
|
|
short ColIndex();
|
|
short LastColIndex();
|
|
short type_;
|
|
bool normalType_;
|
|
|
|
Blank blank_;
|
|
BoolErr boolerr_;
|
|
LabelSST labelsst_;
|
|
MulBlank mulblank_;
|
|
MulRK mulrk_;
|
|
Number number_;
|
|
RK rk_;
|
|
Formula formula_;
|
|
};
|
|
struct DBCell : public Record
|
|
{
|
|
DBCell();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
virtual size_t DataSize();
|
|
virtual size_t RecordSize();
|
|
int firstRowOffset_;
|
|
std::vector<short> offsets_;
|
|
};
|
|
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
|
|
std::vector<Row> rows_;
|
|
std::vector<CellBlock> cellBlocks_;
|
|
DBCell dbcell_;
|
|
};
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
|
|
std::vector<RowBlock> rowBlocks_;
|
|
};
|
|
struct Window2 : public Record
|
|
{
|
|
Window2();
|
|
virtual size_t Read(const char* data);
|
|
virtual size_t Write(char* data);
|
|
short options_;
|
|
short firstVisibleRowIndex_;
|
|
short firstVisibleColIndex_;
|
|
short gridLineColourIndex_;
|
|
short unused1_;
|
|
short magnificationFactorPageBreakPreview_;
|
|
short magnificationFactorNormalView_;
|
|
int unused2_;
|
|
};
|
|
struct SCL;
|
|
struct Pane;
|
|
struct Selection;
|
|
struct MergedCells;
|
|
struct LabelRanges;
|
|
struct ConditionalFormattingTable;
|
|
struct HyperlinkTable;
|
|
struct SheetLayout;
|
|
struct SheetProtection;
|
|
struct RangeProtection;
|
|
|
|
size_t Read(const char* data);
|
|
size_t Write(char* data);
|
|
size_t DataSize();
|
|
size_t RecordSize();
|
|
|
|
BOF bof_;
|
|
Index index_;
|
|
Dimensions dimensions_;
|
|
CellTable cellTable_;
|
|
Window2 window2_;
|
|
YEOF eof_;
|
|
};
|
|
|
|
bool IsRKValueAnInteger(int rkValue);
|
|
bool IsRKValueADouble(int rkValue);
|
|
double GetDoubleFromRKValue(int rkValue);
|
|
int GetIntegerFromRKValue(int rkValue);
|
|
int GetRKValueFromDouble(double value);
|
|
int GetRKValueFromInteger(int value);
|
|
bool CanStoreAsRKValue(double value);
|
|
|
|
// Forward declarations
|
|
class BasicExcel;
|
|
class BasicExcelWorksheet;
|
|
class BasicExcelCell;
|
|
|
|
/*******************************************************************************************************/
|
|
/* Actual classes to read and write to Excel files */
|
|
/*******************************************************************************************************/
|
|
class BasicExcel
|
|
{
|
|
public:
|
|
BasicExcel();
|
|
BasicExcel(const char* filename);
|
|
~BasicExcel();
|
|
|
|
public: // File functions.
|
|
void New(int sheets=3);
|
|
bool Load(const char* filename);
|
|
bool Save();
|
|
bool SaveAs(const char* filename);
|
|
|
|
public: // Worksheet functions.
|
|
size_t GetTotalWorkSheets();
|
|
|
|
BasicExcelWorksheet* GetWorksheet(size_t sheetIndex);
|
|
BasicExcelWorksheet* GetWorksheet(const char* name);
|
|
BasicExcelWorksheet* GetWorksheet(const wchar_t* name);
|
|
|
|
BasicExcelWorksheet* AddWorksheet(int sheetIndex=-1);
|
|
BasicExcelWorksheet* AddWorksheet(const char* name, int sheetIndex=-1);
|
|
BasicExcelWorksheet* AddWorksheet(const wchar_t* name, int sheetIndex=-1);
|
|
|
|
bool DeleteWorksheet(size_t sheetIndex);
|
|
bool DeleteWorksheet(const char* name);
|
|
bool DeleteWorksheet(const wchar_t* name);
|
|
|
|
char* GetAnsiSheetName(size_t sheetIndex);
|
|
wchar_t* GetUnicodeSheetName(size_t sheetIndex);
|
|
bool GetSheetName(size_t sheetIndex, char* name);
|
|
bool GetSheetName(size_t sheetIndex, wchar_t* name);
|
|
|
|
bool RenameWorksheet(size_t sheetIndex, const char* to);
|
|
bool RenameWorksheet(size_t sheetIndex, const wchar_t* to);
|
|
bool RenameWorksheet(const char* from, const char* to);
|
|
bool RenameWorksheet(const wchar_t* from, const wchar_t* to);
|
|
|
|
private: // Functions to read and write raw Excel format.
|
|
size_t Read(const char* data, size_t dataSize);
|
|
size_t Write(char* data);
|
|
void AdjustStreamPositions();
|
|
void AdjustBoundSheetBOFPositions();
|
|
void AdjustDBCellPositions();
|
|
void AdjustExtSSTPositions();
|
|
|
|
enum {WORKBOOK_GLOBALS=0x0005, VISUAL_BASIC_MODULE=0x0006,
|
|
WORKSHEET=0x0010, CHART=0x0020};
|
|
|
|
private: // Internal functions
|
|
void UpdateYExcelWorksheet();
|
|
void UpdateWorksheets();
|
|
|
|
public:
|
|
CompoundFile file_;
|
|
Workbook workbook_;
|
|
std::vector<Worksheet> worksheets_;
|
|
std::vector<BasicExcelWorksheet> yesheets_;
|
|
unsigned char unknown_04A0[0x108];
|
|
};
|
|
|
|
class BasicExcelWorksheet
|
|
{
|
|
friend class BasicExcel;
|
|
|
|
public:
|
|
BasicExcelWorksheet(BasicExcel* excel, size_t sheetIndex);
|
|
|
|
public: // Worksheet functions
|
|
char* GetAnsiSheetName();
|
|
wchar_t* GetUnicodeSheetName();
|
|
bool GetSheetName(char* name);
|
|
bool GetSheetName(wchar_t* name);
|
|
bool Rename(const char* to);
|
|
bool Rename(const wchar_t* to);
|
|
void Print(std::ostream& os, char delimiter=',', char textQualifier='\0');
|
|
|
|
public: // Cell functions
|
|
size_t GetTotalRows();
|
|
size_t GetTotalCols();
|
|
|
|
BasicExcelCell* Cell(size_t row, size_t col);
|
|
bool EraseCell(size_t row, size_t col);
|
|
|
|
private: // Internal functions
|
|
void UpdateCells();
|
|
|
|
private:
|
|
BasicExcel* excel_;
|
|
size_t sheetIndex_;
|
|
size_t maxRows_;
|
|
size_t maxCols_;
|
|
std::vector<std::vector<BasicExcelCell> > cells_;
|
|
};
|
|
|
|
class BasicExcelCell
|
|
{
|
|
public:
|
|
BasicExcelCell();
|
|
|
|
public:
|
|
enum {UNDEFINED, INT, DOUBLE, STRING, WSTRING};
|
|
int Type() const;
|
|
|
|
bool Get(int& val) const;
|
|
bool Get(double& val) const;
|
|
bool Get(char* str) const;
|
|
bool Get(wchar_t* str) const;
|
|
size_t GetStringLength() const;
|
|
|
|
int GetInteger() const;
|
|
double GetDouble() const;
|
|
const char* GetString() const;
|
|
const wchar_t* GetWString() const;
|
|
|
|
friend std::ostream& operator<<(std::ostream& os, const BasicExcelCell& cell);
|
|
|
|
void Set(int val);
|
|
void Set(double val);
|
|
void Set(const char* str);
|
|
void Set(const wchar_t* str);
|
|
|
|
void SetInteger(int val);
|
|
void SetDouble(double val);
|
|
void SetString(const char* str);
|
|
void SetWString(const wchar_t* str);
|
|
|
|
void EraseContents();
|
|
|
|
private:
|
|
int type_;
|
|
int ival_;
|
|
double dval_;
|
|
std::vector<char> str_;
|
|
std::vector<wchar_t> wstr_;
|
|
};
|
|
|
|
static_assert(sizeof(BasicExcel) == 0x5A8);
|
|
static_assert(sizeof(BasicExcelCell) == 0x28);
|
|
|
|
} // Namespace end
|
|
#endif
|