QT 使用第三方库QtXlsx操作Excel表
1.简介
一直以来,都想学习一下C/C++如何操作excel表,在网上调研了一下,觉得使用C/C++去操作很麻烦,遂转向QT这边;QT有一个自带的类QAxObject,可以使用他去操作,但随着了解的深入,觉得他并不是很好,有很多其他缺陷(例如必须电脑安装了办公软件才可以进行操作等),所以继续调研,终于找到了QT的一个第三方库可以很好的实现:QtXlsx.
Github下载:https://github.com/dbzhang800/QtXlsxWriter
官方文档:http://qtxlsx.debao.me/
在Github下载后,可以直接添加到QtCreator项目中,也可以编译成lib库后再添加到VS中去使用。
2、下载QtXlsx
点击链接进入Github下载

下载解压后得到如下文件

二、QtXlsx源码嵌入QTCreator中使用
新建一个QTCreator窗体项目
将上图src文件夹拷贝到该项目路径中

之后双击项目中的.pro文件
将如下代码拷贝到.pro文件中
include(src/xlsx/qtxlsx.pri)

Ctrl + s 保存一下,就可以把QtXlsx源码模块加载进来啦!
可以在项目构造函数中添加如下代码进行测试:
#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"QXlsx::Document xlsx;
xlsx.write(1, 2, "Hello Qt!");
xlsx.write(2, 2, QString::fromLocal8Bit("中文"));
xlsx.saveAs("Text.xlsx");
编译运行后,就可以在项目路径看到程序创建的Text.xlsx文件,打开后就可以看到写入的 "Hello Qt!"和"中文".
三、QtXlsx源码编译成为.lib库使用
1. 下载安装Perl
下载安装:Perl
下载链接:Strawberry Perl for Windows

注意,这个是一定要下载安装的,否则编译lib库会编译失败!!!
下载后默认安装即可

2. 编译QtXlsx
打开下载的QtXlsx文件夹,双击打开.pro

根据自己安装的vs版本,选择相应的msvc编译

打开后直接点击编译

编译完成后,就可以在相应路径找到编译好的lib库

3. 在vs中使用
新建vsQT项目,将include文件夹和Qt5Xlsxd.dll和Qt5Xlsxd.lib拷贝到项目路径中;
将QtXlsxWriter-master文件夹整个拷贝到项目路径中;

拷贝之后项目路径文件,下图方框中的就是我们需要拷贝的文件

右键项目 - 属性 - C/C++ - 常规 - 附加包含目录,把头文件路径添加进来

右键项目 - 属性 - 链接器 - 输入 - 附加依赖项,添加Qt5Xlsxd.lib
之后,可以加入头文件
#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"
在构造函数中加入代码
QXlsx::Document xlsx;xlsx.write(1, 2, "Hello Qt!");xlsx.write(2, 2, QString::fromLocal8Bit("中文"));xlsx.saveAs("Text.xlsx");
编译运行,不出意外的话, 在项目路径会一个名为Text.xlsx的文件,双击打开

数据也已经写入,测试成功!
四、QtXlsx
1. 知识点
a. 定义
QXlsx::Document xlsx;QXlsx::Document xlsx("Text.xlsx");
b. 往单元格中写入数据
writexlsx.write(2, 2, "中文"); 参数一是行,参数二是列,参数三是数据xlsx.write("C3", "C3"); 参数一是对应单元格名字,参数二是数据
c. 设置行高
setRowHeightxlsx.setRowHeight(4, 30); 设置第四行高度为30
d. 设置列宽
setColumnWidthxlsx.setColumnWidth(3, 50); 设置第三列宽度为50
e. 设置单元格样式
QXlsx::Format format;format.setFontColor(Qt::red); // 设置字体颜色为红色format.setFontBold(true); // 设置加粗format.setFontSize(30); // 设置字体大小format.setFontItalic(true); // 设置倾斜format.setFontName("楷体"); // 设置字体format.setPatternBackgroundColor(QColor(100, 200, 100)); // 设置单元格背景颜色format.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置水平居中,更多参考enum HorizontalAlignment枚举format.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置垂直居中format.setBorderColor(QColor(50, 50, 50)); // 设置边框颜色format.setFontUnderline(QXlsx::Format::FontUnderlineDouble); // 设置双下划线,更多参考enum FontUnderline枚举format.setFontUnderline(QXlsx::Format::FontUnderlineSingle); // 设置单下划线format.setFillPattern(QXlsx::Format::PatternLightUp); // 填充方式,更多参考enum FillPattern枚举xlsx.write("C4", "红色|加粗|30", format); 作为第三个参数
f. 设置单元格方框
setBorderStyleformat.setBorderStyle(QXlsx::Format::BorderThin); 更多参考enum BorderStyle枚举
g. 合并单元格
mergeCellsxlsx.mergeCells("C4:E6"); 参数指定那个单元格区间
h. 取消合并
unmergeCellsxlsx.unmergeCells("C4:E6"); 参数指定的单元格区间一定是要已经合并的,否则打开xlsx文件报错
i. 读取单元格中的数据
readQString str1 = xlsx.read(1, 1).toString(); 指定行列获取QString str2 = xlsx.read("B2").toString(); 指定单元格名字获取
j. 获得单元格对象
cellAtQXlsx::Cell *cell = xlsx.cellAt("C4"); 获取到的是指针对象QXlsx::Cell *cell = xlsx.cellAt(1, 1);cell->value(); 可以通过value()函数获取单元格中的值
k. 添加工作表
addSheetxlsx.addSheet("sheet_2"); 添加这一张名为“sheet_2”的工作表
l. 工作表重命名
renameSheetxlsx.workbook()->renameSheet(1, "sheet_3"); 将索引为1(也就是第二张)的工作表命名为“sheet_3”
m. 选择当前工作表
selectSheetxlsx.selectSheet("sheet_3"); 选择名为“sheet_3”的工作表为当前xlsx工作表
n. 获得所有工作表的名字
sheetNames
QStringList sheetList = xlsx.sheetNames(); 获取返回的是一个字符串链表
o. 获取工作簿对象
workbookQXlsx::Workbook *workBook = xlsx.workbook();
p. 获取当前工作簿的第一张sheet工作表
QXlsx::Worksheet *workSheet = static_cast<QXlsx::Worksheet*>(workBook->sheet(0));
q. 获取当前sheet表所使用到的行数
int row = workSheet->dimension().rowCount();
r. 获取当前sheet表所使用到的列数
int colum = workSheet->dimension().columnCount();
s. 遍历sheet表中有数据的单元格
for (int i = 0; i < row; i++) { for (int j = 0; j < colum; j++) { // 获取单元格 QXlsx::Cell *cell = workSheet->cellAt(i, j); // 读取单元格 if (cell) { qDebug() << "(" << i << ", " << j << ")\t" << cell->value().toString().trimmed(); // trimmed 去除字符串两侧的空格 } }
}
t. 删除单元格数据
xlsx.write("G5", ""); 直接重新设置为空即可
u. 修改单元格数据
xlsx.write("G6", "修改"); 重新对单元格写入数据即可
v. 保存
saveAsxlsx.saveAs("Text.xlsx"); 初始化xlsx对象时没有指定excel文件,那么保存时使用这个savexlsx.save(); 初始化xlsx对象时,指定了excel文件,那么保存时使用这个
w. 设置单元格中字符串不同字体颜色
RichString
QXlsx::Document xlsx("Text.xlsx"); QXlsx::Format blue; // 设置字体颜色
blue.setFontColor(Qt::blue);
QXlsx::Format red;
red.setFontColor(Qt::red);
red.setFontSize(20); // 设置字体大小
QXlsx::Format bold;
bold.setFontBold(true); // 设置字体加粗 QXlsx::RichString rich;
rich.addFragment("test", blue);
rich.addFragment("QT", red);
rich.addFragment("中文", bold); xlsx.write("C3", rich); xlsx.save();

x. 给单元格命名
xlsx.defineName("Cell_1", "=Sheet1!$A$1:$A$10"); // A1-A10命名为Cell_1
xlsx.defineName("Cell_2", "=Sheet1!$B$1:$B$10", "这是描述信息"); // B1-B10命名为Cell_2

y. 赋值
xlsx.defineName("Factor", "=0.5"); // 将0.5赋值给Factor,相当于变量赋值一样,我们就可以使用这个变量了
z. 使用公式
xlsx.write(11, 1, "=SUM(Cell_1)"); // 计算A1-A10数据总和,并写入(11,1)单元格中
xlsx.write(15, 1, "=SUM($A$1:$A$10)"); // 计算A1-A10数据总和,并写入(15,1)单元格中
使用公式和变量
xlsx.write(12, 1, "=SUM(Cell_1)*Factor"); // 计算A1-A10数据总和再乘以0.5,并写入(12,1)单元格中
xlsx.write(16, 1, "=SUM($A$1:$A$10)*Factor"); // 计算A1-A10数据总和再乘以0.5,并写入(16,1)单元格中
xlsx.write(13, 2, "=SUM($B$1:B$10)*0.1"); // B1 - B10 计算总和后乘以0.1
五、QtXlsx知识点补充
1.QStringList sheetNames() const
2.bool addSheet(const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
3.bool insertSheet(int index, const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
4.bool renameSheet(const QString &oldName, const QString &newName)
5.bool moveSheet(const QString &srcName, int distIndex)
6.bool deleteSheet(const QString &name)
7.AbstractSheet *Document::sheet(const QString &sheetName) const
8.AbstractSheet::SheetState AbstractSheet::sheetState() const
9.void AbstractSheet::setSheetState(SheetState state)
10.bool AbstractSheet::isHidden() const
11.bool AbstractSheet::isVisible() const
12.void AbstractSheet::setHidden(bool hidden)
13.void AbstractSheet::setVisible(bool visible)\
14.Chart *Document::insertChart(int row, int col, const QSize &size)
15.void Chart::setChartType(ChartType type)
16.void Chart::addSeries(const CellRange &range, AbstractSheet *sheet, bool headerH, bool headerV, bool swapHeaders)
17.void Chart::setChartLegend(Chart::ChartAxisPos legendPos, bool overlay)
18.void Chart::setChartTitle(QString strchartTitle)
19.void Chart::setGridlinesEnable(bool majorGridlinesEnable, bool minorGridlinesEnable)
20.int Document::insertImage(int row, int column, const QImage &image)
21.uint Document::getImageCount()
22.bool Document::getImage(int imageIndex, QImage& img)
23.bool Document::getImage(int row, int col, QImage &img)
不错的连接:https://blog.csdn.net/qq_43627907/category_11756312.html
相关文章:
QT 使用第三方库QtXlsx操作Excel表
1.简介 一直以来,都想学习一下C/C如何操作excel表,在网上调研了一下,觉得使用C/C去操作很麻烦,遂转向QT这边;QT有一个自带的类QAxObject,可以使用他去操作,但随着了解的深入,觉得他…...
警惕网络个人技术人员:隐藏代码风险的启示
在当今数字化时代,我们对网络上个人技术人员的需求日益增加,这使得技术服务成为一项不可或缺的资源。然而,我最近的经历却引发了我对这种服务可靠性的怀疑,特别是当这些个人技术人员没有正式公司背景,缺乏可信的运营保…...
VBA 学习笔记1 对象以及属性
目录 1 取得VBA对象1.1 取得工作簿对象1.2 取得工作表对象1.3 取得单元格对象1.4 取得对象的属性1.5 文档的方法1 进入vba 界面 方式之一: 快捷键:ALTERF11 运行方式之一: 进入vba界面,点击绿色三角符号 1 取得VBA对象 1.1 取得…...
netty核心组件以及实现原理
Netty核心组件 网络通信层:这一层有三个核心组件:Bootstrap、ServerBootStrap和Channel。Bootstrap负责客户端的启动,并用来链接远程Netty Server;ServerBootStrap负责服务端监听,用来监听指定端口;Channe…...
如何正确下载tomcat???
亲爱的小伙伴,千万别再去找下网站下载啦,这样詪容易携带病毒。 我们去官方网址下载。 Apache Tomcat - Welcome! 最后下载解压即可。。。...
mybatis-plus 根据指定字段 批量 删除/修改
mybatis-plus 提供了根据id批量更新和修改的方法,这个大家都不陌生 但是当表没有id的时候怎么办 方案一: 手写SQL方案二: 手动获取SqlSessionTemplate 就是把mybatis plus 干的事自己干了方案三 : 重写 executeBatch 方法结论: mybatis-plus 提供了根据id批量更新和修改的方法,…...
MQTT宝典
文章目录 1.介绍2.发布和订阅3.MQTT 数据包结构4.Demo5.EMQX 1.介绍 什么是MQTT协议 MQTT(消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协…...
【前端】CSS水平居中的6种方法
文章目录 flex绝对定位margin:auto绝对定位margin:负值定位transformtext-align: center;margin: 0 auto;思维导图 后文:【前端】CSS垂直居中的7种方法_karshey的博客-CSDN博客 左右两边间隔相等的居中 flex display: flex;justify-content: center; <div clas…...
nginx如何获取真实的ip
我这里使用是springboot项目,使用nginx做代理,但header里面的参数没有将ip带过来,所有需要配置nginx将ip带过来。 nginx.conf文件 server {listen 80;listen 443 ssl;server_name xxx.xxx.com;ssl_certificate /web/project/ai…...
kotlin + LiveData 测试
viewModel测试:https://developer.android.com/codelabs/basic-android-kotlin-compose-test-viewmodel#3 androidTestImplementation "org.jetbrains.kotlin:kotlin-test:1.9.0"androidTestImplementation org.jetbrains.kotlinx:kotlinx-coroutines-tes…...
【dnf5文档】新一代RedHat自动化包管理器
前言 HI,CSDN的码友们,距离上一次我发文章已经过去了半年的时间,现在我又来介绍自己新发现和探究的开源技术了。计算机的发展总是飞速的,当我在写这篇文章的时候,Fedora rawhide已经进入了40版本、默认采用的自动化包管理器为dnf…...
数据可视化工具的三大类报表制作流程分享
电脑(pc)、移动、大屏三大类型的BI数据可视化报表制作步骤基本相同,差别就在于尺寸调整和具体的报表布局。这对于采用点击、拖拉拽方式来制作报表的奥威BI数据可视化工具来说就显得特别简单。接下来,我们就一起看看不这三大类型的…...
lua使用心得
lua语言的一些注意事项 在控制结构的条件中除了false和nil为假,其他值都为真。所以Lua认为0和空串都是真。lua5.3之前的版本只支持浮点数,lua5.3才引入了对整数的支持,/仅支持浮点数除法,要实现C里的整除效果必须使用双斜杠//超过…...
Docker升级后,出现Error response from daemon: Unknown runtime specified docker-runc
现象:docker升级版本后,重启docker服务出现: [rootDocker scripts]# docker start registry Error response from daemon: Unknown runtime specified docker-runc Error: failed to start containers: registry解决办法: 改完之…...
[Poetize6] IncDec Sequence
题目描述 给定一个长度为 n 的数列 a_1,a_2,...,a_n,每次可以选择一个区间[l,r],使这个区间内的数都加 1 或者都减 1。 请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多…...
通过Microsoft Loopback Adapter实现虚拟机和物理机的通信
问题 问:不借助路由器或交换机的情况下,能不能实现主机和虚拟及之间两个软件的通信呢?要求主机和虚拟及均有独立的ip地址,从而进行指定源的组播通信。 答:可以。通过借助虚拟网络适配器,不需要路由器或交…...
算法leetcode|70. 爬楼梯(rust重拳出击)
文章目录 70. 爬楼梯:样例 1:样例 2:提示: 分析:题解:rust:go:c:python:java: 70. 爬楼梯: 假设你正在爬楼梯。需要 n 阶你才能到达楼…...
基于epoll的TCP服务器端(C++)
网络编程——C实现socket通信(TCP)高并发之epoll模式_tcp通信c 多客户端epoll_n大橘为重n的博客-CSDN博客 网络编程——C实现socket通信(TCP)高并发之select模式_n大橘为重n的博客-CSDN博客 server.cpp #include <stdio.h> #include <sys/types.h> #include <…...
实时安全分析监控加强网络安全
网络犯罪分子只需几分钟,有时甚至几秒钟即可泄露敏感数据。但是,IT 团队可能无法在数周内发现这些违规行为。通常,这些违规行为是由外部方或客户发现的,到那时为时已晚。随着网络漏洞的激增,对安全分析的需求空前高涨。…...
基于ipad协议的gewe框架进行微信群组管理(二)
友情链接 geweapi.com 点击访问即可。 获取群组详情 小提示: 该接口可以一次查询20个群组查询出来的信息是不带公告的 请求URL: http://域名地址/api/group/detail 请求方式: POST 请求头: Content-Type:applica…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
