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 开发者必备的技能之一。

相关推荐
长沙红胖子Qt8 小时前
关于 Qt5.x版本离线安装可以跳过登录但是实际离线仍需要登录 的解决方法
qt·离线安装·离线无法skip
友友马8 小时前
『 QT 』QT控件属性全解析 (二)
开发语言·数据库·qt
大米粥哥哥16 小时前
Qt QProcess基于Linux的命令管道符号无效问题【已解决】
linux·qt·shell·qprocess·1024程序员节·管道符号
mengzhi啊20 小时前
QT实现消息未读提示
qt
mengzhi啊20 小时前
qt实现带数字的消息通知
qt
十日十行21 小时前
信号槽连接不上的可能
qt
Source.Liu1 天前
【CMakeLists.txt】QtSvg 头文件包含配置详解
c++·qt·librecad
sulikey1 天前
Qt 入门简洁笔记:从框架概念到开发环境搭建
开发语言·前端·c++·qt·前端框架·visual studio·qt框架
sulikey1 天前
Qt 入门简洁笔记:信号与槽
前端·c++·笔记·qt·前端框架·1024程序员节·qt框架