封裝 MFC ODBC 操作 Excel,提供類似資料庫的 Sheet/Cell 操作接口,要求:同列數據類型一致、單元格格式為「常規」、純數值前加 ' 強制文本。
class CODBCExcel; // Excel 文件
class CODBCExcelSheet; // 工作表
class CODBCExcelCell; // 單元格
class CODBCExcel {
friend class CODBCExcelSheet;
public:
CODBCExcel(); ~CODBCExcel();
bool Open(const CString& strFileName); // 打開/創建
bool Save(); // 統一保存所有修改
void Close();
CODBCExcelSheet* GetWorkSheet(const CString& name); // 讀取現有
CODBCExcelSheet* AddWorkSheet(const CString& name, const CStringArray& headers); // 新建
void DeleteWorkSheet(const CString& name);
protected:
static CString GetExcelDriver(); // 查找已安裝 Excel ODBC 驅動
private:
std::map<CString, CODBCExcelSheet*> m_Sheets; // 快取
std::vector<CString> m_DeleteSheets; // 待刪除
CDatabase m_db; // ODBC 連接
};
class CODBCExcelSheet {
friend class CODBCExcel; friend class CODBCExcelCell;
enum Flag { Exist, Update, Add, Delete };
public:
CODBCExcelSheet(CODBCExcel& excel, const CString& name);
CODBCExcelCell* Cell(UINT row, UINT col); // 0-based 索引
CODBCExcelCell* Cell(UINT row, const CString& colName); // 列名索引
const CStringArray& GetColHeader() const;
int GetColHeader(const CString& name) const; // 列名→索引
int GetRow(const CString& col, const CString& text) const; // 查找行
DWORD GetTotalRow() const; DWORD GetTotalCol() const;
const CString& GetName() const;
protected:
bool Init(); // 從 Recordset 載入數據到快取
void UpdateRowCount(); // 修剪尾部空行
bool UpdateCells(); // 快取→資料庫寫入
void ResetCells(); // 清空快取(刪除表用)
bool Save(); // 根據 Flag 執行 DROP/CREATE/INSERT
private:
CRecordset m_recordset;
CStringArray m_ColHeaders;
DWORD m_dwRows, m_dwCols;
CString m_strName;
int m_nFlag;
CODBCExcel& m_Excel;
std::vector<std::vector<CODBCExcelCell>> m_Cells; // 內存快取
};
class CODBCExcelCell {
friend class CODBCExcelSheet;
public:
CODBCExcelCell();
void Set(short v); void Set(long v); void Set(float v); void Set(double v); void Set(const CString& v);
CString& GetText();
short GetShort() const; long GetLong() const;
float GetFloat() const; double GetDouble() const;
void Empty();
protected:
void Set(const CDBVariant& dbVal); // 從 ODBC 變體賦值
void SetParent(CODBCExcelSheet* s) { m_Sheet = s; }
CODBCExcelSheet* m_Sheet;
private:
CString m_strVal; // 統一以文本存儲
};
m_Cells,修改只標記 Flag,Save() 時批量 DROP/CREATE/INSERT,減少 ODBC 往返。CODBCExcelCell::m_strVal 統一用 CString,避免類型轉換麻煩,讀取時按需轉 short/long/float/double。GetExcelDriver() 遍歷 SQLGetInstalledDrivers 找含 "Excel" 的驅動,適配不同 Office 版本。CDatabase/CRecordset/CString/CDBVariant,需 MFC 動態/靜態鏈接。CODBCExcel excel;
if (excel.Open("data.xlsx")) {
CODBCExcelSheet* sh = excel.GetWorkSheet("Sheet1");
if (sh) {
sh->Cell(0, "Name")->Set("張三");
sh->Cell(0, "Age")->Set(25);
excel.Save();
}
excel.Close();
}