BasicExcel.hpp 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913
  1. // Created by Yap Chun Wei
  2. // Version 1.0 (20 April 2006)
  3. // Version 1.1 (22 April 2006)
  4. // - Fixed bugs with compound files not being able to write files more than 65535 bytes.
  5. // - Fixed bugs with reading and writing to Excel files containing many strings.
  6. // Version 1.2 (30 April 2006)
  7. // - Added operator<< to pass BasicExcelCell to an output stream.
  8. // - Added Print() to BasicExcelWorksheet to print the worksheet to an output stream.
  9. // - Change BasicExcelCell Get functions to const functions.
  10. // - Rename BasicExcelWorksheet functions RenameWorkSheet() to Rename().
  11. // Version 1.3 (10 May 2006)
  12. // - Fixed bugs with reading from Excel files containing Asian characters.
  13. // Version 1.4 (13 May 2006)
  14. // - Fixed bugs with reading and writing to Excel files containing many strings.
  15. // Version 1.5 (15 May 2006)
  16. // - Remove code for ExtSST because it was causing problems with reading and writing to Excel files containing many strings.
  17. // Version 1.6 (16 May 2006)
  18. // - Optimized code for reading and writing.
  19. // Version 1.7 (22 May 2006)
  20. // - Fixed code to remove some warnings.
  21. // - Fixed bug with BasicExcelWorksheet::Cell.
  22. // - Fixed bug with BasicExcel::UpdateWorksheets().
  23. // Version 1.8 (23 May 2006)
  24. // - Fixed bug with reading Excel files containing many unicode strings.
  25. // - Fixed code to remove some warnings.
  26. // - Fixed variable code_ duplication in BoolErr.
  27. // - Minor changes to BasicExcelCell:Set functions.
  28. // Version 1.9 (24 May 2006)
  29. // - Changed name_ in Style from SmallString to LargeString.
  30. // - Fixed bug in BasicExcelCell::GetString and BasicExcelCell::GetWString.
  31. // - Minor changes to functions in BasicExcel and BasicExcelWorksheet which checks for unicode.
  32. // - Minor change to SmallString::Read.
  33. // Version 1.10 (30 May 2006)
  34. // - Fixed bug with reading Excel files containing many strings.
  35. // - Remove memory leaks.
  36. // Version 1.11 (2 June 2006)
  37. // - Fixed bug with reading and writing Excel files containing many unicode and ANSI strings.
  38. // Version 1.12 (6 June 2006)
  39. // - Fixed bug with reading and writing Excel files containing many unicode and ANSI strings.
  40. // Version 1.13 (1 August 2006)
  41. // - Changed BasicExcelCell::Get() so that it will get a stored double as an integer or vice versa if necessary.
  42. // - Changed BasicExcelCell::Get() so that it will not cause any errors if a string is empty.
  43. // - Changed BasicExcelCell::SetString() and BasicExcelCell::SetWString() so that it will not save an empty string.
  44. // Version 1.14 (6 August 2006)
  45. // - Fixed bug with reading Excel files that contain a null string.
  46. // Version 2.0 (September 2009, Martin Fuchs)
  47. // - extended to maintain font and format information when reading and writing Excel sheets
  48. // - XLSFormatManager, ExcelFont and CellFormat to edit fonts and formats
  49. // Version 2.1 (04.10.2009, Martin Fuchs)
  50. // - fixed memory leak in XLSFormatManager::get_font_idx()
  51. // - define macros and constants for cell and font properties
  52. // Version 2.2 (07.11.2009, Martin Fuchs)
  53. // - fixed VS2008 problem when reading sheets with formula fields
  54. // - added BasicExcel::Close()
  55. // - added CellFormat::get/set_text_props() and get/set_borderlines()
  56. // Version 2.3 (05.01.2010, Ami Castonguay/Martin Fuchs)
  57. // - fixed reference counting of Formula data structs
  58. // - support for shared formulas
  59. // - support for merged cells
  60. // - save formatting even if cell is empty
  61. // - flush fstream instead of closing it followed by open to prevent races in conjunction with virus scanners
  62. // - enable reading of XLS files exported by MacOS Numbers.app
  63. // Version 2.4 (24.01.2010, Long Wenbiao/Martin Fuchs)
  64. // - add second set_borderlines() overload
  65. // - add ExcelFont::set_italic(), CellFormat::set_wrapping()
  66. // - handle COLINFO
  67. // - miscellaneous fixes
  68. // Version 2.5 (01.01.2011, Martin Fuchs)
  69. // - dynamically allocate memory for unexpected high row/column values
  70. // - Unicode overloads for Load() and SaveAs()
  71. // - adjust to RKValues written by OpenOffice Calc
  72. // Version 3.0 (23.01.2011, Martin Fuchs)
  73. // - portability fixes to enable using the code in 64 Bit development environments
  74. // - in a Windows environment use the Windows API instead of the old CompoundFile class to access compound document files
  75. // - reduced memory consumption in BasicExcel data handling
  76. // - return current value string from formula cells
  77. // - don't preserve empty rows/columns at the end of sheets
  78. #ifndef BASICEXCEL_HPP
  79. #define BASICEXCEL_HPP
  80. //MF
  81. #if defined(_MSC_VER) && _MSC_VER<=1200 // VC++ 6.0
  82. #pragma warning(disable: 4786)
  83. #define LONGINT __int64
  84. #define LONGINT_CONST(x) x
  85. #define COMPOUNDFILE
  86. #else // newer Microsoft compilers
  87. #define LONGINT long long
  88. #define LONGINT_CONST(x) x##LL
  89. #define COMPOUNDFILE CompoundFile::
  90. #ifdef _DEBUG
  91. #define _ITERATOR_DEBUG_LEVEL 0 // speedup iterator operations while debugging
  92. #endif
  93. #endif
  94. //MF type definitions of the Windows Compound Binary File Format (CBF) Specification
  95. typedef unsigned char BYTE; // 8 bit unsigned integer
  96. typedef unsigned short WORD; // 16 bit unsigned integer
  97. typedef short SHORT; // 16 bit signed integer
  98. typedef unsigned short USHORT; // 16 bit unsigned integer
  99. #ifdef _MSC_VER
  100. typedef unsigned long DWORD; // 32 bit unsigned integer
  101. typedef long LONG; // 32 bit signed integer
  102. typedef unsigned long ULONG; // 32 bit unsigned integer
  103. #else
  104. typedef unsigned int DWORD; // 32 bit unsigned integer
  105. typedef int LONG; // 32 bit signed integer
  106. typedef unsigned int ULONG; // 32 bit unsigned integer
  107. #endif
  108. typedef short OFFSET;
  109. typedef ULONG SECT;
  110. typedef ULONG FSINDEX;
  111. typedef USHORT FSOFFSET;
  112. typedef ULONG DFSIGNATURE;
  113. typedef WORD DFPROPTYPE;
  114. typedef ULONG CBF_SID; // renamed SID because of ambiguity with windows header files
  115. #ifndef GUID_DEFINED
  116. #define GUID_DEFINED
  117. typedef struct _GUID {
  118. ULONG Data1;
  119. USHORT Data2;
  120. USHORT Data3;
  121. BYTE Data4[8];
  122. } GUID;
  123. #endif
  124. typedef GUID CLSID; // 16 bytes
  125. struct TIME_T { // FILETYPE
  126. DWORD dwLowDateTime;
  127. DWORD dwHighDateTime;
  128. };
  129. #define DIFSECT 0xFFFFFFFC
  130. #define FATSECT 0xFFFFFFFD
  131. #define ENDOFCHAIN 0xFFFFFFFE
  132. #define FREESECT 0xFFFFFFFF
  133. #ifndef _WIN32
  134. enum STGTY {
  135. STGTY_INVALID = 0,
  136. STGTY_STORAGE = 1,
  137. STGTY_STREAM = 2,
  138. STGTY_LOCKBYTES = 3,
  139. STGTY_PROPERTY = 4,
  140. STGTY_ROOT = 5
  141. };
  142. #endif
  143. enum DECOLOR {
  144. DE_RED = 0,
  145. DE_BLACK = 1
  146. };
  147. #if _MSC_VER>=1400 // VS 2005
  148. #define _CRT_SECURE_NO_WARNINGS //MF
  149. #define _SCL_SECURE_NO_WARNINGS //MF
  150. #endif
  151. #include <algorithm>
  152. #include <cmath>
  153. #include <functional>
  154. #include <iostream>
  155. #include <iomanip>
  156. #include <fstream>
  157. #include <map>
  158. #include <vector>
  159. #include <string> //MF
  160. using namespace std;
  161. // get facet from locale for GCC
  162. #ifndef _USE
  163. #define _USE(loc, fac) use_facet<fac >(loc)
  164. #endif
  165. #include <assert.h> //MF
  166. #ifndef _MSC_VER
  167. #include <string.h>
  168. #endif
  169. #define UTF16
  170. #ifdef UTF16
  171. #define SIZEOFWCHAR_T 2
  172. #else
  173. #define SIZEOFWCHAR_T sizeof(wchar_t)
  174. #endif
  175. //MF string conversion functions
  176. // Courtesy of Tom Widmer (VC++ MVP)
  177. inline std::string narrow_string(const std::wstring& str)
  178. {
  179. std::string ret;
  180. if (!str.empty()) {
  181. ret.resize(str.length());
  182. typedef std::ctype<wchar_t> CT;
  183. CT const& ct = std::_USE(std::locale(), CT);
  184. ct.narrow(&str[0], &*str.begin()+str.size(), '?', &ret[0]);
  185. }
  186. return ret;
  187. }
  188. inline std::wstring widen_string(const std::string& str)
  189. {
  190. std::wstring ret;
  191. if (!str.empty()) {
  192. ret.resize(str.length());
  193. typedef std::ctype<wchar_t> CT;
  194. CT const& ct = std::_USE(std::locale(), CT);
  195. ct.widen(&str[0], &*str.begin()+str.size(), &ret[0]);
  196. }
  197. return ret;
  198. }
  199. #ifdef _WIN32
  200. #include <objbase.h>
  201. #pragma comment(lib, "ole32")
  202. // MF
  203. namespace WinCompFiles
  204. {
  205. enum CF_RESULT {
  206. INVALID_SIZE = -6,
  207. FILE_NOT_FOUND = -4,
  208. DIRECTORY_NOT_EMPTY = -3,
  209. DIRECTORY_NOT_FOUND = -2,
  210. INVALID_PATH = -1,
  211. SUCCESS = 1
  212. };
  213. struct CompoundFile
  214. {
  215. CompoundFile();
  216. ~CompoundFile();
  217. // Compound File functions
  218. bool Create(const wchar_t* filename);
  219. bool Open(const wchar_t* filename, ios_base::openmode mode=ios_base::in|ios_base::out);
  220. bool Close();
  221. bool IsOpen();
  222. // File functions
  223. CF_RESULT MakeFile(const wchar_t* path);
  224. CF_RESULT FileSize(const wchar_t* path, ULONGLONG& size);
  225. CF_RESULT ReadFile(const wchar_t* path, char* data, ULONG size);
  226. CF_RESULT ReadFile(const wchar_t* path, vector<char>&data);
  227. CF_RESULT WriteFile(const wchar_t* path, const char* data, ULONG size);
  228. CF_RESULT WriteFile(const wchar_t* path, const vector<char>&data, ULONG size);
  229. // ANSI char functions
  230. bool Create(const char* filename);
  231. bool Open(const char* filename, ios_base::openmode mode=ios_base::in|ios_base::out);
  232. CF_RESULT MakeFile(const char* path);
  233. CF_RESULT FileSize(const char* path, ULONGLONG& size);
  234. CF_RESULT ReadFile(const char* path, char* data, ULONG size);
  235. CF_RESULT ReadFile(const char* path, vector<char>& data);
  236. CF_RESULT WriteFile(const char* path, const char* data, ULONG size);
  237. CF_RESULT WriteFile(const char* path, const vector<char>& data, ULONG size);
  238. private:
  239. IStorage* _pStg;
  240. };
  241. } // namespace WinCompFiles
  242. #endif
  243. namespace YCompoundFiles
  244. {
  245. struct LittleEndian
  246. {
  247. #if defined(_MSC_VER) && _MSC_VER<=1200 // VC++ 6.0
  248. #define READWRITE(Type) \
  249. static void Read(const char* buffer, Type& retVal, size_t pos=0, int bytes=0) \
  250. { \
  251. retVal = Type(0); \
  252. if (bytes == 0) bytes = sizeof(Type); \
  253. for (size_t i=0; i<bytes; ++i) \
  254. { \
  255. retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i; \
  256. } \
  257. } \
  258. static void ReadString(const char* buffer, Type* str, size_t pos=0, int bytes=0) \
  259. { \
  260. for (size_t i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*sizeof(Type)); \
  261. } \
  262. static void Write(char* buffer, Type val, size_t pos=0, int bytes=0) \
  263. { \
  264. if (bytes == 0) bytes = sizeof(Type); \
  265. for (size_t i=0; i<bytes; ++i) \
  266. { \
  267. buffer[pos+i] = (unsigned char)val; \
  268. val >>= 8; \
  269. } \
  270. } \
  271. static void WriteString(char* buffer, Type* str, size_t pos=0, int bytes=0) \
  272. { \
  273. for (size_t i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type)); \
  274. } \
  275. static void Read(const vector<char>& buffer, Type& retVal, size_t pos=0, int bytes=0) \
  276. { \
  277. retVal = Type(0); \
  278. if (bytes == 0) bytes = sizeof(Type); \
  279. for (size_t i=0; i<bytes; ++i) \
  280. { \
  281. retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i; \
  282. } \
  283. } \
  284. static void ReadString(const vector<char>& buffer, Type* str, size_t pos=0, int bytes=0) \
  285. { \
  286. for (size_t i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*sizeof(Type)); \
  287. } \
  288. static void Write(vector<char>& buffer, Type val, size_t pos=0, int bytes=0) \
  289. { \
  290. if (bytes == 0) bytes = sizeof(Type); \
  291. for (size_t i=0; i<bytes; ++i) \
  292. { \
  293. buffer[pos+i] = (unsigned char)val; \
  294. val >>= 8; \
  295. } \
  296. } \
  297. static void WriteString(vector<char>& buffer, Type* str, size_t pos=0, int bytes=0) \
  298. { \
  299. for (size_t i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type)); \
  300. } \
  301. READWRITE(char)
  302. READWRITE(unsigned char)
  303. READWRITE(short)
  304. READWRITE(int)
  305. READWRITE(unsigned int)
  306. READWRITE(long)
  307. READWRITE(unsigned long)
  308. READWRITE(__int64)
  309. READWRITE(unsigned __int64)
  310. #undef READWRITE
  311. static void Read(const char* buffer, wchar_t& retVal, size_t pos=0, int bytes=0)
  312. {
  313. retVal = wchar_t(0);
  314. if (bytes == 0)
  315. bytes = SIZEOFWCHAR_T;
  316. for (int i=0; i<bytes; ++i)
  317. retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
  318. }
  319. static void ReadString(const char* buffer, wchar_t* str, size_t pos=0, int bytes=0)
  320. {
  321. for (int i=0; i<bytes; ++i)
  322. Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  323. }
  324. static void Write(char* buffer, wchar_t val, size_t pos=0, int bytes=0)
  325. {
  326. if (bytes == 0)
  327. bytes = SIZEOFWCHAR_T;
  328. for (int i=0; i<bytes; ++i) {
  329. buffer[pos+i] = (unsigned char)val;
  330. val >>= 8;
  331. }
  332. }
  333. static void WriteString(char* buffer, wchar_t* str, size_t pos=0, int bytes=0)
  334. {
  335. for (int i=0; i<bytes; ++i)
  336. Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  337. }
  338. static void Read(const vector<char>& buffer, wchar_t& retVal, size_t pos=0, int bytes=0)
  339. {
  340. retVal = wchar_t(0);
  341. if (bytes == 0) bytes = SIZEOFWCHAR_T;
  342. for (int i=0; i<bytes; ++i)
  343. {
  344. if (pos+i < buffer.size()) //MF
  345. retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
  346. }
  347. }
  348. static void ReadString(const vector<char>& buffer, wchar_t* str, size_t pos=0, int bytes=0)
  349. {
  350. for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  351. }
  352. static void Write(vector<char>& buffer, wchar_t val, size_t pos=0, int bytes=0)
  353. {
  354. if (bytes == 0)
  355. bytes = SIZEOFWCHAR_T;
  356. for (int i=0; i<bytes; ++i) {
  357. buffer[pos+i] = (unsigned char)val;
  358. val >>= 8;
  359. }
  360. }
  361. static void WriteString(vector<char>& buffer, wchar_t* str, size_t pos=0, int bytes=0)
  362. {
  363. for (int i=0; i<bytes; ++i)
  364. Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  365. }
  366. #else
  367. template<typename Type>
  368. static void Read(const char* buffer, Type& retVal, size_t pos=0, int bytes=0)
  369. {
  370. retVal = Type(0);
  371. if (bytes == 0)
  372. bytes = sizeof(Type);
  373. for (int i=0; i<bytes; ++i)
  374. retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;
  375. }
  376. template<typename Type>
  377. static void ReadString(const char* buffer, Type* str, size_t pos=0, int bytes=0)
  378. {
  379. for (int i=0; i<bytes; ++i)
  380. Read(buffer, str[i], pos+i*sizeof(Type));
  381. }
  382. template<typename Type>
  383. static void Write(char* buffer, Type val, size_t pos=0, int bytes=0)
  384. {
  385. if (bytes == 0)
  386. bytes = sizeof(Type);
  387. for (int i=0; i<bytes; ++i) {
  388. buffer[pos+i] = (unsigned char)val;
  389. val >>= 8;
  390. }
  391. }
  392. template<typename Type>
  393. static void WriteString(char* buffer, Type* str, size_t pos=0, int bytes=0)
  394. {
  395. for (int i=0; i<bytes; ++i)
  396. Write(buffer, str[i], pos+i*sizeof(Type));
  397. }
  398. template<typename Type>
  399. static void Read(const vector<char>& buffer, Type& retVal, size_t pos=0, int bytes=0)
  400. {
  401. retVal = Type(0);
  402. if (bytes == 0)
  403. bytes = sizeof(Type);
  404. for (int i=0; i<bytes; ++i)
  405. retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;
  406. }
  407. template<typename Type>
  408. static void ReadString(const vector<char>& buffer, Type* str, size_t pos=0, int bytes=0)
  409. {
  410. for (int i=0; i<bytes; ++i)
  411. Read(buffer, str[i], pos+i*sizeof(Type));
  412. }
  413. template<typename Type>
  414. static void Write(vector<char>& buffer, Type val, size_t pos=0, int bytes=0)
  415. {
  416. if (bytes == 0)
  417. bytes = sizeof(Type);
  418. for (int i=0; i<bytes; ++i) {
  419. buffer[pos+i] = (unsigned char)val;
  420. val >>= 8;
  421. }
  422. }
  423. template<typename Type>
  424. static void WriteString(vector<char>& buffer, Type* str, size_t pos=0, int bytes=0)
  425. {
  426. for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type));
  427. }
  428. static void Read(const char* buffer, wchar_t& retVal, size_t pos=0, int bytes=0)
  429. {
  430. retVal = wchar_t(0);
  431. if (bytes == 0)
  432. bytes = SIZEOFWCHAR_T;
  433. for (int i=0; i<bytes; ++i)
  434. retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
  435. }
  436. static void ReadString(const char* buffer, wchar_t* str, size_t pos=0, int bytes=0)
  437. {
  438. for (int i=0; i<bytes; ++i)
  439. Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  440. }
  441. static void Write(char* buffer, wchar_t val, size_t pos=0, int bytes=0)
  442. {
  443. if (bytes == 0)
  444. bytes = SIZEOFWCHAR_T;
  445. for (int i=0; i<bytes; ++i) {
  446. buffer[pos+i] = (unsigned char)val;
  447. val >>= 8;
  448. }
  449. }
  450. static void WriteString(char* buffer, wchar_t* str, size_t pos=0, int bytes=0)
  451. {
  452. for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  453. }
  454. static void Read(const vector<char>& buffer, wchar_t& retVal, size_t pos=0, int bytes=0)
  455. {
  456. retVal = wchar_t(0);
  457. if (bytes == 0)
  458. bytes = SIZEOFWCHAR_T;
  459. for (int i=0; i<bytes; ++i) {
  460. if (pos+i < (int)buffer.size()) //MF
  461. retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
  462. }
  463. }
  464. static void ReadString(const vector<char>& buffer, wchar_t* str, size_t pos=0, int bytes=0)
  465. {
  466. for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  467. }
  468. static void Write(vector<char>& buffer, wchar_t val, size_t pos=0, int bytes=0)
  469. {
  470. if (bytes == 0)
  471. bytes = SIZEOFWCHAR_T;
  472. for (int i=0; i<bytes; ++i) {
  473. buffer[pos+i] = (unsigned char)val;
  474. val >>= 8;
  475. }
  476. }
  477. static void WriteString(vector<char>& buffer, wchar_t* str, size_t pos=0, int bytes=0)
  478. {
  479. for (int i=0; i<bytes; ++i)
  480. Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
  481. }
  482. #endif
  483. };
  484. #ifndef _WIN32
  485. class Block
  486. // PURPOSE: In charge of handling blocks of data from a file
  487. {
  488. public:
  489. Block();
  490. // File handling functions
  491. bool Create(const wchar_t* filename);
  492. bool Open(const wchar_t* filename, ios_base::openmode mode=ios_base::in | ios_base::out);
  493. bool Close();
  494. bool IsOpen();
  495. // Block handling functions
  496. bool Read(SECT index, char* block);
  497. bool Write(SECT index, const char* block);
  498. bool Swap(SECT index1, SECT index2);
  499. bool Move(SECT from, SECT to);
  500. bool Insert(SECT index, const char* block);
  501. bool Erase(SECT index);
  502. bool Erase(vector<SECT>& indices);
  503. // Misc functions
  504. ULONG GetBlockSize() const {return blockSize_;}
  505. void SetBlockSize(ULONG size)
  506. {
  507. blockSize_ = size;
  508. indexEnd_ = fileSize_/blockSize_ + (fileSize_%blockSize_? 1: 0);
  509. }
  510. protected:
  511. vector<char> filename_;
  512. ios_base::openmode mode_;
  513. fstream file_;
  514. ULONG blockSize_;
  515. SECT indexEnd_;
  516. ULONG fileSize_;
  517. };
  518. enum {
  519. DUPLICATE_PROPERTY=-6,
  520. NAME_TOO_LONG=-5, FILE_NOT_FOUND=-4,
  521. DIRECTORY_NOT_EMPTY=-3, DIRECTORY_NOT_FOUND=-2,
  522. INVALID_PATH=-1,
  523. SUCCESS=1
  524. };
  525. class CompoundFile
  526. {
  527. public:
  528. CompoundFile();
  529. ~CompoundFile();
  530. // User accessible functions
  531. public:
  532. // Compound File functions
  533. bool Create(const wchar_t* filename);
  534. bool Open(const wchar_t* filename, ios_base::openmode mode=ios_base::in | ios_base::out);
  535. bool Close();
  536. bool IsOpen();
  537. // Directory functions
  538. int ChangeDirectory(const wchar_t* path);
  539. int MakeDirectory(const wchar_t* path);
  540. // File functions
  541. int MakeFile(const wchar_t* path);
  542. int FileSize(const wchar_t* path, ULONG& size);
  543. int ReadFile(const wchar_t* path, char* data);
  544. int ReadFile(const wchar_t* path, vector<char>&data);
  545. int WriteFile(const wchar_t* path, const char* data, ULONG size);
  546. int WriteFile(const wchar_t* path, const vector<char>&data, ULONG size);
  547. // ANSI char functions
  548. bool Create(const char* filename);
  549. bool Open(const char* filename, ios_base::openmode mode=ios_base::in | ios_base::out);
  550. int ChangeDirectory(const char* path);
  551. int MakeDirectory(const char* path);
  552. int MakeFile(const char* path);
  553. int FileSize(const char* path, ULONG& size);
  554. int ReadFile(const char* path, char* data);
  555. int ReadFile(const char* path, vector<char>& data);
  556. int WriteFile(const char* path, const char* data, ULONG size);
  557. int WriteFile(const char* path, const vector<char>& data, ULONG size);
  558. // Protected functions and data members
  559. protected:
  560. // General functions and data members
  561. void IncreaseLocationReferences(vector<SECT> indices);
  562. void DecreaseLocationReferences(vector<SECT> indices);
  563. void SplitPath(const wchar_t* path, wchar_t*& parentpath, wchar_t*& propertyname);
  564. vector<char> block_;
  565. Block file_;
  566. // Header related functions and data members
  567. bool LoadHeader();
  568. void SaveHeader();
  569. class Header
  570. {
  571. public:
  572. Header();
  573. void Write(char* block);
  574. void Read(char* block);
  575. LONGINT _abSig; // 0x0000 Magic number identifying this as a compound file system
  576. CLSID _clid; // 0x0008 class id (set with WriteClassStgm retrieved with GetClassFile/ReadClassStg)
  577. USHORT _ulMinorVersion; // 0x0018 minor version of the format: 33 is written by reference implementation
  578. USHORT _uDllVersion; // 0x001A major version of the dll/format: 3 is written by reference implementation
  579. USHORT _uByteOrder; // 0x001C 0xFFFE: indicates Intel byte ordering
  580. USHORT _uSectorShift; // 0x001E size of sectors in power-of-two, typically 9, indicating 512-byte sectors
  581. USHORT _uMiniSectorShift; // 0x0020 size of mini-sectors in power-of-two, typically 67, indicating 64-byte mini-sectors
  582. USHORT _usReserved; // 0x0022 reserved, must be zero
  583. ULONG _ulReserved1; // 0x0024 reserved, must be zero
  584. ULONG _ulReserved2; // 0x0028 reserved, must be zero
  585. FSINDEX _csectFat; // 0x002C number of SECTs in the FAT chain / "Number of elements in the BAT array"
  586. SECT _sectDirStat; // 0x0030 first SECT in the directory chain / "Block index of the first block of the property table"
  587. DFSIGNATURE _signature; // 0x0034 signature used for transactioning: must be zero, not supported by reference implementation
  588. ULONG _ulMiniSectorCutOff;// 0x0038 maximum size for mini-streams: typically 4096 bytes
  589. SECT _sectMiniFatStart; // 0x003C first SECT in the mini-FAT chain / "Block index of first big block containing the small block allocation table (SBAT)"
  590. FSINDEX _csectMiniFat; // 0x0040 number of SECTs in the mini-FAT chain / "Number of big blocks holding the SBAT"
  591. SECT _sectDifStart; // 0x0044 first SECT in the DIFG chain / "Block index of the first block in the Extended Block Allocation Table (XBAT)"
  592. FSINDEX _csectDif; // 0x0048 number of SECTs in the DIF chain / "Number of elements in the Extended Block Allocation Table (to be added to the BAT)"
  593. SECT _sectFat[109]; // 0x004C..0x01FF the SECTs of the first 109 FAT sectors / "Array of block indices constituting the Block Allocation Table (BAT)"
  594. ULONG bigBlockSize_;
  595. ULONG smallBlockSize_;
  596. private:
  597. void Initialize();
  598. };
  599. Header header_;
  600. // BAT related functions and data members
  601. void LoadBAT();
  602. void SaveBAT();
  603. ULONG DataSize(SECT startIndex, bool isBig);
  604. ULONG ReadData(SECT startIndex, char* data, bool isBig);
  605. SECT WriteData(const char* data, ULONG size, SECT startIndex, bool isBig);
  606. void GetBlockIndices(SECT startIndex, vector<SECT>& indices, bool isBig);
  607. SECT GetFreeBlockIndex(bool isBig);
  608. void ExpandBATArray(bool isBig);
  609. void LinkBlocks(SECT from, SECT to, bool isBig);
  610. void FreeBlocks(vector<SECT>& indices, bool isBig);
  611. vector<SECT> blocksIndices_;
  612. vector<SECT> sblocksIndices_;
  613. // Properties related functions and data members
  614. class DirectoryEntry // struct StructuredStorageDirectoryEntry
  615. {
  616. public:
  617. DirectoryEntry();
  618. void Write(char* block);
  619. void Read(char* block);
  620. friend bool operator==(const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs)
  621. {
  622. return (!wcscmp(lhs.name_, rhs.name_));
  623. }
  624. friend bool operator< (const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs)
  625. {
  626. size_t maxLen1 = wcslen(lhs.name_);
  627. size_t maxLen2 = wcslen(rhs.name_);
  628. if (maxLen1 < maxLen2) return true;
  629. else if (maxLen1 > maxLen2) return false;
  630. else
  631. {
  632. int result = wcscmp(lhs.name_, rhs.name_);
  633. if (result <= 0) return true;
  634. else return false;
  635. }
  636. }
  637. friend bool operator!=(const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs) {return !(lhs == rhs);}
  638. friend bool operator> (const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs) {return (rhs < lhs);}
  639. friend bool operator<=(const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs) {return !(rhs < lhs);}
  640. friend bool operator>=(const COMPOUNDFILE DirectoryEntry& lhs, const COMPOUNDFILE DirectoryEntry& rhs) {return !(lhs < rhs);}
  641. wchar_t name_[32]; // 0x00..0x3E the element name in Unicode, padded with zeros to fill the array / "A unicode null-terminated uncompressed 16bit string (lblocke the high bytes) containing the name of the property"
  642. WORD _cb_namesize; // 0x40 length of the element name in characters, not bytes / "Number of characters in the NAME field"
  643. BYTE _mse; // 0x42 type of object: value taken from the STGTY enumeration / "DirectoryEntry type (directory, file, or root) Byte 1 (directory), 2 (file), or 5 (root entry)"
  644. BYTE _bflags; // 0x43 value taken form DECOLOR enumeration / "Node color"
  645. CBF_SID _sidLeftSib; // 0x44 SID of the left-sibling of this entry in the directory tree / "Previous property index"
  646. CBF_SID _sidRightSib; // 0x48 SID of the right-sibling of this entry in the directroy tree / "Next property index"
  647. CBF_SID _sidChild; // 0x4C SID of the child acting as the root of all the children of this element (if _mse=STGTY_STORAGE) / "First child property index"
  648. GUID _clsId; // 0x50 CLSID if this storage (if _mse=STGTY_STORAGE)
  649. DWORD _dwUserFlags; // 0x60 user flags of this storage (if _mse=STGTY_STORAGE)
  650. TIME_T _time[2]; // 0x64 create/modify time stamps (if _mse=STGTY_STORAGE)
  651. SECT _sectStart; // 0x74 starting SECT of the stream (if _mse=STGTY_STORAGE) / "Starting block of the file, used as the first block in the file and the pointer to the next block from the BAT"
  652. ULONG _ulSize; // 0x78 size of stream in bytes (if _mse=STGTY_STORAGE) / "Actual size of the file this property points to. (used to truncate the blocks to the real size)."
  653. DFPROPTYPE _dptPropType; // 0x7C reserved for future use, must be zero
  654. };
  655. class PropertyTree
  656. {
  657. public:
  658. PropertyTree();
  659. ~PropertyTree();
  660. PropertyTree* parent_;
  661. DirectoryEntry* self_;
  662. SECT index_;
  663. vector<PropertyTree*> children_;
  664. };
  665. void LoadProperties();
  666. void SaveProperties();
  667. int MakeProperty(const wchar_t* path, DirectoryEntry* property);
  668. PropertyTree* FindProperty(SECT index);
  669. PropertyTree* FindProperty(const wchar_t* path);
  670. PropertyTree* FindProperty(PropertyTree* parentTree, wchar_t* name);
  671. void InsertPropertyTree(PropertyTree* parentTree, DirectoryEntry* property, SECT index);
  672. void DeletePropertyTree(PropertyTree* tree);
  673. void UpdateChildrenIndices(PropertyTree* parentTree);
  674. void IncreasePropertyReferences(PropertyTree* parentTree, SECT index);
  675. void DecreasePropertyReferences(PropertyTree* parentTree, SECT index);
  676. PropertyTree* propertyTrees_;
  677. PropertyTree* currentDirectory_;
  678. vector<DirectoryEntry*> dirEntries_;
  679. vector<PropertyTree*> previousDirectories_;
  680. };
  681. #endif // _WIN32
  682. } // namespace YCompoundFiles
  683. // reference counting to implement smart pointers
  684. namespace RefCount
  685. {
  686. // reference counter for SmartPtr managed objects
  687. struct RefCnt
  688. {
  689. // On construction the reference counter is initialized with an usage count of 0.
  690. RefCnt()
  691. : _ref_cnt(0)
  692. {
  693. }
  694. int _ref_cnt;
  695. };
  696. // reference counting smart pointer
  697. template<typename T> struct SmartPtr
  698. {
  699. // default constructor
  700. SmartPtr()
  701. : _ptr(NULL)
  702. {
  703. }
  704. // The initialized SmartPtr constructor increments the reference counter in struct RefCnt.
  705. SmartPtr(T* p)
  706. : _ptr(p)
  707. {
  708. if (p)
  709. ++_ptr->_ref_cnt;
  710. }
  711. // The copy constructor increments the reference counter.
  712. SmartPtr(const SmartPtr& other)
  713. : _ptr(other._ptr)
  714. {
  715. if (_ptr)
  716. ++_ptr->_ref_cnt;
  717. }
  718. // The destructor decreases the reference counter and
  719. // frees the managed memory as the counter reaches zero.
  720. ~SmartPtr()
  721. {
  722. if (_ptr) {
  723. if (!--_ptr->_ref_cnt)
  724. delete _ptr;
  725. }
  726. }
  727. // The assignment operator increments the reference counter.
  728. SmartPtr& operator=(T* p)
  729. {
  730. if (_ptr) {
  731. if (!--_ptr->_ref_cnt)
  732. delete _ptr;
  733. _ptr = NULL;
  734. }
  735. if (p) {
  736. _ptr = p;
  737. ++_ptr->_ref_cnt;
  738. }
  739. return *this;
  740. }
  741. // operator bool() to check for non-empty smart pointers
  742. operator bool() const {return _ptr != NULL;}
  743. // operator!() to check for empty smart pointers
  744. bool operator!() const {return !_ptr;}
  745. // operator->() to access the managed objects
  746. T* operator->() {return _ptr;}
  747. const T* operator->() const {return _ptr;}
  748. // Derefence pointed memory
  749. T& operator*() {return *_ptr;}
  750. const T& operator*() const {return *_ptr;}
  751. private:
  752. T* _ptr;
  753. };
  754. } // namespace RefCount
  755. //MF
  756. namespace ExcelFormat {
  757. struct CellFormat;
  758. }
  759. namespace YExcel
  760. {
  761. using namespace YCompoundFiles;
  762. #ifdef _WIN32
  763. using namespace WinCompFiles;
  764. #endif
  765. struct CODE
  766. {
  767. enum { FORMULA=0x0006, //Token array and the result of a formula cell.
  768. YEOF=0x000A, //End of a record block with leading BOF record.
  769. CALCCOUNT=0x000C, //Maximum number of times the forumlas should be iteratively calculated
  770. CALCMODE=0x000D, //Calculate formulas manually, automatically, or automatically except for multiple table operations
  771. PRECISION=0x000E, //Whether formulas use the real cell values for calculation or the values displayed on the screen.
  772. REFMODE=0x000F, //Method used to show cell addresses in formulas.
  773. DELTA=0x0010, //Maximum change of the result to exit an iteration.
  774. ITERATION=0x0011, //Whether iterations are allowed while calculating recursive formulas.
  775. PROTECT=0x0012, //Whether worksheet or a workbook is protected against modification.
  776. PASSWORD=0x0013, //16-bit hash value, calculated from the worksheet or workbook protection password.
  777. HEADER=0x0014, //Page header string for the current worksheet.
  778. FOOTER=0x0015, //Page footer string for the current worksheet.
  779. EXTERNSHEET=0x0017, //List with indexes to SUPBOOK records
  780. NAME=0x0018, //Name and token array of an internal defined name.
  781. WINDOWPROTECT=0x0019, //Whether the window configuration of the document is protected.
  782. SELECTION=0x001D, //Addresses of all selected cell ranges and position of the active cell for a pane in the current sheet.
  783. DATEMODE=0x0022, //Base date for displaying date values.
  784. EXTERNNAME=0x0023, //Name of an external defined name, name of an add-in function, a DDE item or an OLE object storage identifier.
  785. LEFTMARGIN=0x0026, //Left page margin of the current worksheet.
  786. RIGHTMARGIN=0x0027, //Right page margin of the current worksheet.
  787. TOPMARGIN=0x0028, //Top page margin of the current worksheet.
  788. BOTTOMMARGIN=0x0029, //Bottom page margin of current worksheet
  789. PRINTHEADERS=0x002A, //Whether row and column headers (the areas with row numbers and column letters) will be printed.
  790. PRINTGRIDLINES=0x002B, //Whether sheet grid lines will be printed.
  791. FILEPASS=0x002F, //Information about the read/write password of the file.
  792. FONT=0x0031, //Information about a used font, including character formatting.
  793. TABLE=0x0036, //Information about a multiple operation table in the sheet.
  794. CONTINUE=0x003C, //Continue from previous record
  795. WINDOW1=0x003D, //General settings for the workbook global settings.
  796. BACKUP=0x0040, //Make backup of file while saving?
  797. PANE=0x0041, //Position of window panes.
  798. CODEPAGE=0x0042, //Text encoding used to encode byte strings
  799. DCONREF=0x0051,
  800. DEFCOLWIDTH=0x0055, //Default column width for columns that do not have a specific width set
  801. XCT=0x0059, //Number of immediately following CRN records.
  802. CRN=0x005A, //Contents of an external cell or cell range.
  803. FILESHARING=0x005B, //Information about write protection, for instance the write protection password.
  804. WRITEACCESS=0x005C, //Name of the user that has saved the file.
  805. UNCALCED=0x005E, //Formulas have not been recalculated before the document was saved.
  806. SAVERECALC=0x005F, //"Recalculate before save" option
  807. OBJECTPROTECT=0x0063, //Whether objects of the current sheet are protected.
  808. COLINFO=0x007D, //Width for a given range of columns
  809. GUTS=0x0080, //Layout of outline symbols.
  810. WSBOOL=0x0081, //16-bit value with boolean options for the current sheet.
  811. GRIDSET=0x0082, //Whether option to print sheet grid lines has ever been changed.
  812. HCENTER=0x0083, //Sheet is centred horizontally when printed.
  813. VCENTER=0x0084, //Whether sheet is centred vertically when printed.
  814. BOUNDSHEET=0x0085, //Sheet inside of the workbook
  815. WRITEPROT=0x0086, //Whether file is write protected.
  816. COUNTRY=0x008C, //User interface language of the Excel version that has saved the file, system regional settings at the time the file was saved.
  817. HIDEOBJ=0x008D, //Whether and how to show objects in the workbook.
  818. SORT=0x0090, //Last settings from the "Sort" dialogue for each sheet.
  819. PALETTE=0x0092, //Definition of all user-defined colours available for cell and object formatting.
  820. SETUP=0x00A1, //Page format settings of the current sheet.
  821. SHRFMLA=0x00BC, //Token array of a shared formula.
  822. MULRK=0x00BD, //Cell range containing RK value cells. All cells are located in the same row.
  823. MULBLANK=0x00BE, //Cell range of empty cells. All cells are located in the same row.
  824. DBCELL=0x00D7, //Relative offsets to calculate stream position of the first cell record for each row.
  825. BOOKBOOL=0x00DA, //Save values linked from external workbooks records and XCT records?
  826. SCENPROTECT=0x00DD, //Whether scenarios of the current sheet are protected.
  827. XF=0x00E0, //Formatting information for cells, rows, columns or styles.
  828. MERGECELLS=0x00E5, //All merged cell ranges of the current sheet.
  829. SST=0x00FC, //List of all strings used anywhere in the workbook.
  830. LABELSST=0x00FD, //Cell that contains a string.
  831. EXTSST=0x00FF, //Create a hash table with stream offsets to the SST record to optimise string search operations.
  832. LABELRANGES=0x015F, //Addresses of all row and column label ranges in the current sheet.
  833. USESELFS=0x0160, //Whether formulas in the workbook can use "natural language formulas".
  834. DSF=0x0161, //Whether file contains an addition BIFF5/BIFF7 workbook stream.
  835. SUPBOOK=0x01AE, //URL of an external document and a list of sheet names inside this document.
  836. CONDFMT=0x01B0, //List of cell range addresses for all cells with equal conditional formatting.
  837. CF=0x01B1, //Condition and the formatting attributes applied to the cells specified in the CONDFMT record, if the condition is met
  838. DVAL=0x01B2, //List header of the data validity table in the current sheet.
  839. HLINK=0x01B8, //One cell address or a cell range where all cells contain the same hyperlink.
  840. DV=0x01BE, //Data validity settings and a list of cell ranges which contain these settings.
  841. DIMENSIONS=0x0200, //Range address of the used area in the current sheet.
  842. BLANK=0x0201, //Empty cell, contains cell address and formatting information
  843. NUMBER=0x0203, //Cell that contains a floating-point value.
  844. BOOLERR=0x0205, //Error value cell
  845. STRING=0x0207, //Result of a string formula.
  846. ROW=0x0208, //Properties of a single row in the sheet.
  847. INDEX=0x020B, //Range of used rows and stream positions of several records of the current sheet.
  848. ARRAY=0x0221, //Token array of an array formula
  849. WINDOW2=0x023E, //Additional settings for the window of a specific worksheet.
  850. RK=0x027E, //Cell that contains an RK value (encoded integer or floating point value).
  851. STYLE=0x0293, //Name of a user-defined cell style or specific options for a built-in cell style.
  852. FORMAT=0x041E, //Number format.
  853. SHRFMLA1=0x04BC, //Token array of a shared formula (added).
  854. QUICKTIP=0x0800, //Cell range and text for a tool tip.
  855. BOF=0x0809, //Beginning of file
  856. SHEETLAYOUT=0x0862, //Colour of the tab below the sheet containing the sheet name.
  857. SHEETPROTECTION=0x0867, //Additional options for sheet protection.
  858. RANGEPROTECTION=0x0868, //Information about special protected ranges in a protected sheet.
  859. SXFORMULA=0x0103, //PivotTable Formula Record
  860. };
  861. };
  862. class Record
  863. {
  864. public:
  865. Record();
  866. virtual ~Record();
  867. virtual ULONG Read(const char* data);
  868. virtual ULONG Write(char* data);
  869. virtual ULONG DataSize();
  870. virtual ULONG RecordSize();
  871. USHORT code_;
  872. vector<char> data_;
  873. ULONG dataSize_;
  874. ULONG recordSize_;
  875. vector<ULONG> continueIndices_;
  876. };
  877. struct BOF : public Record
  878. {
  879. BOF();
  880. virtual ULONG Read(const char* data);
  881. virtual ULONG Write(char* data);
  882. USHORT version_;
  883. USHORT type_;
  884. USHORT buildIdentifier_;
  885. USHORT buildYear_;
  886. ULONG fileHistoryFlags_;
  887. ULONG lowestExcelVersion_;
  888. };
  889. struct YEOF : public Record
  890. {
  891. YEOF();
  892. };
  893. // String with 1 byte length field
  894. struct SmallString
  895. {
  896. SmallString();
  897. ~SmallString();
  898. SmallString(const SmallString& s);
  899. SmallString& operator=(const SmallString& s);
  900. const SmallString& operator=(const char* str);
  901. const SmallString& operator=(const wchar_t* str);
  902. void Reset();
  903. ULONG Read(const char* data);
  904. ULONG Write(char* data);
  905. ULONG DataSize();
  906. ULONG RecordSize();
  907. ULONG StringSize();
  908. wchar_t* wname_;
  909. char* name_;
  910. char unicode_;
  911. };
  912. // String with 2 byte length field
  913. struct LargeString
  914. {
  915. LargeString();
  916. ~LargeString();
  917. LargeString(const LargeString& s);
  918. LargeString& operator=(const LargeString& s);
  919. const LargeString& operator=(const char* str);
  920. const LargeString& operator=(const wchar_t* str);
  921. void Reset();
  922. ULONG Read(const char* data);
  923. ULONG ContinueRead(const char* data, int size);
  924. ULONG Write(char* data);
  925. ULONG DataSize();
  926. ULONG RecordSize();
  927. ULONG StringSize();
  928. vector<wchar_t> wname_;
  929. vector<char> name_;
  930. char unicode_;
  931. USHORT richtext_;
  932. ULONG phonetic_;
  933. };
  934. //MF string conversion functions
  935. inline std::string narrow_string(const vector<wchar_t>& wstr)
  936. {
  937. return ::narrow_string(wstring(&*wstr.begin(), wstr.size()));
  938. }
  939. inline std::wstring widen_string(const vector<char>& wstr)
  940. {
  941. return ::widen_string(string(&*wstr.begin(), wstr.size()));
  942. }
  943. inline string stringFromSmallString(const SmallString& ss)
  944. {
  945. if (ss.unicode_)
  946. return ::narrow_string(ss.wname_);
  947. else
  948. return ss.name_;
  949. }
  950. inline string stringFromLargeString(const LargeString& ls)
  951. {
  952. if (ls.unicode_)
  953. return narrow_string(ls.wname_);
  954. else
  955. return string(&*ls.name_.begin(), ls.name_.size());
  956. }
  957. inline wstring wstringFromSmallString(const SmallString& ss)
  958. {
  959. if (ss.unicode_)
  960. return ss.wname_;
  961. else
  962. return ::widen_string(ss.name_);
  963. }
  964. inline wstring wstringFromLargeString(const LargeString& ls)
  965. {
  966. if (ls.unicode_)
  967. return wstring(&*ls.wname_.begin(), ls.wname_.size());
  968. else
  969. return widen_string(ls.name_);
  970. }
  971. class Workbook
  972. {
  973. public:
  974. Workbook();
  975. public:
  976. struct FileProtection;
  977. struct CodePage;
  978. struct DSF;
  979. struct TabID;
  980. struct FnGroupCount;
  981. struct WorkbookProtection;
  982. struct Window1 : public Record
  983. {
  984. Window1();
  985. virtual ULONG Read(const char* data);
  986. virtual ULONG Write(char* data);
  987. USHORT horizontalPos_;
  988. USHORT verticalPos_;
  989. USHORT width_;
  990. USHORT height_;
  991. USHORT options_;
  992. USHORT activeWorksheetIndex_;
  993. USHORT firstVisibleTabIndex_;
  994. USHORT selectedWorksheetNo_;
  995. USHORT worksheetTabBarWidth_;
  996. };
  997. struct Backup;
  998. struct HideObj;
  999. struct DateMode;
  1000. struct Precision;
  1001. struct RefreshAll;
  1002. struct BookBool;
  1003. struct Font : public Record
  1004. {
  1005. Font();
  1006. virtual ULONG Read(const char* data);
  1007. virtual ULONG Write(char* data);
  1008. virtual ULONG DataSize();
  1009. virtual ULONG RecordSize();
  1010. USHORT height_;
  1011. USHORT options_;
  1012. USHORT colourIndex_;
  1013. USHORT weight_;
  1014. USHORT escapementType_;
  1015. BYTE underlineType_;
  1016. BYTE family_;
  1017. BYTE characterSet_;
  1018. BYTE unused_;
  1019. SmallString name_;
  1020. };
  1021. struct Format : public Record
  1022. {
  1023. //MF
  1024. Format();
  1025. virtual ULONG Read(const char* data);
  1026. virtual ULONG Write(char* data);
  1027. virtual ULONG DataSize();
  1028. virtual ULONG RecordSize();
  1029. USHORT index_;
  1030. LargeString fmtstring_;
  1031. };
  1032. struct XF : public Record
  1033. {
  1034. XF();
  1035. virtual ULONG Read(const char* data);
  1036. virtual ULONG Write(char* data);
  1037. USHORT fontRecordIndex_;
  1038. USHORT formatRecordIndex_;
  1039. USHORT protectionType_;
  1040. BYTE alignment_; // 0x08: 1 = Text is wrapped at right border
  1041. BYTE rotation_;
  1042. BYTE textProperties_;
  1043. BYTE usedAttributes_;
  1044. ULONG borderLines_;
  1045. ULONG colour1_;
  1046. USHORT colour2_;
  1047. };
  1048. struct Style : public Record
  1049. {
  1050. Style();
  1051. virtual ULONG Read(const char* data);
  1052. virtual ULONG Write(char* data);
  1053. virtual ULONG DataSize();
  1054. virtual ULONG RecordSize();
  1055. USHORT XFRecordIndex_;
  1056. BYTE identifier_;
  1057. BYTE level_;
  1058. LargeString name_;
  1059. };
  1060. struct Palette;
  1061. struct UseSelfs;
  1062. struct BoundSheet : public Record
  1063. {
  1064. BoundSheet();
  1065. virtual ULONG Read(const char* data);
  1066. virtual ULONG Write(char* data);
  1067. virtual ULONG DataSize();
  1068. virtual ULONG RecordSize();
  1069. ULONG BOFpos_;
  1070. BYTE visibility_;
  1071. BYTE type_;
  1072. SmallString name_;
  1073. };
  1074. struct Country;
  1075. struct LinkTable;
  1076. struct SharedStringTable : public Record
  1077. {
  1078. SharedStringTable();
  1079. virtual ULONG Read(const char* data);
  1080. virtual ULONG Write(char* data);
  1081. virtual ULONG DataSize();
  1082. virtual ULONG RecordSize();
  1083. ULONG stringsTotal_;
  1084. ULONG uniqueStringsTotal_;
  1085. vector<LargeString> strings_;
  1086. };
  1087. struct ExtSST : public Record
  1088. {
  1089. ExtSST();
  1090. virtual ULONG Read(const char* data);
  1091. virtual ULONG Write(char* data);
  1092. virtual ULONG DataSize();
  1093. virtual ULONG RecordSize();
  1094. USHORT stringsTotal_;
  1095. vector<ULONG> streamPos_;
  1096. vector<USHORT> firstStringPos_;
  1097. vector<USHORT> unused_;
  1098. };
  1099. ULONG Read(const char* data);
  1100. ULONG Write(char* data);
  1101. ULONG DataSize();
  1102. ULONG RecordSize();
  1103. BOF bof_;
  1104. Window1 window1_;
  1105. vector<Font> fonts_;
  1106. vector<XF> XFs_;
  1107. vector<Style> styles_;
  1108. vector<Format> formats_; //MF
  1109. vector<BoundSheet> boundSheets_;
  1110. SharedStringTable sst_; // shared string table
  1111. ExtSST extSST_;
  1112. YEOF eof_;
  1113. };
  1114. //MF: exception to handle unexpected YEOF records
  1115. struct EXCEPTION_YEOF
  1116. {
  1117. EXCEPTION_YEOF(ULONG bytesRead)
  1118. : _bytesRead(bytesRead)
  1119. {
  1120. }
  1121. ULONG _bytesRead;
  1122. };
  1123. //MF
  1124. using namespace RefCount;
  1125. class Worksheet
  1126. {
  1127. public:
  1128. Worksheet();
  1129. public:
  1130. struct Uncalced;
  1131. struct Index : public Record
  1132. {
  1133. Index();
  1134. virtual ULONG Read(const char* data);
  1135. virtual ULONG Write(char* data);
  1136. virtual ULONG DataSize();
  1137. virtual ULONG RecordSize();
  1138. ULONG unused1_;
  1139. size_t firstUsedRowIndex_;
  1140. size_t firstUnusedRowIndex_;
  1141. ULONG unused2_;
  1142. vector<ULONG> DBCellPos_;
  1143. };
  1144. struct CalculationSettings
  1145. {
  1146. struct CalcCount;
  1147. struct CalcMode;
  1148. struct RefMode;
  1149. struct Delta;
  1150. struct Iteration;
  1151. struct SafeRecalc;
  1152. };
  1153. struct PrintHeaders;
  1154. struct PrintGridlines;
  1155. struct Gridset;
  1156. struct Guts;
  1157. struct DefaultRowHeight;
  1158. struct WSBool;
  1159. struct PageSettings
  1160. {
  1161. struct Header;
  1162. struct Footer;
  1163. struct HCenter;
  1164. struct VCenter;
  1165. struct LeftMargin;
  1166. struct RightMargin;
  1167. struct TopMargin;
  1168. struct BottomMargin;
  1169. struct PLS;
  1170. struct Setup;
  1171. };
  1172. struct WorksheetProtection;
  1173. struct DefColWidth;
  1174. struct ColInfo : public Record
  1175. {
  1176. ColInfo();
  1177. virtual ULONG Read(const char* data);
  1178. virtual ULONG Write(char* data);
  1179. USHORT firstColumnIndex_;
  1180. USHORT lastColumnIndex_;
  1181. USHORT columnWidth_;
  1182. USHORT XFRecordIndex_;
  1183. USHORT options_;
  1184. USHORT unused_;
  1185. };
  1186. struct Sort;
  1187. struct ColInfos : public Record
  1188. {
  1189. virtual ULONG Read(const char* data);
  1190. virtual ULONG Write(char* data);
  1191. virtual ULONG RecordSize();
  1192. vector<ColInfo> colinfo_;
  1193. };
  1194. struct Dimensions : public Record
  1195. {
  1196. Dimensions();
  1197. virtual ULONG Read(const char* data);
  1198. virtual ULONG Write(char* data);
  1199. ULONG firstUsedRowIndex_;
  1200. ULONG lastUsedRowIndexPlusOne_;
  1201. USHORT firstUsedColIndex_;
  1202. USHORT lastUsedColIndexPlusOne_;
  1203. USHORT unused_;
  1204. };
  1205. struct CellTable
  1206. {
  1207. struct RowBlock
  1208. {
  1209. struct Row : public Record
  1210. {
  1211. Row();
  1212. virtual ULONG Read(const char* data);
  1213. virtual ULONG Write(char* data);
  1214. USHORT rowIndex_;
  1215. USHORT firstCellColIndex_;
  1216. USHORT lastCellColIndexPlusOne_;
  1217. USHORT height_;
  1218. USHORT unused1_;
  1219. USHORT unused2_;
  1220. ULONG options_;
  1221. };
  1222. struct CellBlock : public RefCnt
  1223. {
  1224. struct Blank : public Record
  1225. {
  1226. Blank();
  1227. virtual ULONG Read(const char* data);
  1228. virtual ULONG Write(char* data);
  1229. USHORT rowIndex_;
  1230. USHORT colIndex_;
  1231. USHORT XFRecordIndex_;
  1232. };
  1233. struct BoolErr : public Record
  1234. {
  1235. BoolErr();
  1236. virtual ULONG Read(const char* data);
  1237. virtual ULONG Write(char* data);
  1238. USHORT rowIndex_;
  1239. USHORT colIndex_;
  1240. USHORT XFRecordIndex_;
  1241. BYTE value_;
  1242. BYTE error_;
  1243. };
  1244. struct LabelSST : public Record
  1245. {
  1246. LabelSST();
  1247. virtual ULONG Read(const char* data);
  1248. virtual ULONG Write(char* data);
  1249. USHORT rowIndex_;
  1250. USHORT colIndex_;
  1251. USHORT XFRecordIndex_;
  1252. size_t SSTRecordIndex_; // shared string table index
  1253. };
  1254. struct MulBlank : public Record
  1255. {
  1256. MulBlank();
  1257. virtual ULONG Read(const char* data);
  1258. virtual ULONG Write(char* data);
  1259. virtual ULONG DataSize();
  1260. virtual ULONG RecordSize();
  1261. USHORT rowIndex_;
  1262. USHORT firstColIndex_;
  1263. vector<USHORT> XFRecordIndices_;
  1264. USHORT lastColIndex_;
  1265. };
  1266. struct MulRK : public Record
  1267. {
  1268. MulRK();
  1269. virtual ULONG Read(const char* data);
  1270. virtual ULONG Write(char* data);
  1271. virtual ULONG DataSize();
  1272. virtual ULONG RecordSize();
  1273. struct XFRK
  1274. {
  1275. XFRK();
  1276. void Read(const char* data);
  1277. void Write(char* data);
  1278. USHORT XFRecordIndex_;
  1279. LONG RKValue_;
  1280. };
  1281. USHORT rowIndex_;
  1282. USHORT firstColIndex_;
  1283. vector<XFRK> XFRK_;
  1284. USHORT lastColIndex_;
  1285. };
  1286. struct Number : public Record
  1287. {
  1288. Number();
  1289. virtual ULONG Read(const char* data);
  1290. virtual ULONG Write(char* data);
  1291. USHORT rowIndex_;
  1292. USHORT colIndex_;
  1293. USHORT XFRecordIndex_;
  1294. double value_;
  1295. private:
  1296. union
  1297. {
  1298. LONGINT intvalue_;
  1299. double doublevalue_;
  1300. } intdouble_;
  1301. };
  1302. struct RK : public Record
  1303. {
  1304. RK();
  1305. virtual ULONG Read(const char* data);
  1306. virtual ULONG Write(char* data);
  1307. USHORT rowIndex_;
  1308. USHORT colIndex_;
  1309. USHORT XFRecordIndex_;
  1310. ULONG value_;
  1311. };
  1312. struct Formula : public Record
  1313. {
  1314. struct Array : public Record
  1315. {
  1316. Array();
  1317. virtual ULONG Read(const char* data);
  1318. virtual ULONG Write(char* data);
  1319. virtual ULONG DataSize();
  1320. virtual ULONG RecordSize();
  1321. USHORT firstRowIndex_;
  1322. USHORT lastRowIndex_;
  1323. BYTE firstColIndex_;
  1324. BYTE lastColIndex_;
  1325. USHORT options_;
  1326. ULONG unused_;
  1327. vector<char> formula_;
  1328. };
  1329. struct ShrFmla : public Record
  1330. {
  1331. ShrFmla();
  1332. virtual ULONG Read(const char* data);
  1333. virtual ULONG Write(char* data);
  1334. virtual ULONG DataSize();
  1335. virtual ULONG RecordSize();
  1336. USHORT firstRowIndex_;
  1337. USHORT lastRowIndex_;
  1338. BYTE firstColIndex_;
  1339. BYTE lastColIndex_;
  1340. USHORT unused_;
  1341. vector<char> formula_;
  1342. };
  1343. struct ShrFmla1 : public Record
  1344. {
  1345. ShrFmla1();
  1346. virtual ULONG Read(const char* data);
  1347. virtual ULONG Write(char* data);
  1348. virtual ULONG DataSize();
  1349. virtual ULONG RecordSize();
  1350. USHORT firstRowIndex_;
  1351. USHORT lastRowIndex_;
  1352. BYTE firstColIndex_;
  1353. BYTE lastColIndex_;
  1354. USHORT unused_;
  1355. vector<char> formula_;
  1356. };
  1357. struct Table : public Record
  1358. {
  1359. Table();
  1360. virtual ULONG Read(const char* data);
  1361. virtual ULONG Write(char* data);
  1362. USHORT firstRowIndex_;
  1363. USHORT lastRowIndex_;
  1364. BYTE firstColIndex_;
  1365. BYTE lastColIndex_;
  1366. USHORT options_;
  1367. USHORT inputCellRowIndex_;
  1368. USHORT inputCellColIndex_;
  1369. USHORT inputCellColumnInputRowIndex_;
  1370. USHORT inputCellColumnInputColIndex_;
  1371. };
  1372. struct String : public Record
  1373. {
  1374. String();
  1375. ~String();
  1376. virtual ULONG Read(const char* data);
  1377. virtual ULONG Write(char* data);
  1378. virtual ULONG DataSize();
  1379. virtual ULONG RecordSize();
  1380. bool empty() {return !wstr_;}
  1381. void Reset();
  1382. char flag_; // 0 = compressed unicode string 1 = uncompressed unicode string
  1383. // From BIFF8 on, strings are always stored using UTF-16LE text encoding, optionally compressed (see compressed field)
  1384. wchar_t* wstr_;
  1385. };
  1386. Formula();
  1387. virtual ULONG Read(const char* data);
  1388. virtual ULONG Write(char* data);
  1389. virtual ULONG DataSize();
  1390. virtual ULONG RecordSize();
  1391. USHORT rowIndex_;
  1392. USHORT colIndex_;
  1393. USHORT XFRecordIndex_;
  1394. BYTE result_[8]; // formula result (IEEE 754 floating-point value, 64-bit double precision or other special values)
  1395. USHORT options_; // 1 = Recalculate always 2 = Calculate on open 8 = Part of a shared formula
  1396. ULONG unused_; // chn field
  1397. vector<char> RPNtoken_; // 2 length bytes, followed by a variable length structure
  1398. USHORT type_;
  1399. Array array_;
  1400. ShrFmla shrfmla_;
  1401. ShrFmla1 shrfmla1_;
  1402. Table table_;
  1403. String string_;
  1404. };
  1405. CellBlock();
  1406. ~CellBlock();
  1407. void Reset();
  1408. void SetType(int type);
  1409. ULONG Read(const char* data);
  1410. ULONG Write(char* data);
  1411. ULONG DataSize();
  1412. ULONG RecordSize();
  1413. USHORT RowIndex();
  1414. USHORT ColIndex();
  1415. USHORT LastColIndex();
  1416. SHORT type_;
  1417. //MF
  1418. union CellBlockUnion {
  1419. void* void_;
  1420. Blank* blank_;
  1421. MulBlank* mulblank_;
  1422. BoolErr* boolerr_;
  1423. LabelSST* labelsst_;
  1424. MulRK* mulrk_;
  1425. Number* number_;
  1426. RK* rk_;
  1427. Formula* formula_;
  1428. } _union;
  1429. };
  1430. struct DBCell : public Record
  1431. {
  1432. DBCell();
  1433. virtual ULONG Read(const char* data);
  1434. virtual ULONG Write(char* data);
  1435. virtual ULONG DataSize();
  1436. virtual ULONG RecordSize();
  1437. ULONG firstRowOffset_;
  1438. vector<USHORT> offsets_;
  1439. };
  1440. ULONG Read(const char* data);
  1441. ULONG Write(char* data);
  1442. ULONG DataSize();
  1443. ULONG RecordSize();
  1444. vector<Row> rows_;
  1445. vector<SmartPtr<CellBlock> > cellBlocks_;
  1446. DBCell dbcell_;
  1447. };
  1448. ULONG Read(const char* data);
  1449. ULONG Write(char* data);
  1450. ULONG DataSize();
  1451. ULONG RecordSize();
  1452. vector<RowBlock> rowBlocks_;
  1453. };
  1454. struct Window2 : public Record
  1455. {
  1456. Window2();
  1457. virtual ULONG Read(const char* data);
  1458. virtual ULONG Write(char* data);
  1459. USHORT options_;
  1460. USHORT firstVisibleRowIndex_;
  1461. USHORT firstVisibleColIndex_;
  1462. USHORT gridLineColourIndex_;
  1463. USHORT unused1_;
  1464. USHORT magnificationFactorPageBreakPreview_;
  1465. USHORT magnificationFactorNormalView_;
  1466. ULONG unused2_;
  1467. };
  1468. struct SCL;
  1469. struct Pane;
  1470. struct Selection;
  1471. struct MergedCells
  1472. {
  1473. struct MergedCell
  1474. {
  1475. MergedCell();
  1476. virtual ULONG Read(const char* data);
  1477. virtual ULONG Write(char* data);
  1478. ULONG DataSize();
  1479. ULONG RecordSize();
  1480. USHORT firstRow_;
  1481. USHORT lastRow_;
  1482. USHORT firstColumn_;
  1483. USHORT lastColumn_;
  1484. };
  1485. ULONG Read(const char* data);
  1486. ULONG Write(char* data);
  1487. ULONG DataSize();
  1488. ULONG RecordSize();
  1489. vector<MergedCell> mergedCellsVector_;
  1490. };
  1491. struct LabelRanges;
  1492. struct ConditionalFormattingTable;
  1493. struct HyperlinkTable;
  1494. struct SheetLayout;
  1495. struct SheetProtection;
  1496. struct RangeProtection;
  1497. ULONG Read(const char* data);
  1498. ULONG Write(char* data);
  1499. ULONG DataSize();
  1500. ULONG RecordSize();
  1501. BOF bof_;
  1502. Index index_;
  1503. ColInfos colinfos_;
  1504. Dimensions dimensions_;
  1505. CellTable cellTable_;
  1506. Window2 window2_;
  1507. MergedCells mergedCells_;
  1508. YEOF eof_;
  1509. };
  1510. double GetDoubleFromRKValue(LONG rkValue); ///< Convert a rk value to a double.
  1511. int GetIntegerFromRKValue(LONG rkValue); ///< Convert a rk value to an integer.
  1512. LONG GetRKValueFromDouble(double value); ///< Convert a double to a rk value.
  1513. LONG GetRKValueFromInteger(int value); ///< Convert an integer to a rk value.
  1514. bool CanStoreAsRKValue(double value); ///< Returns true if the supplied double can be stored as a rk value.
  1515. // Forward declarations
  1516. class BasicExcel;
  1517. class BasicExcelWorksheet;
  1518. class BasicExcelCell;
  1519. /*******************************************************************************************************/
  1520. /* Actual classes to read and write to Excel files */
  1521. /*******************************************************************************************************/
  1522. class BasicExcel
  1523. {
  1524. public:
  1525. BasicExcel();
  1526. BasicExcel(const char* filename);
  1527. ~BasicExcel();
  1528. public: // File functions.
  1529. void New(int sheets=3); ///< Create a new Excel workbook with a given number of spreadsheets (Minimum 1).
  1530. bool Load(const char* filename); ///< Load an Excel workbook from a file.
  1531. bool Load(const wchar_t* filename); ///< Load an Excel workbook from a file.
  1532. bool Save(); ///< Save current Excel workbook to opened file.
  1533. bool SaveAs(const char* filename); ///< Save current Excel workbook to a file.
  1534. bool SaveAs(const wchar_t* filename); ///< Save current Excel workbook to a file.
  1535. void Close();
  1536. public: // Worksheet functions.
  1537. int GetTotalWorkSheets(); ///< Total number of Excel worksheets in current Excel workbook.
  1538. BasicExcelWorksheet* GetWorksheet(int sheetIndex); ///< Get a pointer to an Excel worksheet at the given index. Index starts from 0. Returns 0 if index is invalid.
  1539. BasicExcelWorksheet* GetWorksheet(const char* name); ///< Get a pointer to an Excel worksheet that has given ANSI name. Returns 0 if there is no Excel worksheet with the given name.
  1540. BasicExcelWorksheet* GetWorksheet(const wchar_t* name); ///< Get a pointer to an Excel worksheet that has given Unicode name. Returns 0 if there is no Excel worksheet with the given name.
  1541. BasicExcelWorksheet* AddWorksheet(int sheetIndex=-1); ///< Add a new Excel worksheet to the given index. Name given to worksheet is SheetX, where X is a number which starts from 1. Index starts from 0. Worksheet is added to the last position if sheetIndex == -1. Returns a pointer to the worksheet if successful, 0 if otherwise.
  1542. BasicExcelWorksheet* AddWorksheet(const char* name, int sheetIndex=-1); ///< Add a new Excel worksheet with given ANSI name to the given index. Index starts from 0. Worksheet is added to the last position if sheetIndex == -1. Returns a pointer to the worksheet if successful, 0 if otherwise.
  1543. BasicExcelWorksheet* AddWorksheet(const wchar_t* name, int sheetIndex=-1); ///< Add a new Excel worksheet with given Unicode name to the given index. Index starts from 0. Worksheet is added to the last position if sheetIndex == -1. Returns a pointer to the worksheet if successful, 0 if otherwise.
  1544. bool DeleteWorksheet(int sheetIndex); ///< Delete an Excel worksheet at the given index. Index starts from 0. Returns true if successful, false if otherwise.
  1545. bool DeleteWorksheet(const char* name); ///< Delete an Excel worksheet that has given ANSI name. Returns true if successful, false if otherwise.
  1546. bool DeleteWorksheet(const wchar_t* name); ///< Delete an Excel worksheet that has given Unicode name. Returns true if successful, false if otherwise.
  1547. char* GetAnsiSheetName(int sheetIndex); ///< Get the worksheet name at the given index. Index starts from 0. Returns 0 if name is in Unicode format.
  1548. wchar_t* GetUnicodeSheetName(int sheetIndex); ///< Get the worksheet name at the given index. Index starts from 0. Returns 0 if name is in Ansi format.
  1549. bool GetSheetName(int sheetIndex, char* name); ///< Get the worksheet name at the given index. Index starts from 0. Returns false if name is in Unicode format.
  1550. bool GetSheetName(int sheetIndex, wchar_t* name); ///< Get the worksheet name at the given index. Index starts from 0. Returns false if name is in Ansi format.
  1551. bool RenameWorksheet(int sheetIndex, const char* to); ///< Rename an Excel worksheet at the given index to the given ANSI name. Index starts from 0. Returns true if successful, false if otherwise.
  1552. bool RenameWorksheet(int sheetIndex, const wchar_t* to); ///< Rename an Excel worksheet at the given index to the given Unicode name. Index starts from 0. Returns true if successful, false if otherwise.
  1553. bool RenameWorksheet(const char* from, const char* to); ///< Rename an Excel worksheet that has given ANSI name to another ANSI name. Returns true if successful, false if otherwise.
  1554. bool RenameWorksheet(const wchar_t* from, const wchar_t* to); ///< Rename an Excel worksheet that has given Unicode name to another Unicode name. Returns true if successful, false if otherwise.
  1555. private: // Functions to read and write raw Excel format.
  1556. size_t Read(const char* data, size_t dataSize);
  1557. size_t Write(char* data);
  1558. void AdjustStreamPositions();
  1559. void AdjustBoundSheetBOFPositions();
  1560. void AdjustDBCellPositions();
  1561. void AdjustExtSSTPositions();
  1562. enum {WORKBOOK_GLOBALS=0x0005, VISUAL_BASIC_MODULE=0x0006,
  1563. WORKSHEET=0x0010, CHART=0x0020};
  1564. private: // Internal functions
  1565. void UpdateYExcelWorksheet(); ///< Update yesheets_ using information from worksheets_.
  1566. void UpdateWorksheets(); ///< Update worksheets_ using information from yesheets_.
  1567. public:
  1568. CompoundFile file_; ///< Compound file handler.
  1569. Workbook workbook_; ///< Raw Workbook.
  1570. vector<Worksheet> worksheets_; ///< Raw Worksheets.
  1571. vector<SmartPtr<BasicExcelWorksheet> > yesheets_; ///< Parsed Worksheets.
  1572. };
  1573. class BasicExcelWorksheet : public RefCount::RefCnt
  1574. {
  1575. friend class BasicExcel;
  1576. public:
  1577. BasicExcelWorksheet(BasicExcel* excel, int sheetIndex);
  1578. public: // Worksheet functions
  1579. char* GetAnsiSheetName(); ///< Get the current worksheet name. Returns 0 if name is in Unicode format.
  1580. wchar_t* GetUnicodeSheetName(); ///< Get the current worksheet name. Returns 0 if name is in Ansi format.
  1581. bool GetSheetName(char* name); ///< Get the current worksheet name. Returns false if name is in Unicode format.
  1582. bool GetSheetName(wchar_t* name); ///< Get the current worksheet name. Returns false if name is in Ansi format.
  1583. bool Rename(const char* to); ///< Rename current Excel worksheet to another ANSI name. Returns true if successful, false if otherwise.
  1584. bool Rename(const wchar_t* to); ///< Rename current Excel worksheet to another Unicode name. Returns true if successful, false if otherwise.
  1585. void Print(ostream& os, char delimiter=',', char textQualifier='\0') const; ///< Print entire worksheet to an output stream, separating each column with the defined delimiter and enclosing text using the defined textQualifier. Leave out the textQualifier argument if do not wish to have any text qualifiers.
  1586. public: // Cell functions
  1587. int GetTotalRows() const; ///< Total number of rows in current Excel worksheet.
  1588. int GetTotalCols() const; ///< Total number of columns in current Excel worksheet.
  1589. BasicExcelCell* Cell(int row, int col); ///< Return a pointer to an Excel cell. row and col starts from 0. Returns 0 if row exceeds 65535 or col exceeds 255.
  1590. const BasicExcelCell* Cell(int row, int col) const; ///< Return a pointer to an Excel cell. row and col starts from 0. Returns 0 if row exceeds 65535 or col exceeds 255.
  1591. bool EraseCell(int row, int col); ///< Erase content of a cell. row and col starts from 0. Returns true if successful, false if row or col exceeds range.
  1592. void SetColWidth(const int colindex , const USHORT colwidth);
  1593. USHORT GetColWidth(const int colindex);
  1594. void MergeCells(int row, int col, USHORT rowRange, USHORT colRange);
  1595. private: // Internal functions
  1596. void UpdateCells(); ///< Update cells using information from BasicExcel.worksheets_.
  1597. private:
  1598. BasicExcel* excel_; ///< Pointer to instance of BasicExcel.
  1599. int sheetIndex_; ///< Index of worksheet in workbook.
  1600. int maxRows_; ///< Total number of rows in worksheet.
  1601. int maxCols_; ///< Total number of columns in worksheet.
  1602. vector<vector<BasicExcelCell> > cells_; ///< Cells matrix.
  1603. Worksheet::ColInfos colInfos_; /// used to record column info
  1604. };
  1605. class BasicExcelCell
  1606. {
  1607. public:
  1608. BasicExcelCell();
  1609. enum {UNDEFINED, INT, DOUBLE, STRING, WSTRING, FORMULA/*MF*/};
  1610. int Type() const; ///< Get type of value stored in current Excel cell. Returns one of the above enums.
  1611. bool Get(int& val) const; ///< Get an integer value. Returns false if cell does not contain an integer or a double.
  1612. bool Get(double& val) const; ///< Get a double value. Returns false if cell does not contain a double or an integer.
  1613. size_t GetStringLength() const; ///< Return length of ANSI or Unicode string (excluding null character).
  1614. int GetInteger() const; ///< Get an integer value. Returns 0 if cell does not contain an integer.
  1615. double GetDouble() const; ///< Get a double value. Returns 0.0 if cell does not contain a double.
  1616. const char* GetString() const; ///< Get an ANSI string. Returns 0 if cell does not contain an ANSI string.
  1617. const wchar_t* GetWString() const; ///< Get an Unicode string. Returns 0 if cell does not contain an Unicode string.
  1618. friend ostream& operator<<(ostream& os, const BasicExcelCell& cell); ///< Print cell to output stream. Print a null character if cell is undefined.
  1619. void Set(int val); ///< Set content of current Excel cell to an integer.
  1620. void Set(double val); ///< Set content of current Excel cell to a double.
  1621. void Set(const char* str); ///< Set content of current Excel cell to an ANSI string.
  1622. void Set(const wchar_t* str); ///< Set content of current Excel cell to an Unicode string.
  1623. void SetInteger(int val); ///< Set content of current Excel cell to an integer.
  1624. void SetDouble(double val); ///< Set content of current Excel cell to a double.
  1625. void SetRKValue(int rkValue); ///< Set content of current Excel cell to a double or integer value.
  1626. void SetString(const char* str); ///< Set content of current Excel cell to an ANSI string.
  1627. void SetWString(const wchar_t* str);///< Set content of current Excel cell to an Unicode string.
  1628. void SetFormula(const Worksheet::CellTable::RowBlock::CellBlock::Formula& f);//MF
  1629. int GetXFormatIdx() const {return _xf_idx;} //MF
  1630. void SetXFormatIdx(int xf_idx) {_xf_idx = xf_idx;} //MF
  1631. void SetFormat(const ExcelFormat::CellFormat& fmt); //MF
  1632. void EraseContents(); ///< Erase the content of current Excel cell. Set type to UNDEFINED.
  1633. USHORT GetMergedRows() const {return mergedRows_;}
  1634. USHORT GetMergedColumns() const {return mergedColumns_;}
  1635. void SetMergedRows(USHORT mergedRows) {mergedRows_ = mergedRows;}
  1636. void SetMergedColumns(USHORT mergedColumns) {mergedColumns_ = mergedColumns;}
  1637. private:
  1638. int type_; ///< Type of value stored in current Excel cell. Contains one of the above enums.
  1639. int ival_; ///< Integer value stored in current Excel cell.
  1640. double dval_; ///< Double value stored in current Excel cell.
  1641. vector<char> str_; ///< ANSI string stored in current Excel cell. Include null character.
  1642. vector<wchar_t> wstr_; ///< Unicode string stored in current Excel cell. Include null character.
  1643. USHORT mergedRows_; ///< Number of rows merged to this cell. 1 means only itself.
  1644. USHORT mergedColumns_; ///< Number of columns merged to this cell. 1 means only itself.
  1645. bool Get(char* str) const; ///< Get an ANSI string. Returns false if cell does not contain an ANSI string.
  1646. bool Get(wchar_t* str) const; ///< Get an Unicode string. Returns false if cell does not contain an Unicode string.
  1647. //MF extensions for formating and formulas ...
  1648. int _xf_idx; //MF
  1649. friend class BasicExcel;
  1650. friend class BasicExcelWorksheet; // for Get(w/char*);
  1651. struct Formula : public RefCount::RefCnt
  1652. {
  1653. Formula(const Worksheet::CellTable::RowBlock::CellBlock::Formula& f);
  1654. int _formula_type;
  1655. vector<char> _formula;
  1656. unsigned char _result[8]; // formula result (IEEE 754 floating-point value, 64-bit double precision or other special values)
  1657. std::wstring wstr_; // formula result in case of strings, stored as UTF-16LE string
  1658. std::string str_; // formula result in case of strings, stored as ANSI string
  1659. //shrfmla1_
  1660. USHORT firstRowIndex_;
  1661. USHORT lastRowIndex_;
  1662. char firstColIndex_;
  1663. char lastColIndex_;
  1664. USHORT unused_;
  1665. vector<char> shrformula_;
  1666. };
  1667. SmartPtr<Formula> _pFormula;
  1668. bool get_formula(Worksheet::CellTable::RowBlock::CellBlock* pCell) const;
  1669. };
  1670. } // namespace YExcel
  1671. #endif