最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt利用QXlsx庫操作Excel表格的應用全解析

 更新時間:2025年10月27日 09:33:22   作者:牽牛老人  
這篇文章主要為大家系統(tǒng)梳理了 Qt 生態(tài)中幾種主流 Excel 操作方案,例如QXlsx、QAxObject、LibXL、ODBC,有需要的小伙伴可以跟隨小編一起學習一下

前言

在 Qt 應用開發(fā)中,“數(shù)據(jù)導出為表格”“讀取 Excel 數(shù)據(jù)進行分析” 是高頻需求 —— 從管理系統(tǒng)的報表生成,到科研工具的數(shù)據(jù)整理,再到工業(yè)軟件的日志歸檔,幾乎都離不開 Excel 交互。但 Qt 原生并未提供 Excel 操作模塊,因此選擇合適的開源庫成為關鍵。

本文將系統(tǒng)梳理 Qt 生態(tài)中幾種主流 Excel 操作方案(QXlsx、QAxObject、LibXL、ODBC),對比其核心差異與適用場景;并以跨平臺、無依賴、輕量級的 QXlsx開源庫 為核心,實現(xiàn) Excel 的 “創(chuàng)建 - 讀寫 - 格式美化” 全流程。

一、Qt 操作 Excel 的 4 種主流方案對比

在選擇 Excel 操作庫前,需先明確項目的核心約束:是否需要跨平臺?是否依賴本地 Excel 安裝?是否需要格式控制或公式計算?不同庫的設計理念差異極大,選錯方案可能導致后期重構成本飆升。以下是 4 種主流方案的深度解析:

1. QXlsx(推薦)

簡介:QXlsx 是一個輕量級開源庫(MIT 協(xié)議),基于 Qt 框架實現(xiàn),無需依賴 Microsoft Excel 或其他第三方軟件,純 C++ 實現(xiàn) Excel 文件(.xlsx)的讀寫和格式控制。它是從早期的QtXlsxWriter fork 而來,目前維護活躍,兼容性更好。

特點

  • 支持 .xlsx 格式(不支持舊版 .xls);
  • 跨平臺(Windows、Linux、macOS),無需安裝 Excel;
  • 提供豐富的 API:單元格讀寫、合并單元格、字體 / 顏色 / 對齊方式設置、圖表、批注等;
  • 輕量,可直接將源碼集成到項目(無需預編譯庫)。

優(yōu)缺點

  • 優(yōu)點:跨平臺性強、無外部依賴、集成簡單、功能滿足大多數(shù)場景;
  • 缺點:不支持 .xls 格式,復雜圖表或高級 Excel 功能(如宏、公式計算)支持有限。
  • 適用場景:跨平臺項目、無需依賴 Excel 環(huán)境、需要基本 Excel 讀寫和格式控制的場景(如數(shù)據(jù)導出、簡單報表生成)。

2. QAxObject(Qt 自帶,非純開源庫)

簡介:QAxObject 是 Qt 提供的 ActiveX 組件交互類,通過調(diào)用 Windows 系統(tǒng)中的 Excel COM 接口操作 Excel 文件。它本身是 Qt 的一部分,無需額外下載,但依賴 Windows 系統(tǒng)和本地安裝的 Excel。

特點

  • 支持 .xls 和 .xlsx 格式,可調(diào)用 Excel 的全部功能(包括宏、公式計算、高級圖表等);
  • 本質(zhì)是 “操控本地 Excel 程序”,操作方式與 VBA 類似。

優(yōu)缺點

  • 優(yōu)點:功能完整(Excel 能做的它都能做),無需額外學習新 API(可參考 VBA 語法);
  • 缺點:僅支持 Windows 平臺,必須安裝 Excel,操作速度較慢(依賴 Excel 進程),跨平臺項目無法使用。

適用場景:僅限 Windows 平臺、需要使用 Excel 高級功能(如宏、復雜公式)、允許依賴本地 Excel 安裝的場景。

3. LibXL(半開源,免費版有限制)

簡介:LibXL 是一個跨平臺的 Excel 操作庫(C/C++),提供 Qt 綁定,支持 .xls 和 .xlsx 格式。它分為免費版和商業(yè)版,免費版有功能限制(如無法隱藏水印、最多處理 100 行數(shù)據(jù))。

特點

  • 跨平臺(Windows、Linux、macOS),無需依賴 Excel;
  • 支持豐富的格式控制(字體、顏色、邊框、合并單元格等),支持公式計算和圖表;
  • 性能較好,比 QXlsx 處理大數(shù)據(jù)時更快。

優(yōu)缺點

  • 優(yōu)點:支持 .xls 和 .xlsx,性能強,功能豐富;
  • 缺點:免費版有功能限制,商業(yè)使用需要購買授權(價格較高)。
  • 適用場景:需要處理 .xls 格式、對性能要求高、可接受商業(yè)授權的項目。

4. ODBC 接口(通過 QSqlDatabase)

簡介:ODBC(開放數(shù)據(jù)庫連接)是一種通用數(shù)據(jù)庫接口,可將 Excel 文件視為 “數(shù)據(jù)庫”,通過 Qt 的 QSqlDatabase 進行讀寫(需配置 Excel ODBC 驅(qū)動)。
 

特點

  • 跨平臺(需安裝對應平臺的 Excel ODBC 驅(qū)動);
  • 操作方式類似數(shù)據(jù)庫(通過 SQL 語句讀寫單元格數(shù)據(jù))。

優(yōu)缺點

  • 優(yōu)點:無需依賴 Excel,可跨平臺,適合簡單數(shù)據(jù)讀寫;
  • 缺點:不支持格式控制(如字體、顏色),無法處理合并單元格、圖表等,配置驅(qū)動較繁瑣(尤其非 Windows 平臺)。
  • 適用場景:僅需簡單讀寫 Excel 數(shù)據(jù)(無需格式)、可接受繁瑣配置的跨平臺項目。

總結與選擇建議

庫 / 方式跨平臺依賴 Excel支持格式功能豐富度開源 / 免費推薦場景
QXlsx.xlsx中(夠用)完全開源(MIT)跨平臺、基本 Excel 操作
QAxObject否(僅 Windows).xls/.xlsx高(完整)免費(Qt 自帶)Windows 平臺、高級 Excel 功能
LibXL.xls/.xlsx免費版有限制需.xls 格式、高性能、商業(yè)授權
ODBC是(需驅(qū)動).xls/.xlsx低(僅數(shù)據(jù))免費簡單數(shù)據(jù)讀寫、跨平臺

二、QXlsx 庫實際應用:從環(huán)境搭建到核心功能

通過上一部分的對比,不難發(fā)現(xiàn) QXlsx 是 “跨平臺、無依賴、功能均衡” 的最優(yōu)解,也是大多數(shù) Qt 項目的首選。本節(jié)將從環(huán)境搭建→基礎操作→進階功能→實戰(zhàn)案例,完整覆蓋 QXlsx 的使用流程。

2.1 QXlsx 環(huán)境搭建:兩種集成方式(源碼 / 靜態(tài)庫)

QXlsx 的集成方式靈活,推薦新手使用 “源碼直接集成”(無需編譯庫,開箱即用),大型項目可選擇 “編譯靜態(tài)庫”(減少編譯時間,便于多項目復用)。

方式 1:源碼直接集成(推薦新手)

步驟 1:獲取 QXlsx 源碼

GitHub 地址:https://github.com/QtExcel/QXlsx

解壓后,核心源碼在QXlsx/src目錄下(包含 20 多個.cpp 和.h 文件,如xlsxworkbook.h、xlsxworksheet.cpp)。

步驟 2:項目結構規(guī)劃

建議將 QXlsx 源碼放在項目的 “第三方庫” 目錄下,保持項目結構清晰。如下:

步驟 3:配置.pro 文件

在項目的.pro文件中,添加 QXlsx 的頭文件路徑和源碼文件,確保編譯器能找到并編譯 QXlsx 代碼。

Qt 5/.pro 配置示例:

#excel制作庫
include($$PWD/QXlsx/QXlsx.pri)

然后工程中就有了QXlsx的文件結構:

步驟 4:驗證集成是否成功

在main.cpp中引入 QXlsx 頭文件,編譯項目。若無 “頭文件找不到”“未定義符號” 錯誤,說明集成成功:

#include <QApplication>
#include "thirdparty/qxlsx/src/xlsxworkbook.h"  // 引入QXlsx頭文件

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    // 嘗試創(chuàng)建工作簿,驗證集成
    QXlsx::Workbook workbook;
    qDebug() << "QXlsx集成成功!";

    return a.exec();
}

方式 2:編譯靜態(tài)庫(適合多項目復用)

若多個項目需使用 QXlsx,直接集成源碼會導致重復編譯,可將 QXlsx 編譯為靜態(tài)庫(.a/.lib),供所有項目鏈接使用。

步驟 1:創(chuàng)建 QXlsx 靜態(tài)庫項目

打開 Qt Creator,新建 “Library”→“C++ Library” 項目,類型選擇 “Static Library”;

項目名稱設為 “QXlsxLib”,保存路徑自定義;

將 QXlsx 源碼的src目錄復制到項目根目錄,刪除默認生成的qxlsxlibrary.cpp和qxlsxlibrary.h。

步驟 2:配置靜態(tài)庫項目的.pro

QT += core widgets
TARGET = QXlsxLib  # 靜態(tài)庫名稱
TEMPLATE = lib
CONFIG += staticlib  # 指定為靜態(tài)庫

# 頭文件路徑
INCLUDEPATH += $$PWD/src

# 添加所有QXlsx源碼(同方式1的SOURCES和HEADERS)
SOURCES += \
    $$PWD/src/xlsxabstractooxmlfile.cpp \
    ...(省略其他.cpp文件,同方式1)

HEADERS += \
    $$PWD/src/xlsxabstractooxmlfile.h \
    ...(省略其他.h文件,同方式1)

# Qt 6專屬配置
DEFINES += QXLSX_QT6

步驟 3:編譯靜態(tài)庫

  • 選擇對應的編譯器(如 MinGW 64-bit、MSVC 2019),點擊 “構建”,生成靜態(tài)庫文件:
  • Windows(MinGW):生成libQXlsxLib.a;
  • Windows(MSVC):生成QXlsxLib.lib;
  • Linux:生成libQXlsxLib.a;
  • macOS:生成libQXlsxLib.a。

步驟 4:在目標項目中鏈接靜態(tài)庫

在需要使用 QXlsx 的項目的.pro中,添加靜態(tài)庫的路徑和鏈接配置:

QT += core widgets

# 1. 頭文件路徑(指向QXlsx的src目錄)
INCLUDEPATH += $$PWD/../QXlsxLib/src  # 需根據(jù)實際路徑調(diào)整

# 2. 靜態(tài)庫路徑(指向生成的.a/.lib文件所在目錄)
LIBS += -L$$PWD/../QXlsxLib/build-QXlsxLib-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/lib \
        -lQXlsxLib  # 鏈接靜態(tài)庫(MinGW用-lxxx,MSVC直接寫xxx.lib)

# Qt 6專屬配置
DEFINES += QXLSX_QT6

2.2 QXlsx 核心概念:3 個關鍵類

QXlsx 的 API 設計遵循 “Excel 對象模型”,核心邏輯圍繞 3 個類展開,理解它們的關系是使用 QXlsx 的基礎:

類名對應 Excel 概念核心作用
QXlsx::Workbook工作簿代表整個 Excel 文件,負責創(chuàng)建 / 加載 / 保存文件
QXlsx::Worksheet工作表代表 Excel 中的一個工作表,負責單元格操作
QXlsx::Format單元格格式定義單元格的樣式(字體、顏色、對齊等)

2.3 QXlsx 基礎操作:從創(chuàng)建到保存

接下來介紹 Excel 最常用的基礎功能:創(chuàng)建工作簿、新建工作表、寫入 / 讀取單元格數(shù)據(jù)、格式設置、合并單元格、列寬行高調(diào)整,所有代碼均附帶詳細注釋。

示例 1:創(chuàng)建 Excel 文件并寫入基礎數(shù)據(jù)

目標:創(chuàng)建一個包含 “學生成績表” 的 Excel 文件,包含標題行和 2 條數(shù)據(jù),設置標題格式,調(diào)整列寬。

#include <QApplication>
#include <QDebug>
#include "thirdparty/qxlsx/src/xlsxworkbook.h"
#include "thirdparty/qxlsx/src/xlsxworksheet.h"
#include "thirdparty/qxlsx/src/xlsxformat.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    // 1. 創(chuàng)建工作簿(Workbook):代表整個Excel文件
    QXlsx::Workbook workbook;

    // 2. 新建工作表(Worksheet):默認工作表名為“Sheet1”,可自定義
    QXlsx::Worksheet *sheet = workbook.addSheet("學生成績表");  // 新建名為“學生成績表”的工作表
    // 若需獲取默認工作表,可使用:QXlsx::Worksheet *sheet = workbook.activeSheet();

    // 3. 創(chuàng)建格式(Format):定義標題單元格的樣式
    QXlsx::Format titleFormat;
    titleFormat.setFontBold(true);                          // 字體加粗
    titleFormat.setFontSize(14);                            // 字體大小14號
    titleFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter);  // 水平居中
    titleFormat.setVerticalAlignment(QXlsx::Format::AlignVCenter);    // 垂直居中
    titleFormat.setFillColor(QColor(230, 240, 255));         // 背景色(淡藍色)
    titleFormat.setBorderStyle(QXlsx::Format::BorderThin);   // 邊框:細線條
    titleFormat.setBorderColor(QColor(100, 100, 100));       // 邊框顏色(深灰色)

    // 4. 創(chuàng)建數(shù)據(jù)格式:定義數(shù)據(jù)單元格的樣式
    QXlsx::Format dataFormat;
    dataFormat.setFontSize(12);                             // 字體大小12號
    dataFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter);  // 水平居中
    dataFormat.setBorderStyle(QXlsx::Format::BorderThin);   // 邊框
    dataFormat.setBorderColor(QColor(100, 100, 100));       // 邊框顏色

    // 5. 寫入單元格數(shù)據(jù):支持“單元格坐標”(如"A1")或“行號+列號”(行/列從1開始)
    // 寫入標題行(應用標題格式)
    sheet->write("A1", "學號", titleFormat);  // A1單元格:學號
    sheet->write("B1", "姓名", titleFormat);  // B1單元格:姓名
    sheet->write("C1", "數(shù)學", titleFormat);  // C1單元格:數(shù)學
    sheet->write("D1", "英語", titleFormat);  // D1單元格:英語
    sheet->write("E1", "總分", titleFormat);  // E1單元格:總分

    // 寫入數(shù)據(jù)行(應用數(shù)據(jù)格式)
    sheet->write(2, 1, "2023001", dataFormat);  // 第2行第1列(A2):學號
    sheet->write(2, 2, "張三", dataFormat);     // 第2行第2列(B2):姓名
    sheet->write(2, 3, 95, dataFormat);        // 第2行第3列(C2):數(shù)學成績
    sheet->write(2, 4, 88, dataFormat);        // 第2行第4列(D2):英語成績
    sheet->write(2, 5, "=C2+D2", dataFormat);  // 第2行第5列(E2):總分(公式)

    sheet->write(3, 1, "2023002", dataFormat);  // A3:學號
    sheet->write(3, 2, "李四", dataFormat);     // B3:姓名
    sheet->write(3, 3, 78, dataFormat);        // C3:數(shù)學成績
    sheet->write(3, 4, 92, dataFormat);        // D3:英語成績
    sheet->write(3, 5, "=C3+D3", dataFormat);  // E3:總分(公式)

    // 6. 調(diào)整列寬和行高
    sheet->setColumnWidth(1, 12);  // 第1列(A列)寬度12
    sheet->setColumnWidth(2, 10);  // 第2列(B列)寬度10
    sheet->setColumnWidth(3, 8);   // 第3列(C列)寬度8
    sheet->setColumnWidth(4, 8);   // 第4列(D列)寬度8
    sheet->setColumnWidth(5, 8);   // 第5列(E列)寬度8
    sheet->setRowHeight(1, 25);    // 第1行(標題行)高度25

    // 7. 保存Excel文件
    // 保存路徑:默認在項目的構建目錄下(如build-MyExcelProject-.../debug)
    QString savePath = QCoreApplication::applicationDirPath() + "/學生成績表.xlsx";
    bool saveSuccess = workbook.saveAs(savePath);

    if (saveSuccess) {
        qDebug() << "Excel文件保存成功!路徑:" << savePath;
    } else {
        qDebug() << "Excel文件保存失敗!請檢查路徑權限。";
    }

    return a.exec();
}

運行結果:生成的 Excel 文件中,標題行呈淡藍色、粗體居中,數(shù)據(jù)行帶邊框,總分列自動計算結果,列寬行高適配內(nèi)容,整體樣式整潔。

示例 2:讀取已有的 Excel 文件數(shù)據(jù)

目標:讀取上一步生成的 “學生成績表.xlsx”,提取所有數(shù)據(jù)并打印到控制臺。

#include <QApplication>
#include <QDebug>
#include "thirdparty/qxlsx/src/xlsxworkbook.h"
#include "thirdparty/qxlsx/src/xlsxworksheet.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    // 1. 定義Excel文件路徑(需與保存路徑一致)
    QString filePath = QCoreApplication::applicationDirPath() + "/學生成績表.xlsx";

    // 2. 創(chuàng)建工作簿并加載文件
    QXlsx::Workbook workbook;
    bool loadSuccess = workbook.load(filePath);
    if (!loadSuccess) {
        qDebug() << "Excel文件加載失??!請檢查路徑是否正確。";
        return -1;
    }

    // 3. 獲取目標工作表(通過工作表名稱)
    QXlsx::Worksheet *sheet = workbook.sheet("學生成績表");
    if (!sheet) {
        qDebug() << "未找到名為“學生成績表”的工作表!";
        return -1;
    }

    // 4. 獲取數(shù)據(jù)范圍:確定表格的行數(shù)和列數(shù)(避免遍歷空單元格)
    // 方法:獲取最后一個非空行和最后一個非空列
    int lastRow = sheet->dimension().lastRow();    // 最后一行(示例中為3)
    int lastCol = sheet->dimension().lastColumn();// 最后一列(示例中為5)
    qDebug() << "數(shù)據(jù)范圍:" << lastRow << "行," << lastCol << "列";

    // 5. 遍歷所有單元格,讀取數(shù)據(jù)
    qDebug() << "\n讀取到的Excel數(shù)據(jù):";
    for (int row = 1; row <= lastRow; ++row) {  // 行從1開始
        QString rowData;
        for (int col = 1; col <= lastCol; ++col) {  // 列從1開始
            // 讀取單元格數(shù)據(jù)(返回QVariant,需根據(jù)實際類型轉(zhuǎn)換)
            QVariant cellValue = sheet->read(row, col);
            // 將數(shù)據(jù)拼接為字符串(處理數(shù)字、文本、公式結果)
            if (cellValue.isValid()) {
                rowData += cellValue.toString() + "\t";
            } else {
                rowData += "空\t";
            }
        }
        qDebug() << rowData;
    }

    return a.exec();
}

2.4 QXlsx 常見問題與解決方案

在實際開發(fā)中,使用 QXlsx 可能遇到編譯錯誤、中文亂碼、大數(shù)據(jù)處理緩慢等問題,以下是高頻問題的解決方案:

(1)編譯錯誤:“找不到 xlsxworkbook.h” 或 “未定義符號”

問題原因:

  • 頭文件路徑配置錯誤,編譯器無法定位 QXlsx 源碼;
  • .pro文件中遺漏部分.cpp文件,導致鏈接時缺少符號。

解決方案:

  • 檢查INCLUDEPATH:確保路徑指向 QXlsx 的src目錄,且路徑格式正確(Qt 中用“$$PWD”表示項目根目錄,如$$PWD/thirdparty/qxlsx/src);
  • 核對SOURCES列表:打開src目錄,確認所有.cpp文件均已添加到.pro的SOURCES中(可按文件名排序逐一核對,避免遺漏xlsxchart_p.cpp等隱藏后綴文件);
  • 清理項目后重新編譯:Qt Creator 中點擊「項目」→「清理項目」,再點擊「構建」,避免舊編譯緩存干擾。

(2)中文亂碼:Excel 中中文顯示為 “???”

問題原因:

QXlsx 默認使用 UTF-8 編碼,但 Excel 打開文件時可能默認使用 GBK 編碼,導致編碼不匹配;

字符串未指定編碼格式,Qt 中默認字符串為 UTF-16,寫入 Excel 時未正確轉(zhuǎn)換。

解決方案:

  • 確保字符串編碼統(tǒng)一:在寫入中文前,將字符串轉(zhuǎn)換為 UTF-8 格式(如QString(“員工信息”).toUtf8());
  • 強制 Excel 使用 UTF-8 編碼:在保存文件前,添加編碼設置(需修改 QXlsx 源碼):
  • 打開src/xlsxsharedstrings.cpp,找到write()函數(shù),在xmlWriter.writeStartElement(“sst”)后添加:
xmlWriter.writeAttribute("xml:lang", "zh-CN");
xmlWriter.writeAttribute("encoding", "UTF-8");

用 WPS 打開驗證:若 Microsoft Excel 仍亂碼,嘗試用 WPS 打開(WPS 對 UTF-8 兼容性更好),或在 Excel 中手動設置編碼(「數(shù)據(jù)」→「獲取外部數(shù)據(jù)」→「從文本 / CSV」→選擇 UTF-8)。

(3)大數(shù)據(jù)處理:10 萬行數(shù)據(jù)寫入后內(nèi)存溢出或卡頓

問題原因:

QXlsx 默認將所有單元格數(shù)據(jù)存入內(nèi)存,大數(shù)據(jù)量時占用內(nèi)存過高(10 萬行 ×10 列約占用 100MB + 內(nèi)存);

一次性寫入所有數(shù)據(jù),未分塊處理,導致主線程阻塞。

解決方案:

分塊寫入數(shù)據(jù):每寫入 1000 行數(shù)據(jù),調(diào)用QCoreApplication::processEvents()釋放主線程,避免卡頓:

for (int i = 0; i < 100000; ++i) {
    sheet->write(i+3, 1, QString("員工%1").arg(i));
    sheet->write(i+3, 2, "技術部");
    // ... 其他列數(shù)據(jù) ...

    // 每1000行釋放一次事件循環(huán)
    if (i % 1000 == 0) {
        QCoreApplication::processEvents();
    }
}

禁用不必要的格式:大數(shù)據(jù)場景下,減少Format對象創(chuàng)建(如復用同一個dataFormat,而非每行創(chuàng)建新對象),格式越簡單,寫入速度越快;

使用QXlsx::Worksheet::writeArray()批量寫入:對于二維數(shù)組數(shù)據(jù),優(yōu)先使用writeArray()(底層優(yōu)化了 IO 操作),比循環(huán)write()快:

// 示例:批量寫入1000行2列數(shù)據(jù)
QVector<QVector<QVariant>> data(1000, QVector<QVariant>(2));
for (int i = 0; i < 1000; ++i) {
    data[i][0] = QString("員工%1").arg(i);
    data[i][1] = 20000 + qRand() % 10000;
}
sheet->writeArray("A3", data, dataFormat);  // 從A3開始寫入二維數(shù)組

(4)保存失敗:“saveAs () 返回 false”

問題原因:

  • 保存路徑不存在(如指定 “C:\ 未創(chuàng)建的文件夾 \test.xlsx”);
  • 文件被占用(如 Excel 已打開該文件,導致寫入權限不足);
  • 磁盤空間不足或權限不夠(如 Linux 下無寫入當前目錄的權限)。

解決方案:

檢查路徑合法性:用QDir確保保存目錄存在,不存在則創(chuàng)建:

QString saveDir = QCoreApplication::applicationDirPath() + "/reports";
QDir dir(saveDir);
if (!dir.exists()) {
    dir.mkpath(saveDir);  // 創(chuàng)建目錄(包括父目錄)
}
QString savePath = saveDir + "/員工信息報表.xlsx";

釋放文件占用:提示用戶關閉已打開的 Excel 文件,或在保存前檢查文件是否被占用:

QFile file(savePath);
if (file.isOpen()) {
    file.close();
}
if (file.exists() && !file.remove()) {  // 若文件已存在,嘗試刪除舊文件
    qDebug() << "舊文件被占用,無法覆蓋!";
    return false;
}

檢查權限:Linux/macOS 下,用dir.permissions()檢查目錄是否有寫入權限,必要時用sudo運行程序測試。

2.7 QXlsx 擴展使用技巧

除了基礎和進階功能,QXlsx 還可通過一些技巧滿足更復雜的需求,提升開發(fā)效率:

(1)批量處理:讀取 Excel 文件并導入數(shù)據(jù)庫

在實際項目中,常需將 Excel 中的數(shù)據(jù)導入到 MySQL、SQLite 等數(shù)據(jù)庫,可結合 Qt 的QSqlDatabase實現(xiàn):

// 示例:讀取Excel數(shù)據(jù)并插入SQLite數(shù)據(jù)庫
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>

bool importExcelToDb(const QString &excelPath, const QString &dbPath) {
    // 1. 加載Excel文件
    QXlsx::Workbook workbook;
    if (!workbook.load(excelPath)) {
        qDebug() << "Excel加載失?。?;
        return false;
    }
    QXlsx::Worksheet *sheet = workbook.sheet("員工信息表");
    if (!sheet) return false;

    // 2. 連接SQLite數(shù)據(jù)庫
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(dbPath);
    if (!db.open()) {
        qDebug() << "數(shù)據(jù)庫連接失?。? << db.lastError().text();
        return false;
    }

    // 3. 創(chuàng)建表(若不存在)
    QSqlQuery query;
    QString createTableSql = "CREATE TABLE IF NOT EXISTS employee ("
                            "id INTEGER PRIMARY KEY AUTOINCREMENT,"
                            "name TEXT,"
                            "dept TEXT,"
                            "job TEXT,"
                            "salary REAL)";
    if (!query.exec(createTableSql)) {
        qDebug() << "創(chuàng)建表失?。? << query.lastError().text();
        return false;
    }

    // 4. 讀取Excel數(shù)據(jù)并插入數(shù)據(jù)庫
    int lastRow = sheet->dimension().lastRow();
    for (int row = 3; row <= lastRow; ++row) {  // 從第3行(數(shù)據(jù)行)開始
        QString name = sheet->read(row, 1).toString();
        QString dept = sheet->read(row, 2).toString();
        QString job = sheet->read(row, 3).toString();
        double salary = sheet->read(row, 4).toDouble();

        // 插入SQL
        QString insertSql = QString("INSERT INTO employee (name, dept, job, salary) "
                                    "VALUES ('%1', '%2', '%3', %4)")
                            .arg(name).arg(dept).arg(job).arg(salary);
        if (!query.exec(insertSql)) {
            qDebug() << "插入數(shù)據(jù)失?。ㄐ? << row << "):" << query.lastError().text();
            continue;
        }
    }

    db.close();
    qDebug() << "Excel數(shù)據(jù)導入數(shù)據(jù)庫成功!共" << (lastRow-2) << "條數(shù)據(jù)。";
    return true;
}

(2)模板導出:基于固定模板填充數(shù)據(jù)

若需生成格式固定的報表(如公司財務模板、項目驗收模板),可先在 Excel 中創(chuàng)建模板文件(含 logo、固定表頭、簽名區(qū)),再用 QXlsx 填充動態(tài)數(shù)據(jù),避免重復設置格式:

// 示例:基于模板填充數(shù)據(jù)
bool fillExcelTemplate(const QString &templatePath, const QString &outputPath, const QList<Employee> &empList) {
    // 1. 加載模板文件(模板中已設置好標題、表頭、logo)
    QXlsx::Workbook workbook;
    if (!workbook.load(templatePath)) {
        qDebug() << "模板加載失敗!";
        return false;
    }
    QXlsx::Worksheet *sheet = workbook.activeSheet();
    if (!sheet) return false;

    // 2. 填充動態(tài)數(shù)據(jù)(假設模板中數(shù)據(jù)從第5行開始)
    int startRow = 5;
    for (int i = 0; i < empList.size(); ++i) {
        int row = startRow + i;
        const auto &emp = empList[i];
        sheet->write(row, 1, emp.name);    // 模板中A列是姓名
        sheet->write(row, 2, emp.dept);    // B列是部門
        sheet->write(row, 3, emp.salary);  // C列是薪資(模板已設置數(shù)值格式)
    }

    // 3. 填充統(tǒng)計信息(模板中D10單元格是“總人數(shù)”,D11是“平均薪資”)
    int totalCount = empList.size();
    double totalSalary = 0;
    for (const auto &emp : empList) totalSalary += emp.salary;
    double avgSalary = totalCount > 0 ? totalSalary / totalCount : 0;

    sheet->write("D10", totalCount);
    sheet->write("D11", avgSalary);

    // 4. 保存填充后的文件
    return workbook.saveAs(outputPath);
}

優(yōu)勢:

  • 格式維護方便:模板由 Excel 直接編輯,無需在代碼中重復設置格式;
  • 降低開發(fā)成本:代碼只需關注數(shù)據(jù)填充,無需關注樣式細節(jié)。

(3)加密保存:保護 Excel 文件不被篡改

QXlsx 本身不直接支持 Excel 文件加密,但可通過 Qt 的QCryptographicHash結合文件加密工具(如 OpenSSL)實現(xiàn)簡單加密,或生成加密壓縮包:

// 示例:生成加密壓縮包(需鏈接Qt的network模塊,或使用第三方壓縮庫)
#include <QZipWriter>
#include <QCryptographicHash>

bool encryptExcel(const QString &excelPath, const QString &zipPath, const QString &password) {
    // 1. 讀取Excel文件內(nèi)容
    QFile excelFile(excelPath);
    if (!excelFile.open(QIODevice::ReadOnly)) return false;
    QByteArray excelData = excelFile.readAll();
    excelFile.close();

    // 2. 簡單加密(基于密碼生成密鑰,異或加密,適合輕量級保護)
    QByteArray key = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Sha256).left(16);
    QByteArray encryptedData;
    for (int i = 0; i < excelData.size(); ++i) {
        encryptedData.append(excelData[i] ^ key[i % key.size()]);
    }

    // 3. 寫入加密壓縮包
    QZipWriter zipWriter(zipPath);
    QZipWriter::FileInfo fileInfo;
    fileInfo.setFileName("員工信息報表_encrypted.xlsx");
    zipWriter.addFile(fileInfo, encryptedData);
    zipWriter.close();

    return true;
}

注意:

  • 輕量級加密適合普通場景,若需高強度加密,建議集成 OpenSSL 庫(如使用EVP_EncryptInit_ex等函數(shù));
  • 解密時需對應解密邏輯,確保用戶能正確解析文件。

三、總結

QXlsx 的核心優(yōu)勢與適用場景

核心優(yōu)勢

  • 跨平臺無依賴:一次編碼可在 Windows、Linux、macOS 運行,無需用戶安裝 Excel,降低部署門檻;
  • 輕量級易集成:源碼僅 20 + 文件,可直接集成到項目,無需預編譯庫,編譯配置簡單;
  • 功能均衡:支持單元格讀寫、格式控制、圖表、公式,滿足報表生成、數(shù)據(jù)導出等常規(guī)需求;
  • 開源免費:MIT 協(xié)議允許商業(yè)項目免費使用,無版權風險,社區(qū)維護活躍(GitHub 星標 5k+,issues 響應及時)。

適用場景

  • 跨平臺桌面應用(如工業(yè)控制軟件、跨平臺管理系統(tǒng));
  • 輕量級數(shù)據(jù)導出 / 導入(如工具類軟件、小型報表系統(tǒng));
  • 無 Excel 依賴的場景(如嵌入式設備、服務器端數(shù)據(jù)生成);
  • 需基礎格式控制(如字體、顏色、圖表)的報表需求。

到此這篇關于Qt利用QXlsx庫操作Excel表格的應用全解析的文章就介紹到這了,更多相關Qt操作Excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Qt創(chuàng)建SQlite數(shù)據(jù)庫的示例代碼

    Qt創(chuàng)建SQlite數(shù)據(jù)庫的示例代碼

    本文主要介紹了Qt創(chuàng)建SQlite數(shù)據(jù)庫的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • C語言中變量與其內(nèi)存地址對應的入門知識簡單講解

    C語言中變量與其內(nèi)存地址對應的入門知識簡單講解

    這篇文章主要介紹了C語言中變量與其內(nèi)存地址對應的入門知識簡單講解,同時這也是掌握指針部分知識的基礎,需要的朋友可以參考下
    2015-12-12
  • C++運算符重載的實現(xiàn)示例

    C++運算符重載的實現(xiàn)示例

    本文主要介紹了C++運算符重載的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-12-12
  • C語言經(jīng)典指針筆試題詳解

    C語言經(jīng)典指針筆試題詳解

    今天博主來講解4道經(jīng)典的指針筆試題,很多朋友沒有深刻理解函數(shù)傳參知識都會在這些題目上出錯,下面話不多說,我們開始
    2021-10-10
  • VS2019實現(xiàn)C++的第一個MFC程序

    VS2019實現(xiàn)C++的第一個MFC程序

    本文主要介紹了VS2019實現(xiàn)C++的第一個MFC程序,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-06-06
  • C++實現(xiàn)獲取指定代碼段的cpu占用

    C++實現(xiàn)獲取指定代碼段的cpu占用

    這篇文章主要為大家詳細介紹了C++實現(xiàn)獲取指定代碼段的cpu占用的相關知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2023-12-12
  • Qt實現(xiàn)TCP客戶端和服務器通訊程序

    Qt實現(xiàn)TCP客戶端和服務器通訊程序

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)TCP客戶端和服務器通訊程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Qt中QPushButton組件的使用詳解

    Qt中QPushButton組件的使用詳解

    QPushButton是Qt庫中的一個重要組件,本文主要介紹了Qt中QPushButton組件的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-07-07
  • C++實現(xiàn)基于reactor的百萬級并發(fā)服務器

    C++實現(xiàn)基于reactor的百萬級并發(fā)服務器

    本文介紹了基于Reactor模式的百萬級并發(fā)服務器,使用epoll進行高效I/O多路復用,支持多個端口的監(jiān)聽,并通過回調(diào)機制處理每個連接的接收和發(fā)送操作,需要的朋友可以參考下
    2025-02-02
  • Qt視頻播放器的實現(xiàn)示例

    Qt視頻播放器的實現(xiàn)示例

    本文主要介紹了Qt視頻播放器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08

最新評論

卓尼县| 棋牌| 盐池县| 石楼县| 洛扎县| 开江县| 利辛县| 合水县| 尼木县| 吉安市| 沿河| 旺苍县| 昌黎县| 莱州市| 海原县| 鹤峰县| 塔城市| 文成县| 凤冈县| 景宁| 商城县| 汶川县| 佛学| 和龙市| 郁南县| 千阳县| 乌审旗| 闻喜县| 桦甸市| 松阳县| 定陶县| 上林县| 兖州市| 瑞昌市| 南京市| 梅州市| 津市市| 南阳市| 政和县| 深州市| 武夷山市|