QXlsx 读取 XLSX 文件数据的代码

以下是使用 QXlsx 读取 XLSX 文件数据的详细代码示例,包含注释说明和常见场景处理:


代码示例:读取 Excel 文件数据

#include <QCoreApplication>
#include <QXlsx/xlsxdocument.h>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    // 1. 加载 Excel 文件
    QString filePath = "EmployeeData.xlsx";
    QXlsx::Document xlsx(filePath);

    // 检查文件是否加载成功
    if (!xlsx.isLoaded()) {
        qDebug() << "错误:无法加载文件" << filePath;
        qDebug() << "可能原因:文件不存在、路径错误或权限不足。";
        return -1;
    }

    // 2. 获取所有工作表名称,并遍历每个工作表
    QStringList sheetNames = xlsx.sheetNames();
    qDebug() << "工作表列表:" << sheetNames;

    foreach (const QString &sheetName, sheetNames) {
        qDebug() << "\n===== 正在读取工作表:" << sheetName << "=====";

        // 切换到当前工作表
        xlsx.setCurrentSheet(sheetName);

        // 3. 获取工作表的行数和列数
        QXlsx::CellRange range = xlsx.dimension();
        int rowCount = range.rowCount();
        int colCount = range.columnCount();
        qDebug() << "总行数:" << rowCount << "总列数:" << colCount;

        // 4. 逐行逐列读取数据
        for (int row = 1; row <= rowCount; ++row) {
            QString rowData;
            for (int col = 1; col <= colCount; ++col) {
                // 读取单元格内容
                QVariant cellValue = xlsx.read(row, col);

                // 处理不同类型的数据
                if (cellValue.isValid()) {
                    // 日期类型处理
                    if (cellValue.type() == QVariant::DateTime) {
                        QDateTime dt = cellValue.toDateTime();
                        rowData += dt.toString("yyyy-MM-dd") + "\t";
                    } 
                    // 数字或文本类型
                    else {
                        rowData += cellValue.toString() + "\t";
                    }
                    qDebug() << QString("单元格 [%1, %2] 数据:%3")
                                    .arg(row)
                                    .arg(col)
                                    .arg(cellValue.toString());
                } else {
                    rowData += "(空)\t"; // 标记空单元格
                }
            }
            qDebug().noquote() << "行" << row << ":" << rowData;
        }

        // 5. 检查合并单元格
        QList<QXlsx::CellRange> mergedCells = xlsx.mergedCells();
        if (!mergedCells.isEmpty()) {
            qDebug() << "\n合并单元格区域:";
            foreach (const QXlsx::CellRange &merged, mergedCells) {
                QString mergedInfo = QString("区域: %1-%2, 值: %3")
                    .arg(merged.topLeft().toString())
                    .arg(merged.bottomRight().toString())
                    .arg(xlsx.read(merged.topLeft()).toString());
                qDebug() << mergedInfo;
            }
        }
    }

    return 0;
}

关键功能说明

  1. 文件加载与错误处理

    • 使用 QXlsx::Document 直接加载文件。
    • 通过 isLoaded() 检查是否成功加载,避免因路径错误导致崩溃。
  2. 多工作表支持

    • 通过 sheetNames() 获取所有工作表名称。
    • 使用 setCurrentSheet() 切换工作表,确保读取正确内容。
  3. 动态获取行列范围

    • dimension() 返回工作表的单元格范围,获取工作表的行数和列数,自动适应数据区域。
    • 通过双重循环遍历所有单元格。
  4. 读取单元格数据

    • 使用 xlsx.read(row, col) 读取指定单元格内容。
    • 返回值为 QVariant,支持多种数据类型(文本、数字、日期等)。
    • 使用 cellValue.isValid() 检查单元格是否有数据,也即检查单元格是否为空。
  5. 数据类型处理

    • 文本/数字:直接通过 toString() 转换。
    • 日期:识别 QVariant::DateTime 类型,格式化为易读字符串。
    • 空单元格:用 (空) 标记,避免遗漏数据。
  6. 合并单元格检测

    • 使用 mergedCells() 获取所有合并区域。
    • 输出合并区域的左上角值和范围(如 “A1:C1”)。

示例文件内容

假设 EmployeeData.xlsx 内容如下:

姓名年龄入职日期
张三282020-05-10
李四352018-09-01
合并单元格:A4:C4 -> “备注:所有员工为全职”

输出结果

工作表列表: ("Sheet1")

===== 正在读取工作表: Sheet1 =====
总行数:4 总列数:3
行1 : 姓名    年龄    入职日期    
行2 : 张三    28      2020-05-10  
行3 : 李四    35      2018-09-01  
行4 : 备注:所有员工为全职    (空)    (空)

合并单元格区域:
区域: A4-C4, 值: 备注:所有员工为全职

常见问题处理

  1. 文件路径问题

    • 如果文件不在程序运行目录,需使用绝对路径(如 C:/data/file.xlsx)。
  2. 日期显示异常

    • Excel 内部以浮点数存储日期,QXlsx 自动转换为 QDateTime,格式化为 yyyy-MM-dd 更直观。
  3. 公式结果读取

    • 若单元格包含公式(如 =SUM(A1:A3)),QXlsx 默认读取公式本身,非计算结果。
    • 解决方案:手动计算(需复杂逻辑)或用 Excel 打开文件后保存,QXlsx 读取结果值。
  4. 性能优化

    • 对于大型文件(如 10 万行),逐行读取可能较慢。可限制读取范围(如 row <= 1000)或按需读取特定列。

扩展功能示例

读取特定区域的单元格格式
// 获取单元格格式
QXlsx::Format format = xlsx.cellFormat(row, col);
if (format.isValid()) {
    qDebug() << "字体加粗:" << format.fontBold();
    qDebug() << "背景颜色:" << format.patternBackgroundColor();
}
按列名读取数据(假设第一行为列名)
QMap<QString, int> columnMap; // 存储列名与列号的映射

// 第一行为列头
for (int col = 1; col <= colCount; ++col) {
    QString header = xlsx.read(1, col).toString();
    columnMap[header] = col;
}

// 读取“年龄”列的所有数据
for (int row = 2; row <= rowCount; ++row) {
    int age = xlsx.read(row, columnMap["年龄"]).toInt();
    qDebug() << "第" << row << "行年龄:" << age;
}

通过以上代码,你可以灵活读取 Excel 文件中的结构化数据,适用于数据导入、报表分析等场景。如需更多高级操作,可参考 QXlsx 官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值