首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

基於 ODBC 的 Excel 讀寫類設計(一):頭文件架構解析

     編輯:關於C語言

設計目標

封裝 MFC ODBC 操作 Excel,提供類似資料庫的 Sheet/Cell 操作接口,要求:同列數據類型一致、單元格格式為「常規」、純數值前加 ' 強制文本。

核心類結構

class CODBCExcel;       // Excel 文件
class CODBCExcelSheet;  // 工作表
class CODBCExcelCell;   // 單元格

CODBCExcel:文件級管理

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 連接
};

CODBCExcelSheet:工作表操作

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; // 內存快取
};

CODBCExcelCell:單元格數據封裝

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; // 統一以文本存儲
};

關鍵設計決策

  1. 三層架構:文件→表→儲存格,職責清晰,符合 Excel 邏輯模型。
  2. 內存快取 + 延遲寫入:讀取時全量載入 m_Cells,修改只標記 Flag,Save() 時批量 DROP/CREATE/INSERT,減少 ODBC 往返。
  3. 統一文本存儲:CODBCExcelCell::m_strVal 統一用 CString,避免類型轉換麻煩,讀取時按需轉 short/long/float/double。
  4. 驅動自動探測:GetExcelDriver() 遍歷 SQLGetInstalledDrivers 找含 "Excel" 的驅動,適配不同 Office 版本。
  5. MFC 依賴:使用 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();
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved