⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basicexcelvc6.hpp

📁 对EXCEL的操作
💻 HPP
📖 第 1 页 / 共 3 页
字号:
// 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.

#ifndef BASICEXCEL_HPP
#define BASICEXCEL_HPP

#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <map>
#include <vector>
using namespace std;

#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, ios_base::openmode mode=ios_base::in | 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(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:
	vector<char> filename_;
	ios_base::openmode mode_;
	fstream file_;
	size_t blockSize_;
	size_t indexEnd_;
	size_t fileSize_;
};

struct LittleEndian
{
	#define READWRITE(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<bytes; ++i)	\
		{	\
			retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;	\
		}	\
	}	\
	static void ReadString(const char* buffer, Type* str, int pos=0, int bytes=0)	\
	{	\
		for (size_t i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*sizeof(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<bytes; ++i)	\
		{	\
			buffer[pos+i] = (unsigned char)val;	\
			val >>= 8;	\
		}	\
	}	\
	static void WriteString(char* buffer, Type* str, int pos=0, int bytes=0)	\
	{	\
		for (size_t i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type));	\
	}	\
	static void Read(const 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<bytes; ++i)	\
		{	\
			retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;	\
		}	\
	}	\
	static void ReadString(const vector<char>& buffer, Type* str, int pos=0, int bytes=0)	\
	{	\
		for (size_t i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*sizeof(Type));	\
	}	\
	static void Write(vector<char>& buffer, Type val, int pos=0, int bytes=0)	\
	{	\
		if (bytes == 0) bytes = sizeof(Type);	\
		for (size_t i=0; i<bytes; ++i)	\
		{	\
			buffer[pos+i] = (unsigned char)val;	\
			val >>= 8;	\
		}	\
	}	\
	static void WriteString(vector<char>& buffer, Type* str, int pos=0, int bytes=0)	\
	{	\
		for (size_t i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*sizeof(Type));	\
	}	\

	READWRITE(char)
	READWRITE(unsigned char)
	READWRITE(short)
	READWRITE(int)
	READWRITE(unsigned int)
	READWRITE(long)
	READWRITE(unsigned long)
	READWRITE(__int64)
	READWRITE(unsigned __int64)

	#undef READWRITE


	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 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 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(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(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, ios_base::openmode mode=ios_base::in | 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(vector<wchar_t>& path);
	int RemoveDirectory(const wchar_t* path);
	int DelTree(const wchar_t* path);
	int DirectoryList(vector<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, vector<char>&data);
	int WriteFile(const wchar_t* path, const char* data, size_t size);
	int WriteFile(const wchar_t* path, const vector<char>&data, size_t size);


	// ANSI char functions
	bool Create(const char* filename);
	bool Open(const char* filename, ios_base::openmode mode=ios_base::in | ios_base::out);
	int ChangeDirectory(const char* path);
	int MakeDirectory(const char* path);
	int PresentWorkingDirectory(char* path);
	int PresentWorkingDirectory(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, vector<char>& data);
	int WriteFile(const char* path, char* data, size_t size);
	int WriteFile(const char* path, vector<char>& data, size_t size);

// Protected functions and data members
protected:
	// General functions and data members
	void IncreaseLocationReferences(vector<size_t> indices);
	void DecreaseLocationReferences(vector<size_t> indices);
	void SplitPath(const wchar_t* path, wchar_t*& parentpath, wchar_t*& propertyname);
	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);

		__int64 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, 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(vector<size_t>& indices, bool isBig);
	vector<int> blocksIndices_;
	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 Property& lhs, const Property& rhs) 
		{
			return (!wcscmp(lhs.name_, rhs.name_));
		}
		friend bool operator< (const Property& lhs, const 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 Property& lhs, const Property& rhs) {return !(lhs == rhs);}
		friend bool operator> (const Property& lhs, const Property& rhs) {return (rhs < lhs);}
		friend bool operator<=(const Property& lhs, const Property& rhs) {return !(rhs < lhs);}
		friend bool operator>=(const Property& lhs, const 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_;
		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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -