QXlsx操作Excel深度解析:核心类接口与 Qt C++ 功能解析

前言

在 Qt 开发领域,QXlsx 凭借跨平台、无依赖、轻量级的特性,成为 Excel 表格操作的事实标准。对于开发者而言,掌握其核心类接口与功能实现逻辑,是从 "能用法" 到 "精通法" 的关键。本文聚焦 QXlsx 的类接口细节与主流功能实现,直接深入Workbook「工作簿」、Worksheet「工作表」、Format「格式」、Chart「图表」等核心类的接口函数,代码说明,详解表头设置、字体样式、颜色控制、图片插入、图表生成等实用功能,帮你系统性掌握 QXlsx 的全部主流应用。

一、QXlsx 核心类体系与关系

在学习具体接口前,需先明确 QXlsx 的核心类体系 ------ 其设计完全映射 Excel 的对象模型,类之间的层级关系决定了功能调用的逻辑顺序。

核心类关系图谱

类名 核心定位 关键接口方向
QXlsx::Workbook 管理整个 Excel 文件 工作表创建、文件加载 / 保存、全局配置
QXlsx::Worksheet 管理单个工作表数据与元素 单元格读写、合并、行高列宽、图片 / 图表插入
QXlsx::Format 定义单元格样式(视觉属性) 字体、颜色、对齐、边框、填充
QXlsx::Chart 生成数据可视化图表 图表类型、数据关联、标题 / 轴标签设置
QXlsx::Cell 单个单元格的数据与格式载体 数据读写、格式绑定(一般通过 Worksheet 操作)

核心类调用逻辑

所有操作均以Workbook为起点,流程如下:

1.创建Workbook实例

  1. 通过Workbook创建Worksheet

  2. 定义Format样式

  3. 通过Worksheet接口读写单元格(绑定Format)

  4. 插入图片 / 图表(通过Worksheet接口)

  5. 保存文件(Workbook接口)。

二、Workbook 类:Excel 文件的 "总控中心"

Workbook是 QXlsx 的入口类,负责 Excel 文件的全局管理,包括工作表创建、文件加载 / 保存、全局样式配置等。其接口虽少,但为所有功能提供基础支撑。

2.1 工作表管理接口

接口函数 功能描述 参数说明 示例代码
Worksheet* addSheet(const QString &name) 新增工作表 name:工作表名称(默认 "Sheet1") QXlsx::Workbook wb; QXlsx::Worksheet *sheet1 = wb.addSheet("销售数据"); // 新增名为"销售数据"的工作表 QXlsx::Worksheet *sheet2 = wb.addSheet("用户列表"); // 新增第二个工作表
Worksheet* sheet(int index) 通过索引获取工作表 index:索引(从 0 开始) // 获取第一个工作表(索引0) QXlsx::Worksheet *firstSheet = wb.sheet(0);
Worksheet* sheet(const QString &name) 通过名称获取工作表 name:工作表名称 // 获取名为"销售数据"的工作表 QXlsx::Worksheet *salesSheet = wb.sheet("销售数据");
QList<Worksheet*> sheets() 获取所有工作表 -- QListQXlsx::Worksheet* allSheets = wb.sheets(); for (auto sheet : allSheets) { qDebug() << "工作表名称:" << sheet->sheetName(); }
bool renameSheet(int index, const QString &newName) 重命名工作表 index:原索引;newName:新名称 // 将第一个工作表重命名为"2023销售数据" wb.renameSheet(0, "2023销售数据");
bool removeSheet(int index) 删除工作表 index:待删除工作表索引 // 删除第二个工作表(索引1) wb.removeSheet(1);

2.2 文件操作接口

接口函数 功能描述 参数说明 示例代码
bool load(const QString &fileName) 加载已有的 Excel 文件 fileName:文件路径(含.xlsx 后缀) if (wb.load("existing_file.xlsx")) { qDebug() << "文件加载成功"; } else { qDebug() << "文件加载失败"; }
bool saveAs(const QString &fileName) 保存工作簿到指定路径 fileName:目标路径(需带.xlsx 后缀) 保存到程序运行目录下的"output.xlsx" QString savePath = QCoreApplication::applicationDirPath() + "/output.xlsx"; if (wb.saveAs(savePath)) { qDebug() << "保存成功:" << savePath; }
QByteArray toByteArray() 将工作簿转为字节数组(内存操作) -- 将Excel数据存入内存(可用于网络传输或数据库存储) QByteArray excelData = wb.toByteArray();

2.3 全局配置接口

接口函数 功能描述 参数说明 示例代码
void setDocumentProperty(const QString &key, const QString &value) 设置文档属性(作者、标题等) key:属性名(如 "title"、"author");value:属性值 wb.setDocumentProperty("title", "2023年度报表"); // 文档标题 wb.setDocumentProperty("author", "Qt开发团队"); // 作者 wb.setDocumentProperty("company", "示例科技"); // 公司
QString documentProperty(const QString &key) 获取文档属性 key:属性名 qDebug() << "文档作者:" << wb.documentProperty("author");

三、Worksheet 类:工作表的 "数据与元素管家"

Worksheet是 QXlsx 中最核心的功能类,几乎所有与表格内容相关的操作(单元格读写、合并、行高列宽调整、图片 / 图表插入)都通过它实现。其接口数量最多,也是实际开发中使用最频繁的类。

3.1 单元格数据读写接口

单元格是工作表的基本单位,Worksheet提供了多种读写接口,支持按坐标(如 "A1")或行列号(从 1 开始)操作。

接口函数 功能描述 参数说明 示例代码
bool write(int row, int col, const QVariant &value, const Format &format = Format()) 按行列号写入数据 row:行号(1 开始);col:列号(1 开始);value:数据(支持字符串、数字、日期等);format:格式(可选) 向第2行第3列(C2)写入数字100,应用默认格式 sheet->write(2, 3, 100); // 向第3行第1列(A3)写入字符串"示例",应用自定义格式 QXlsx::Format f; f.setFontBold(true); sheet->write(3, 1, "示例", f);
bool write(const QString &cell, const QVariant &value, const Format &format = Format()) 按单元格坐标写入数据 cell:坐标(如 "A1"、"B5");value:数据;format:格式(可选) 向A1写入标题"销售报表" sheet->write("A1", "销售报表"); // 向B2写入日期(QDate需转为QVariant) sheet->write("B2", QDate::currentDate());
QVariant read(int row, int col) 按行列号读取数据 row:行号;col:列号 读取C2单元格数据 QVariant value = sheet->read(2, 3); qDebug() << "C2的值:" << value.toString();
QVariant read(const QString &cell) 按坐标读取数据 cell:坐标(如 "A1") 读取B2单元格数据 QVariant dateValue = sheet->read("B2"); qDebug() << "B2的日期:" << dateValue.toDate().toString();
QVariant read(const QString &cell) 按坐标读取数据 cell:坐标(如 "A1") 读取B2单元格数据 QVariant dateValue = sheet->read("B2"); qDebug() << "B2的日期:" << dateValue.toDate().toString();
bool writeBlank(int row, int col, const Format &format = Format()) 写入空单元格(仅应用格式) row:行号;col:列号;format:格式 在D5写入空单元格,但设置灰色背景 QXlsx::Format f; f.setFillColor(Qt::lightGray); sheet->writeBlank(5, 4, f);

3.2 单元格区域操作接口

实际开发中常需操作连续区域(如批量写入数据、合并单元格),Worksheet提供了专门的区域操作接口。

3.3 行高与列宽设置接口

合理的行高列宽能避免内容溢出,Worksheet提供了灵活的调整接口。

3.4 工作表属性接口

接口函数 功能描述 参数说明 示例代码
QString sheetName() const 获取工作表名称 -- qDebug() << "当前工作表名称:" << sheet->sheetName();
void setSheetName(const QString &name) 设置工作表名称 name:新名称 sheet->setSheetName("Q1销售数据");
Dimension dimension() const 获取数据区域(最小 / 最大行列) -- QXlsx::Worksheet::Dimension dim = sheet->dimension(); qDebug() << "数据范围:" << "行:" << dim.firstRow() << "-" << dim.lastRow() << "列:" << dim.firstColumn() << "-" << dim.lastColumn();
void setGridLinesVisible(bool visible) 设置是否显示网格线 visible:true 显示,false 隐藏 sheet->setGridLinesVisible(false); // 隐藏网格线

四、Format 类:单元格样式的 "设计师"

Format类是 QXlsx 中控制单元格视觉样式的核心,几乎所有与 "外观" 相关的设置(字体、颜色、对齐、边框)都通过它实现。掌握Format的接口,能让你的 Excel 表格从 "纯数据" 升级为 "可视化报表"。

4.1 字体设置接口

字体是单元格样式的基础,Format提供了丰富的字体属性控制函数。

接口函数 功能描述 参数说明 示例代码
void setFontFamily(const QString &family) 设置字体家族(如 "微软雅黑") family:字体名称(需系统支持) QXlsx::Format f; f.setFontFamily("微软雅黑"); // Windows系统,f.setFontFamily("PingFang SC"); // macOS系统
void setFontSize(double size) 设置字体大小(单位:磅) size:字号(如 12、14) f.setFontSize(14); // 14号字
void setFontBold(bool bold) 设置字体加粗 bold:true 加粗,false 正常 f.setFontBold(true); // 粗体
void setFontItalic(bool italic) 设置字体斜体 italic:true 斜体,false 正常 f.setFontItalic(true); // 斜体
void setFontUnderline(Underline underline) 设置下划线 underline:下划线类型(NoUnderline/SingleUnderline/DoubleUnderline) f.setFontUnderline(QXlsx::Format::SingleUnderline); // 单下划线
void setFontStrikeOut(bool strikeOut) 设置删除线 strikeOut:true 显示删除线 f.setFontStrikeOut(true); // 添加删除线
void setFontColor(const QColor &color) 设置字体颜色 color:颜色(支持 Qt 颜色或 RGB 值) f.setFontColor(Qt::red); // 红色字体 f.setFontColor(QColor(255, 100, 100)); // 自定义RGB颜色

4.2 对齐方式接口

对齐方式直接影响内容的可读性,Format支持水平、垂直对齐及自动换行。

4.3 背景与填充接口

背景填充能突出重要内容(如标题行、总计行),Format支持纯色填充和图案填充。

4.4 边框设置接口

边框能增强表格的层次感,Format支持设置边框样式、颜色及方向(上、下、左、右、外框、内框)。

4.5 数字格式接口

数字格式控制数据的显示形式(如保留 2 位小数、百分比、日期格式),Format通过格式字符串实现。

void setNumberFormat(const QString &format) ; 功能是设置数字格式字符串。

其中:format:格式字符串(与 Excel 格式语法一致)

例如: 保留2位小数 QXlsx::Format f1; f1.setNumberFormat("#,##0.00"); // 1234.56 → 1,234.56 // 百分比格式(保留1位小数) QXlsx::Format f2; f2.setNumberFormat("0.0%"); // 0.123 → 12.3% // 日期格式(年-月-日) QXlsx::Format f3; f3.setNumberFormat("yyyy-mm-dd"); // 日期数据显示为2023-10-01。

五、表头设置:从基础到复杂的实战方案

表头是表格的 "导航栏",清晰的表头能大幅提升表格可读性。QXlsx 中表头设置的核心是格式定制与单元格合并,结合Worksheet和Format的接口可实现各种复杂表头。

5.1 基础表头:单行列标题

最常见的表头形式,一行包含多个列标题(如 "姓名""年龄""性别"),通过Format设置统一样式。
实现步骤:

  • 定义表头格式(加粗、居中、背景色、边框);
  • 向第一行(或指定行)写入列标题,应用表头格式;
  • 调整行高和列宽适配内容。

代码示例:

cpp 复制代码
// 1. 创建表头格式
QXlsx::Format headerFormat;
headerFormat.setFontFamily("微软雅黑");
headerFormat.setFontSize(12);
headerFormat.setFontBold(true); // 加粗
headerFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 水平居中
headerFormat.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 垂直居中
headerFormat.setFillColor(QColor(217, 225, 242)); // 淡蓝色背景
headerFormat.setBorderStyle(QXlsx::Format::BorderThin); // 细边框
headerFormat.setBorderColor(QColor(100, 100, 100)); // 边框灰色

// 2. 写入表头(第1行)
sheet->write(1, 1, "学号", headerFormat);   // A1
sheet->write(1, 2, "姓名", headerFormat);   // B1
sheet->write(1, 3, "数学", headerFormat);   // C1
sheet->write(1, 4, "语文", headerFormat);   // D1
sheet->write(1, 5, "英语", headerFormat);   // E1
sheet->write(1, 6, "总分", headerFormat);   // F1

// 3. 调整表头行高和列宽
sheet->setRowHeight(1, 25); // 表头行高25磅
sheet->setColumnWidth(1, 10);  // 学号列
sheet->setColumnWidth(2, 10);  // 姓名列
sheet->setColumnWidth(3, 8);   // 数学列
sheet->setColumnWidth(4, 8);   // 语文列
sheet->setColumnWidth(5, 8);   // 英语列
sheet->setColumnWidth(6, 8);   // 总分列

结果说明:

表头行背景为淡蓝色,文字加粗居中,带灰色细边框,列宽适配内容,整体清晰易读。

5.2 复杂表头:多级合并表头

在报表类场景中,常需多级表头(如 "成绩" 包含 "数学""语文""英语"),需通过mergeCells合并单元格实现。
实现步骤:

  • 定义多级表头的格式(一级表头可使用更深的背景色区分);
  • 合并一级表头单元格(如合并 A1 到 F1 作为总标题);
  • 合并二级表头单元格(如合并 A2 到 A3 作为 "基本信息");
  • 写入各级标题并调整行高列宽。

代码示例:

cpp 复制代码
// 1. 定义一级表头格式(总标题)
QXlsx::Format level1Format;
level1Format.setFontFamily("微软雅黑");
level1Format.setFontSize(14);
level1Format.setFontBold(true);
level1Format.setHorizontalAlignment(QXlsx::Format::AlignHCenter);
level1Format.setVerticalAlignment(QXlsx::Format::AlignVCenter);
level1Format.setFillColor(QColor(189, 215, 238)); // 蓝色背景
level1Format.setBorderStyle(QXlsx::Format::BorderThin);

// 2. 定义二级表头格式(分类标题)
QXlsx::Format level2Format;
level2Format.setFontFamily("微软雅黑");
level2Format.setFontSize(12);
level2Format.setFontBold(true);
level2Format.setHorizontalAlignment(QXlsx::Format::AlignHCenter);
level2Format.setVerticalAlignment(QXlsx::Format::AlignVCenter);
level2Format.setFillColor(QColor(217, 225, 242)); // 淡蓝色背景
level2Format.setBorderStyle(QXlsx::Format::BorderThin);

// 3. 合并一级表头(A1到F1:总标题)
sheet->mergeCells(1, 1, 1, 6, "学生成绩表", level1Format);

// 4. 合并二级表头
sheet->mergeCells(2, 1, 3, 1, "学号", level2Format);      // A2-A3合并
sheet->mergeCells(2, 2, 3, 2, "姓名", level2Format);      // B2-B3合并
sheet->mergeCells(2, 3, 2, 5, "单科成绩", level2Format);  // C2-E2合并(二级分类)
sheet->write(3, 3, "数学", level2Format);                 // C3
sheet->write(3, 4, "语文", level2Format);                 // D3
sheet->write(3, 5, "英语", level2Format);                 // E3
sheet->mergeCells(2, 6, 3, 6, "总分", level2Format);      // F2-F3合并

// 5. 调整行高
sheet->setRowHeight(1, 30); // 一级表头行高
sheet->setRowHeight(2, 25); // 二级表头行高(分类行)
sheet->setRowHeight(3, 25); // 二级表头行高(子项行)

// 6. 调整列宽(同基础表头)
sheet->setColumnWidth(1, 10);
sheet->setColumnWidth(2, 10);
sheet->setColumnWidth(3, 8);
sheet->setColumnWidth(4, 8);
sheet->setColumnWidth(5, 8);
sheet->setColumnWidth(6, 8);

效果说明:

  • 一级表头(第 1 行)合并为 "学生成绩表",蓝色背景 + 14 号粗体;
  • 二级表头中,"单科成绩" 合并 C2-E2,其下方 C3-E3 分别为 "数学""语文""英语";
  • 各级表头通过背景色区分,边框统一,层次清晰。

六、图片插入:丰富表格视觉元素

在报表中插入图片(如公司 Logo、产品截图、二维码)能提升专业性,QXlsx 通过Worksheet的insertImage接口实现图片插入,支持 PNG、JPG、BMP 等格式。

6.1 图片插入核心接口

接口函数 功能描述 参数说明
bool insertImage(int row, int col, const QString &imagePath, const QSize &size = QSize(), double xOffset = 0, double yOffset = 0) 按行列号插入图片 row/col:插入位置(单元格左上角);imagePath:图片路径;size:图片大小(默认原尺寸);xOffset/yOffset:单元格内偏移量(像素)
bool insertImage(const QString &cell, const QString &imagePath, const QSize &size = QSize(), double xOffset = 0, double yOffset = 0) 按坐标插入图片 cell:插入位置(如 "A1");其他参数同上

6.2 基础图片插入(固定大小)

实现步骤:

  • 准备图片路径(建议使用绝对路径,避免找不到文件);
  • 调用insertImage指定插入位置和大小;
  • 调整行高 / 列宽避免图片被压缩。

代码示例:

cpp 复制代码
// 1. 图片路径(程序运行目录下的logo.png)
QString logoPath = QCoreApplication::applicationDirPath() + "/logo.png";

// 2. 检查图片是否存在
if (!QFile::exists(logoPath)) {
    qDebug() << "图片不存在:" << logoPath;
    return;
}

// 3. 插入图片到B2单元格,大小设为200×80像素
bool inserted = sheet->insertImage("B2", logoPath, QSize(200, 80));
if (!inserted) {
    qDebug() << "图片插入失败";
}

// 4. 调整B列宽度和第2行高度,避免图片被截断
sheet->setColumnWidth(2, 30); // B列宽度30字符(足够容纳200px图片)
sheet->setRowHeight(2, 80);  // 第2行高度80磅(≈28mm,匹配图片高度)

6.3 图片偏移与缩放

通过xOffset和yOffset调整图片在单元格内的位置,或通过QSize按比例缩放图片。

代码示例:

cpp 复制代码
// 1. 插入图片到D5单元格,原尺寸缩放50%
QImage img(logoPath);
QSize originalSize = img.size();
QSize scaledSize = originalSize * 0.5; // 缩小到50%

// 2. 插入时向右偏移10像素,向下偏移5像素
sheet->insertImage("D5", logoPath, scaledSize, 10, 5);

// 3. 调整行高列宽
sheet->setColumnWidth(4, 20); // D列宽度
sheet->setRowHeight(5, scaledSize.height() + 10); // 行高略大于图片高度

6.4 图片与单元格内容共存

图片默认浮于单元格上方,可通过调整插入位置实现 "图片 + 文字" 共存(如 Logo 旁添加公司名称)。

代码示例:

cpp 复制代码
// 1. 插入Logo到A1单元格,大小100×40
sheet->insertImage("A1", logoPath, QSize(100, 40));

// 2. 在B1单元格写入公司名称,应用标题格式
QXlsx::Format titleFormat;
titleFormat.setFontSize(16);
titleFormat.setFontBold(true);
sheet->write("B1", "示例科技有限公司", titleFormat);

// 3. 调整行高列宽
sheet->setRowHeight(1, 50);
sheet->setColumnWidth(1, 15); // A列容纳图片
sheet->setColumnWidth(2, 25); // B列容纳文字

效果说明:

A1 单元格显示 Logo,B1 单元格显示公司名称,两者在同一行共存,适合报表页眉设计。

七、图表生成:数据可视化实战

图表是数据可视化的核心工具,QXlsx 支持生成柱状图、折线图、饼图等 10 + 种图表类型,通过Chart类与Worksheet联动实现数据关联。

7.1 图表核心类与接口

Chart类关键接口

Worksheet插入图表接口

7.2 柱状图(最常用图表类型)

柱状图适合对比不同类别的数据(如各部门销售额、各月份产量)。
实现步骤:

  • 准备图表数据(写入工作表);
  • 创建Chart实例(类型为BarChart);
  • 添加数据系列(关联数据范围和分类标签);
  • 设置图表标题、轴标签、样式;
  • 插入工作表并调整位置。

代码示例:

cpp 复制代码
// 1. 准备数据(月份销售额)
sheet->write("A1", "月份");
sheet->write("B1", "销售额(万元)");
sheet->write("A2", "1月"); sheet->write("B2", 125);
sheet->write("A3", "2月"); sheet->write("B3", 98);
sheet->write("A4", "3月"); sheet->write("B4", 156);
sheet->write("A5", "4月"); sheet->write("B5", 132);
sheet->write("A6", "5月"); sheet->write("B6", 148);
sheet->write("A7", "6月"); sheet->write("B7", 165);

// 2. 创建柱状图(垂直方向)
QXlsx::Chart *chart = wb.addChart(QXlsx::Chart::BarChart, QXlsx::Chart::Vertical);

// 3. 添加数据系列(销售额数据:B2-B7,分类标签:A2-A7)
QXlsx::Chart::DataRange dataRange;
dataRange.first = sheet->cellAt(2, 2); // 数据起始单元格(B2)
dataRange.second = sheet->cellAt(7, 2); // 数据结束单元格(B7)
chart->addSeries(dataRange, sheet->cellAt(2, 1), sheet->cellAt(7, 1)); // 分类标签A2-A7

// 4. 设置图表标题
chart->setTitle("2023年上半年销售额趋势");
QFont titleFont("微软雅黑", 12, QFont::Bold);
chart->setTitleFont(titleFont);

// 5. 设置轴标签
chart->setCategoryAxisTitle("月份"); // X轴(分类轴)
chart->setValueAxisTitle("销售额(万元)"); // Y轴(值轴)

// 6. 设置系列样式(柱状图颜色)
chart->setSeriesFillColor(0, QColor(54, 162, 235)); // 系列0(唯一系列)填充蓝色
chart->setSeriesBorderColor(0, QColor(31, 119, 180)); // 边框颜色

// 7. 插入图表到D2单元格,大小600×400
sheet->insertChart("D2", chart, QSize(600, 400));

// 8. 调整数据列宽(避免遮挡)
sheet->setColumnWidth(1, 8);
sheet->setColumnWidth(2, 12);

效果说明:

图表 X 轴显示月份(1 月 - 6 月),Y 轴显示销售额,蓝色柱状图直观对比各月数据,标题和轴标签清晰,适合报表数据展示。

7.3 折线图(展示趋势变化)

折线图适合展示数据随时间的变化趋势(如股价波动、用户增长)。

代码示例:

cpp 复制代码
// 1. 准备数据(月度活跃用户)
sheet->write("A1", "月份");
sheet->write("B1", "活跃用户(万)");
sheet->write("A2", "1月"); sheet->write("B2", 5.2);
sheet->write("A3", "2月"); sheet->write("B3", 6.8);
sheet->write("A4", "3月"); sheet->write("B4", 7.5);
sheet->write("A5", "4月"); sheet->write("B5", 9.1);
sheet->write("A6", "5月"); sheet->write("B6", 8.7);
sheet->write("A7", "6月"); sheet->write("B7", 10.3);

// 2. 创建折线图
QXlsx::Chart *chart = wb.addChart(QXlsx::Chart::LineChart);

// 3. 添加数据系列
QXlsx::Chart::DataRange dataRange;
dataRange.first = sheet->cellAt(2, 2);
dataRange.second = sheet->cellAt(7, 2);
chart->addSeries(dataRange, sheet->cellAt(2, 1), sheet->cellAt(7, 1));

// 4. 设置标题和轴标签
chart->setTitle("2023年上半年活跃用户趋势");
chart->setCategoryAxisTitle("月份");
chart->setValueAxisTitle("活跃用户(万)");

// 5. 设置折线样式
chart->setSeriesLineColor(0, QColor(255, 99, 132)); // 折线颜色(粉红色)
chart->setSeriesLineStyle(0, QXlsx::Chart::LineSolid); // 实线
chart->setSeriesMarkerStyle(0, QXlsx::Chart::MarkerCircle); // 数据点为圆形
chart->setSeriesMarkerSize(0, 8); // 数据点大小

// 6. 插入图表到D2,大小600×400
sheet->insertChart("D2", chart, QSize(600, 400));

效果说明:

折线图清晰展示用户数的上升趋势,数据点用圆形标记,便于观察具体数值,适合趋势分析场景。

7.4 饼图(展示占比关系)

饼图适合展示各部分占总体的比例(如市场份额、费用占比)。

代码示例:

cpp 复制代码
// 1. 准备数据(各渠道流量占比)
sheet->write("A1", "渠道");
sheet->write("B1", "占比(%)");
sheet->write("A2", "官网"); sheet->write("B2", 35);
sheet->write("A3", "APP"); sheet->write("B3", 25);
sheet->write("A4", "小程序"); sheet->write("B4", 20);
sheet->write("A5", "第三方平台"); sheet->write("B5", 20);

// 2. 创建饼图
QXlsx::Chart *chart = wb.addChart(QXlsx::Chart::PieChart);

// 3. 添加数据系列(饼图无需分类轴,直接关联数据和标签)
QXlsx::Chart::DataRange dataRange;
dataRange.first = sheet->cellAt(2, 2);
dataRange.second = sheet->cellAt(5, 2);
chart->addSeries(dataRange, sheet->cellAt(2, 1), sheet->cellAt(5, 1)); // 标签为渠道名称

// 4. 设置标题
chart->setTitle("各渠道流量占比");

// 5. 设置饼图样式(各部分颜色)
QList<QColor> colors = {
    QColor(54, 162, 235),   // 官网:蓝色
    QColor(75, 192, 192),   // APP:青色
    QColor(255, 206, 86),   // 小程序:黄色
    QColor(255, 99, 132)    // 第三方:粉红色
};
for (int i=0; i<colors.size(); i++) {
    chart->setSeriesFillColor(i, colors[i]);
}

// 6. 显示数据标签(占比数值)
chart->setSeriesDataLabels(0, true); // 系列0显示数据标签

// 7. 插入图表到D2,大小500×500
sheet->insertChart("D2", chart, QSize(500, 500));

效果说明:

饼图分为 4 个部分,分别用不同颜色表示,每个部分标注渠道名称和占比,直观展示各渠道的流量贡献。

八、公式与函数:Excel 的计算能力

QXlsx 支持 Excel 的大部分内置函数(如求和、平均值、条件判断),通过向单元格写入公式字符串(以 "=" 开头)实现计算功能。

8.1 常用公式示例

公式类型 示例公式字符串 功能描述 代码示例
求和 =SUM(B2:B5) 计算 B2 到 B5 的总和 sheet->write("B6", "=SUM(B2:B5)"); // 计算B2-B5的和,写入B6
平均值 =AVERAGE(C2:C5) 计算 C2 到 C5 的平均值 sheet->write("C6", "=AVERAGE(C2:C5)");
最大值 =MAX(D2:D5) 取 D2 到 D5 的最大值 sheet->write("D6", "=MAX(D2:D5)");
条件判断 =IF(E2>=60,"及格","不及格") 若 E2>=60 则显示 "及格",否则 "不及格" sheet->write("F2", "=IF(E2>=60,"及格","不及格")"); // 注意转义双引号
计数 =COUNTIF(F2:F5,"及格") 统计 F2-F5 中 "及格" 的个数 sheet->write("F6", "=COUNTIF(F2:F5,"及格")");
日期计算 =DATEDIF(A2,TODAY(),"Y") 计算 A2 日期到今天的年数 sheet->write("B2", "=DATEDIF(A2,TODAY(),"Y")");

8.2 公式使用注意事项

  • 公式前缀:所有公式必须以 "=" 开头,否则会被视为普通文本;
  • 单元格引用:支持相对引用(如B2)和绝对引用(如B2),语法与 Excel 一致;
  • 字符串转义:公式中的双引号需用反斜杠转义(如"及格");
  • 函数兼容性:QXlsx 支持大部分常用函数,但复杂函数(如VLOOKUP、INDEX)需测试验证;
  • 计算时机:公式计算在 Excel 中打开文件时执行,QXlsx 仅负责写入公式字符串,不直接计算结果。

8.3 批量公式应用示例

对学生成绩表批量计算总分、平均分和及格情况:

cpp 复制代码
// 1. 写入成绩数据
sheet->write("A1", "姓名");
sheet->write("B1", "数学");
sheet->write("C1", "语文");
sheet->write("D1", "英语");
sheet->write("E1", "总分");
sheet->write("F1", "是否及格");

sheet->write("A2", "张三"); sheet->write("B2", 85); sheet->write("C2", 92); sheet->write("D2", 78);
sheet->write("A3", "李四"); sheet->write("B3", 65); sheet->write("C3", 58); sheet->write("D3", 72);
sheet->write("A4", "王五"); sheet->write("B4", 90); sheet->write("C4", 88); sheet->write("D4", 95);
sheet->write("A5", "赵六"); sheet->write("B5", 55); sheet->write("C5", 62); sheet->write("D5", 48);

// 2. 批量计算总分(E2-E5)
for (int row=2; row<=5; row++) {
    sheet->write(row, 5, QString("=SUM(B%1:D%1)").arg(row)); // 求和公式:SUM(B2:D2)、SUM(B3:D3)...
}

// 3. 批量判断是否及格(F2-F5,总分>=180为及格)
for (int row=2; row<=5; row++) {
    sheet->write(row, 6, QString("=IF(E%1>=180,\"及格\",\"不及格\")").arg(row));
}

// 4. 计算班级平均分(E6)
sheet->write("E6", "=AVERAGE(E2:E5)");

// 5. 计算及格人数(F6)
sheet->write("F6", "=COUNTIF(F2:F5,\"及格\")");

九、高级功能:数据验证、批注与打印设置

除基础功能外,QXlsx 还支持数据验证(限制输入)、单元格批注(添加说明)、打印设置(页眉页脚、页边距)等高级功能,进一步提升表格的实用性。

9.1 数据验证(限制单元格输入)

数据验证可限制单元格的输入范围(如仅允许整数、日期或特定列表值),防止无效数据录入。

void dataValidation(int firstRow, int firstCol, int lastRow, int lastCol, const DataValidation &validation);为单元格区域添加数据验证,其中firstRow-lastCol:区域范围;validation:验证规则。

cpp 复制代码
// 1. 创建数据验证规则(仅允许输入1-100的整数)
QXlsx::DataValidation validation;
validation.setType(QXlsx::DataValidation::Whole); // 整数类型
validation.setOperator(QXlsx::DataValidation::Between); // 范围之间
validation.setFormula1("1"); // 最小值1
validation.setFormula2("100"); // 最大值100
validation.setInputTitle("输入提示");
validation.setInputMessage("请输入1-100之间的整数");
validation.setErrorTitle("输入错误");
validation.setErrorMessage("请输入1-100之间的整数!");

// 2. 为C2-C10区域应用验证规则(假设为分数列)
sheet->dataValidation(2, 3, 10, 3, validation); // C2到C10

效果说明:

在 Excel 中向 C2-C10 输入 101 或 - 5 时,会弹出错误提示,确保数据合法性。

9.2 单元格批注(添加说明文字)

批注用于对单元格内容添加额外说明(如数据来源、特殊备注),支持格式设置。

bool writeComment(int row, int col, const QString &text, const Format &format = Format());为单元格添加批注,其中: row/col:单元格位置;text:批注内容;format:批注文本格式。

cpp 复制代码
// 1. 定义批注文本格式
QXlsx::Format commentFormat;
commentFormat.setFontSize(10);
commentFormat.setFontColor(Qt::darkBlue);

// 2. 为B2单元格添加批注(说明销售额包含优惠)
sheet->writeComment(2, 2, "注:本销售额已扣除春节期间的优惠活动金额", commentFormat);

// 3. 为D5单元格添加多行批注
QString multiLineComment = "数据来源:市场部Q3报告\n"
                          "统计范围:国内地区(不含港澳台)";
sheet->writeComment(5, 4, multiLineComment);

十、常见问题与处理方法

10.1 接口使用常见问题

中文乱码

原因:QXlsx 默认 UTF-8 编码,Excel 打开时可能使用其他编码;

解决:写入中文时确保字符串为 UTF-8(Qt 默认支持),或在xlsxsharedstrings.cpp中强制设置编码为 UTF-8。
公式不生效

原因:公式未加 "=" 前缀,或函数名称拼写错误;

解决:确保公式以 "=" 开头(如=SUM(A1:A5)而非SUM(A1:A5)),检查函数名称是否与 Excel 一致(区分大小写)。
图片插入失败

原因:图片路径错误,或图片格式不支持(如 SVG);

解决:使用绝对路径(QCoreApplication::applicationDirPath()),确保图片为 PNG/JPG/BMP 格式。
大数据写入卡顿

原因:一次性写入 10 万行 + 数据,主线程阻塞;

解决:分块写入并调用QCoreApplication::processEvents()释放线程(每 1000 行一次)。

10.2 最佳实践

  • 格式复用:避免重复创建Format对象(如表头格式可全局定义一次,多次使用),减少内存占用;
  • 路径处理:使用QCoreApplication::applicationDirPath()获取程序目录,避免硬编码路径;
  • 错误处理:对load()、saveAs()、insertImage()等返回bool的函数进行结果判断,确保操作成功;
  • 版本兼容:Qt 6 需在.pro中添加DEFINES += QXLSX_QT6,避免编译错误;
  • 性能优化:大数据场景使用writeArray()批量写入,禁用不必要的格式和图表。

总结

QXlsx 作为 Qt 生态中操作 Excel 的佼佼者,其核心类接口覆盖了从基础数据读写到高级图表生成的全场景需求。本文系统解析了Workbook「工作簿管理」、Worksheet「单元格操作」、Format「样式控制」、Chart「图表生成」等核心类的接口函数,通过代码例子详解了表头设置、字体颜色、图片插入、图表生成等主流应用。

掌握这些接口的关键在于理解 "类之间的层级关系"------ 以Workbook为起点,通过Worksheet操作具体内容,用Format美化样式,借Chart实现可视化。结合最佳实践(如格式复用、错误处理),可高效开发出专业级的 Excel 报表功能。

QXlsx 的灵活性与轻量级特性,使其在跨平台 Qt 项目中无可替代。无论是简单的数据导出,还是复杂的可视化报表,QXlsx 都能满足需求,是 Qt 开发者必备的技能之一。

相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能13 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G13 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt