开发者

Qt利用QXlsx库操作Excel表格的应用全解析

目录
  • 前言
  • 一、Qt 操作 Excel 的 4 种主流方案对比
    • 1. QXlsx(推荐)
    • 2. QAxObject(Qt 自带,非纯开源库)
    • 3. LibXL(半开源,免费版有限制)
    • 4. ODBC 接口(通过 QSqlDatabase)
  • 二、QXlsx 库实际应用:从环境搭建到核心功能
    • 2.1 QXlsx 环境搭建:两种集成方式(源码 / 静态库)
    • 2.2 QXlsx 核心概念:3 个关键类
    • 2.3 QXlsx 基础操作:从创建到保存
    • 2.4 QXlsx 常见问题与解决方案
    • 2.7 QXlsx 扩展使用技巧
  • 三、总结

    前言

    在 Qt 应用开发中,“数据导出为表格”“读取 Excel 数据进行分析” 是高频需求 —— 从管理系统的报表生成,到科研工具的数据整理,再到工业软件的日志归档,几乎都离不开 Excel 交互。但 Qt 原生并未提供 Excel 操作模块,因此选择合适的开源库成为关键。

    本文将系统梳理 Qt 生态中几种主流 Excel 操作方案(QXlsx、QAxObject、LibXL、ODBC),对比其核心差异与适用场景;并以跨平台、无依赖、轻量级的 QXlsx开源库 为核心,实现 Excel 的 “创建 - 读写 - 格式美化” 全流程。

    一、Qt 操作 Excel 的 4 种主流方案对比

    在选择 Excel 操作库前,需先明确项目的核心约束:是否需要跨平台?是否依赖本地 Excel 安装?是否需要格式控制或公式计算?不同库的设计理念差异极大,选错方案可能导致后期重构成本飙升。以下是 4 种主流方案的深度解析:

    1. QXlsx(推荐)

    简介:QXlsx 是一个轻量级开源库(MIT 协议),基于 Qt 框架实现,无需依赖 Microsoft Excel 或其他第三方软件,纯 C++ 实现 Excel 文件(.xlsx)的读写和格式控制。它是从早期的QtXlsxWriter fork 而来,目前维护活跃,兼容性更好。

    特点

    • 支持 .xlsx 格式(不支持旧版 .xls);
    • 跨平台(Windows、linux、MACOS),无需安装 Excel;
    • 提供丰富的 API:单元格读写、合并单元格、字体 / 颜色 / 对齐方式设置、图表、批注等;
    • 轻量,可直接将源码集成到项目(无需预编译库)。

    优缺点

    • 优点:跨平台性强、无外部依赖、集成简单、功能满足大多数场景;
    • 缺点:不支持 .xls 格式,复杂图表或高级 Excel 功能(如宏、公式ngllG计算)支持有限。
    • 适用场景:跨平台项目、无需依赖 Excel 环境、需要基本 Excel 读写和格式控制的场景(如数据导出、简单报表生成)。

    2. QAxObject(Qt 自带,非纯开源库)

    简介:QAxObject 是 Qt 提供的 ActiveX 组件交互类,通过调用 Windows 系统中的 Excel COM 接口操作 Excel 文件。它本身是 Qt 的一部分,无需额外下载,但依赖 Windows 系统和本地安装的 Excel。

    特点

    • 支持 .xls 和 .xlsx 格式,可调用 Excel 的全部功能(包括宏、公式计算、高级图表等);
    • 本质是 “操控本地 Excel 程序”,操作方式与 vbA 类似。

    优缺点

    • 优点:功能完整(Excel 能做的它都能做),无需额外学习新 API(可参考 VBA 语法);
    • 缺点:仅支持 Windows 平台,必须安装 Excel,操作速度较慢(依赖 Excel 进程),跨平台项目无法使用。

    适用场景:仅限 Windows 平台、需要使用 Excel 高级功能(如宏、复杂公式)、允许依赖本地 Excel 安装的场景。

    3. LibXL(半开源,免费版有限制)

    简介:LibXL 是一个跨平台的 Excel 操作库(C/C++),提供 Qt 绑定,支持 .xls 和 .xlsx 格式。它分为免费版和商业版,免费版有功能限制(如无法隐藏水印、最多处理 100 行数据)。

    特点

    • 跨平台(Windows、Linux、macOS),无需依赖 Excel;
    • 支持丰富的格式控制(字体、颜色、边框、合并单元格等),支持公式计算和图表;
    • 性能较好,比 QXlsx 处理大数据时更快。

    优缺点

    • 优点:支持 .xls 和 .xlsx,性能强,功能丰富;
    • 缺点:免费版有功能限制,商业使用需要购买授权(价格较高)。
    • 适用场景:需要处理 .xls 格式、对性能要求高、可接受商业授权的项目。

    4. ODBC 接口(通过 QSqlDatabase)

    简介:ODBC(开放数据库连接)是一种通用数据库接口,可将 Excel 文件视为 “数据库”,通过 Qt 的 QSqlDatabase 进行读写(需配置 Excel ODBC 驱动)。

     

    特点

    • 跨平台(需安装对应平台的 Excel ODBC 驱动);
    • 操作方式类似数据库(通过 SQL 语句读写单元格数据)。

    优缺点

    • 优点:无需依赖 Excel,可跨平台,适合简单数据读写;
    • 缺点:不支持格式控制(如字体、颜色),无法处理合并单元格、图表等,配置驱动较繁琐(尤其非 Windows 平台)。
    • 适用场景:仅需简单读写 Excel 数据(无需格式)、可接受繁琐配置的跨平台项目。

    总结与选择建议

    库 / 方式跨平台依赖 Excel支持格式功能丰富度开源 / 免费推荐场景
    QXlsx.xlsx中(够用)完全开源(MIT)跨平台、基本 Excel 操作
    QAxObject否(仅 Windows).xls/.xlsx高(完整)免费(Qt 自带)Windows 平台、高级 Excel 功能
    LibXL.xls/.xlsx免费版有限制需.xls 格式、高性能、商业授权
    ODBC是(需驱动).xls/.xlsx低(仅数据)免费简单数据读写、跨平台

    二、QXlsx 库实际应用:从环境搭建到核心功能

    通过上一部分的对比,不难发现 QXlsx 是 “跨平台、无依赖、功能均衡” 的最优解,也是大多数 Qt 项目的首选。本节将从环境搭建→基础操作→进阶功能→实战案例,完整覆盖 QXlsx 的使用流程。

    2.1 QXlsx 环境搭建:两种集成方式(源码 / 静态库)

    QXlsx 的集成方式灵活,推荐新手使用 “源码直接集成”(无需编译库,开箱即用),大型项目可选择 “编译静态库”(减少编译时间,便于多项目复用)。

    方式 1:源码直接集成(推荐新手)

    步骤 1:获取 QXlsx 源码

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

    解压后,核心源码在QXlsx/src目录下(包含 20 多个.cpp 和.h 文件,如xlsxworkbook.h、xlsxworksheet.cpp)。

    步骤 2:项目结构规划

    建议将 QXlsx 源码放在项目的 “第三方库” 目录下,保持项目结构清晰。如下:

    Qt利用QXlsx库操作Excel表格的应用全解析

    步骤 3:配置.pro 文件

    在项目的.pro文件中,添加 QXlsx 的头文件路径和源码文件,确保编译器能找到并编译 QXlsx 代码。

    Qt 5/.pro 配置示例:

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

    然后工程中就有了QXlsx的文件结构:

    Qt利用QXlsx库操作Excel表格的应用全解析

    步骤 4:验证集成是否成功

    在main.cpp中引入 QXlsx 头文件,编译项目。若无 “头文件找不到”“未定义符号” 错误,说明集成成功:

    #include <QApplication>
    #include "thirdparty/qxlsx/src/xlsxworkbook.h"  // 引入QXlsx头文件
    
    int main(int argc, char *argv[]) {
        QApplication a(argc, argv);
    
        // 尝试创建工作簿,验证集成
        QXlsx::Workbook workbook;
        qDebug() << "QXlsx集成成功!";
    
        return a.exec();
    }
    

    方式 2:编译静态库(适合多项目复用)

    若多个项目需使用 QXlsx,直接集成源码会导致重复编译,可将 QXlsx 编译为静态库(.a/.lib),供所有项目链接使用。

    步骤 1:创建 QXlsx 静态库项目

    打开 Qt Creator,新建 “Library”→“C++ Library” 项目,类型选择 “Static Library”;

    项目名称设为 “QXlsxLib”,保存路径自定义;

    将 QXlsx 源码的src目录复制到项目根目录,删除默认生成的qxlsxlibrary.cpp和qxlsxlibrary.h。

    步骤 2:配置静态库项目的.pro

    QT += core widgets
    TARGET = QXlsxLib  # 静态库名称
    TEMPLATE = lib
    CONFIG += staticlib  # 指定为静态库
    
    # 头文件路径
    INCLUDEPATH += $$PWD/src
    
    # 添加所有QXlsx源码(同方式1的SOURCES和HpythonEADERS)
    SOURCES += \
        $$PWD/src/xlsxabstractooXMLfile.cpp \
        ...(省略其他.cpp文件,同方式1)
    
    HEADERS += \
        $$PWD/src/xlsxabstractooxmlfile.h \
        ...(省略其他.h文件,同方式1)
    
    # Qt 6专属配置
    DEFINES += QXLSX_QT6
    

    步骤 3:编译静态库

    • 选择对应的编译器(如 MinGW 64-bit、MSVC 2019),点击 “构建”,生成静态库文件:
    • Windows(MinGW):生成libQXlsxLib.a;
    • Windows(MSVC):生成QXlsxLib.lib;
    • Linux:生成libQXlsxLib.a;
    • macOS:生成libQXlsxLib.a。

    步骤 4:在目标项目中链接静态库

    在需要使用 QXlsx 的项目的.pro中,添加静态库的路径和链接配置:

    QT += core widgets
    
    # 1. 头文件路径(指向QXlsx的src目录)
    INCLUDEPATH += $$PWD/../QXlsxLib/src  # 需根据实际路径调整
    
    # 2. 静态库路径(指向生成的.a/.lib文件所在目录)
    LIBS += -L$$PWD/../QXlsxLib/build-QXlsxLib-Desktop_Qt_5_15_2_MinGW_64_bit-Debug/lib \
            -lQXlsxLib  # 链接静态库(MinGW用-lxxx,MSVC直接写xxx.lib)
    
    # Qt 6专属配置
    DEFINES += QXLSX_QT6
    

    2.2 QXlsx 核心概念:3 个关键类

    QXlsx 的 API 设计遵循 “Excel 对象模型”,核心逻辑围绕 3 个类展开,理解它们的关系是使用 QXlsx 的基础:

    类名对应 Excel 概念核心作用
    QXlsx::Workbook工作簿代表整个 Excel 文件,负责创建 / 加载 / 保存文件
    QXlsx::Worksheet工作表代表 Excel 中的一个工作表,负责单元格操作
    QXlsx::Format单元格格式定义单元格的样式(字体、颜色、对齐等)

    2.3 QXlsx 基础操作:从创建到保存

    接下来介绍 Excel 最常用的基础功能:创建工作簿、新建工作表、写入 / 读取单元格数据、格式设置、合并单元格、列宽行高调整,所有代码均附带详细注释。

    示例 1:创建 Excel 文件并写入基础数据

    目标:创建一个包含 “学生成绩表” 的 Excel 文件,包含标题行和 2 条数据,设置标题格式,调整列宽。

    #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. 创建工作簿(Workbook):代表整个Excel文件
        QXlsx::Workbook workbook;
    
        // 2. 新建工作表(Worksheet):默认工作表名为“Sheet1”,可自定义
        QXlsx::Worksheet *sheet = workbook.addSheet("学生成绩表");  // 新建名为“学生成绩表”的工作表
        // 若需获取默认工作表,可使用:QXlsx::Worksheet *sheet = workbook.activeSheet();
    
        // 3. 创建格式(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. 创建数据格式:定义数据单元格的样式
        QXlsx::Format dataFormat;
        dataFormat.setFontSize(12);                             // 字体大小12号
        dataFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter);  // 水平居中
        dataFormat.setBorderStyle(QXlsx::Format::BorderThin);   // 边框
        dataFormat.setBorderColor(QColor(100, 100, 100));       // 边框颜色
    
        // 5. 写入单元格数据:支持“单元格坐标”(如"A1")或“行号+列号”(行/列从1开始)
        // 写入标题行(应用标题格式)
        sheet->write("A1", "学号", titleFormat);  // A1单元格:学号
        sheet->write("B1", "姓名", titleFormat);  // B1单元格:姓名
        sheet->write("C1", "数学", titleFormat);  // C1单元格:数学
        sheet->write("D1", "英语", titleFormat);  // D1单元格:英语
        sheet->write("E1", "总分", titleFormat);  // E1单元格:总分
    
        // 写入数据行(应用数据格式)
        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):数学成绩
        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:数学成绩
        sheet->write(3, 4, 92, dataFormat);        // D3:英语成绩
        sheet->write(3, 5, "=C3+D3", dataFormat);  // E3:总分(公式)
    
        // 6. 调整列宽和行高
        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 文件中,标题行呈淡蓝色、粗体居中,数据行带边框,总分列自动计算结果,列宽行高适配内容,整体样式整洁。

    示例 2:读取已有的 Excel 文件数据

    目标:读取上一步生成的 “学生成绩表.xlsx”,提取所有数据并打印到控制台。

    #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. 创建工作簿并加载文件
        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. 获取数据范围:确定表格的行数和列数(避免遍历空单元格)
        // 方法:获取最后一个非空行和最后一个非空列
        int lastRow = sheet->dimension().lastRow();    // 最后一行(示例中为3)
        int lastCol = sheet->dimension().lastColumn();// 最后一列(示例中为5)
        qDebug() << "数据范围:" << lastRow << "行," << lastCol << "列";
    
        // 5. 遍历所有单元格,读取数据
        qDebug() << "\n读取到的Excel数据:";
        for (int row = 1; row <= lastRow; ++row) {  // 行从1开始
            QString rowData;
            for (int col = 1; col <= lastCol; ++col) {  // 列从1开始
                // 读取单元格数据(返回QVariant,需根据实际类型转换)
                QVariant cellValue = sheet->read(row, col);
                // 将数据拼接为字符串(处理数字、文本、公式结果)
                if (cellValue.isValid()) {
                    rowData += cellValue.toString() + "\t";
                } else {
                    rowData += "空\t";
                }
            }
            qDebug() << rowData;
        }
    
        return a.exec();
    }
    

    2.4 QXlsx 常见问题与解决方案

    在实际开发中,使用 QXlsx 可能遇到编译错误、中文乱码、大数据处理缓慢等问题,以下是高频问题的解决方案:

    (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 时未正确转换。

    解决方案:

    • 确保字符串编码统一:在写入中文前,将字符串转换为 UTF-8 格式(如QString(“员工信息”).toUtf8());
    • 强制 Excel 使用 UTF-8 编码:在保存文件前,添加编码设置(需修改 QXlsx 源码):
    • 打开src/xlsxsharedstrings.cpp,找到write()函数,在xmlWriter.writeStartElement(“sst”)后添加:
    xmlWriter.writeAttribute("xml:lang", "zh-CN");
    xmlWriter.writeAttribute("encoding", "UTF-8");
    

    用 wpS 打开验证:若 Microsoft Excel 仍乱码,尝试用 WPS 打开(WPS 对 UTF-8 兼容性更好),或在 Excel 中手动设置编码(「数据」→「获取外部数据」→「从文本 / CSV」→选择 UTF-8)。

    (3)大数据处理:10 万行数据写入后内存溢出或卡顿

    问题原因:

    QXlsx 默认将所有单元格数据存入内存,大数据量时占用内存过高(10 万行 ×10 列约占用 100MB + 内存);

    一次性写入所有数据,未分块处理,导致主线程阻塞。

    解决方案:

    分块写入数据:每写入 1000 行数据,调用QCoreApplication::processEvents()释放主线程,避免卡顿:

    for (int i = 0; i < 100000; ++i) {
        sheet->write(i+3, 1, QString("员工%1").arg(i));
        sheet->write(i+3, 2, "技术部");
        // ... 其他列数据 ...
    
        // 每1000行释放一次事件循环
        if (i % 1000 == 0) {
            QCoreApplication::processEvents();
        }
    }
    

    禁用不必要的格式:大数据场景下,减少Format对象创建(如复用同一个dataFormat,而非每行创建新对象),格式越简单,写入速度越快;

    使用QXlsx::Worksheet::writeArray()批量写入:对于二维数组数据,优先使用writeArray()(底层优化了 IO 操作),比循环write()快:

    // 示例:批量写入1000行2列数据
    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开始写入二维数组
    

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

    问题原因:

    • 保存路径不存在(如指定 “C:\ 未创建的文件夹 \test.xlsx”);
    • 文件被占用(如 Excel 已打开该文件,导致写入权限不足);
    • 磁盘空间不足或权限不够(如 Linux 下无写入当前目录的权限)。

    解决方案:

    检查路径合法性:用QDir确保保存目录存在,不存在则创建:

    QString saveDir = QCoreApplication::applicationDirPath() + "/reports";
    QDir dir(saveDir);
    if (!dir.exists()) {
        dir.mkpath(saveDir);  // 创建目录(包括父目录)
    }
    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 还可通过一些技巧满足更复杂的需求,提升开发效率:

    (1)批量处理:读取 Excel 文件并导入数据库

    在实际项目中,常需将 Excel 中的数据导入到 mysql、SQLite 等数据库,可结合 Qt 的QSqlDatabase实python现:

    // 示例:读取Excel数据并插入SQLite数据库
    #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数据库
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(dbPath);
        if (!db.open()) {
            qDebug() << "数据库连接失败:" << db.lastError().text();
            return false;
        }
    
        // 3. 创建表(若不存在)
        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() << "创建表失败:" << query.lastError().text();
            return false;
        }
    
        // 4. 读取Excel数据并插入数据库
        int lastRow = sheet->dimension().lastRow();
        for (int row = 3; row <= lastRow; ++row) {  // 从第3行(数据行)开始
            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() << "插入数据失败(行" << row << "):" << query.lastError().text();
                continue;
            }
        }
    
        db.close();
        qDebug() << "Excel数据导入数据库成功!共" << (lastRow-2) << "条数据。";
        return true;
    }
    

    (2)模板导出:基于固定模板填充数据

    若需生成格式固定的报表(如公司财务模板、项目验收模板),可先在 Excel 中创建模板文件(含 logo、固定表头、签名区),再用 QXlsx 填充动态数据,避免重复设置格式:

    // 示例:基于模板填充数据
    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. 填充动态数据(假设模板中数据从第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列是薪资(模板已设置数值格式)
        }
    
        // 3. 填充统计信息(android模板中D10单元格是“总人数”,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);
    }
    

    优势:

    • 格式维护方便:模板由 Excel 直接编辑,无需在代码中重复设置格式;
    • 降低开发成本:代码只需关注数据填充,无需关注样式细节。

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

    QXlsx 本身不直接支持 Excel 文件加密,但可通过 Qt 的QCryptographicHash结合文件js加密工具(如 OpenSSL)实现简单加密,或生成加密压缩包:

    // 示例:生成加密压缩包(需链接Qt的network模块,或使用第三方压缩库)
    #include <QZipWriter>
    #include <QCryptographicHash>
    
    bool encryptExcel(const QString &excelPath, const QString &zipPath, const QString &password) {
        // 1. 读取Excel文件内容
        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等函数);
    • 解密时需对应解密逻辑,确保用户能正确解析文件。

    三、总结

    QXlsx 的核心优势与适用场景

    核心优势

    • 跨平台无依赖:一次编码可在 Windows、Linux、macOS 运行,无需用户安装 Excel,降低部署门槛;
    • 轻量级易集成:源码仅 20 + 文件,可直接集成到项目,无需预编译库,编译配置简单;
    • 功能均衡:支持单元格读写、格式控制、图表、公式,满足报表生成、数据导出等常规需求;
    • 开源免费:MIT 协议允许商业项目免费使用,无版权风险,社区维护活跃(GitHub 星标 5k+,issues 响应及时)。

    适用场景

    • 跨平台桌面应用(如工业控制软件、跨平台管理系统);
    • 轻量级数据导出 / 导入(如工具类软件、小型报表系统);
    • 无 Excel 依赖的场景(如嵌入式设备、服务器端数据生成);
    • 需基础格式控制(如字体、颜色、图表)的报表需求。

    到此这篇关于Qt利用QXlsx库操作Excel表格的应用全解析的文章就介绍到这了,更多相关Qt操作Excel内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:没有了

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜