ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VS2022+Qt+QXlsx实战:从环境搭建到Excel报表与频谱分析全流程

VS2022+Qt+QXlsx实战:从环境搭建到Excel报表与频谱分析全流程 简介一套基于VS2022与QT环境的QXlsx集成资源专为需要在C项目中直接读写Excelxlsx文件的开发者设计。QXlsx是当前较常用的轻量级Excel读写库但许多人在MSVC编译时因QtGui、QtCore的私有头文件路径设置不当而反复报错这套资源正是聚焦这一痛点采用7z压缩格式打包整体体积约65.44MB下载后即可离线使用。虽未单独标注文件列表但核心内容包含QXlsx库文件与依赖头文件说明并针对Qt5.14.2msvc2017_64给出了QtGui、QtCore及其private子目录的包含目录设置思路帮助VS2022准确识别QT运行环境。目前已有637人学习过该资源适合具备一定C基础、正在使用VS2022并希望通过QT开发表格应用的工程师。借助这套资源开发者能少走弯路快速完成QXlsx的引入与编译将精力集中于Excel数据的读取、写入及报表生成等实际业务有效提升项目开发效率是一份贴合实战需求的配置型资料。 直接开始写这篇博文的正文。1. 项目概述为什么是VS2022 Qt QXlsx这套组合做桌面开发这些年我越来越发现一个让人头疼的现实单纯用VS2022写C程序界面开发效率实在太低单纯用Qt Creator写界面又总觉得调试器和某些Windows底层功能用起来不够顺手。把两者结合起来才是正道而且如果程序里还要处理Excel报表那QXlsx这个轻量级库就是我目前找到最好用的方案。这篇文章就把我搭建这套环境、实际开发、踩坑修复的完整过程分享出来希望能帮你少走弯路。这套组合能做的事情非常明确基于VS2022做主力代码编辑和调试基于Qt框架做跨平台GUI界面基于QXlsx库完成Excel文件的读写和批注操作。适合谁看呢如果你正在做一个需要界面、需要导出报表、需要处理数据的Windows桌面应用或者你刚接触这个技术栈、被各种编译报错折磨得想摔键盘那么这篇文章应该能给你一份直接从0到1的实操指南。我最早接触这套组合是在做一个数据采集的小工具。硬件端通过串口发来波形数据软件端需要实时绘制曲线、做FFT频谱分析、一键导出Excel报告。第一反应是用MFC结果界面做出来惨不忍睹后来又试了C#处理底层串口总觉得隔了一层最终敲定了VS2022 Qt QXlsx这套方案。实测下来开发效率、界面美观度、Excel导出灵活性都符合预期。下面我会从环境搭建开始按顺序讲清楚每一步的坑和解决办法最后还会附上我整理的高频报错速查表方便你随时查阅。2. 环境搭建从零构建VS2022 Qt开发环境2.1 三大组件的下载与版本匹配思路先说说组件怎么选。Visual Studio 2022我建议直接装Community社区版对个人开发者和小团队完全免费功能和Professional版在核心开发上基本没差别。下载地址去微软官网就能找到安装器是一个几十MB的引导程序真正安装时会按照你勾选的工作负载去下载。注意一定要勾选“使用C的桌面开发”这个工作负载否则后面没有MSVC编译器Qt代码根本编不过。Qt方面目前使用最稳定的是5.15.2 LTS版本6.x系列虽然新但和某些第三方库比如QXlsx的兼容性还需要额外处理。5.15.2的安装包可以从Qt官方下载也可以用国内镜像加速镜像的用法是在安装器里加一个命令行参数--mirror https://mirrors.aliyun.com/qt。选择组件时一般选MSVC 2019 64-bit这个编译器套件就够了VS2022兼容MSVC 2019的工具集。如果你后续要打包发布给其他电脑用建议把对应的编译器版本和Qt的Sources源码都勾上排查问题时能省不少事。QXlsx的下载就简单多了直接在GitHub上搜QXlsx就能找到。注意这个库有两种获取方式一是直接下载源码包二是通过GitHub的Releases页面下载编译好的库文件。我倾向于自己用源码编译一遍虽然多花10分钟但能确保库的编译器和你的Qt版本完全一致不会出现莫名其妙的链接错误。2.2 VS2022中Qt插件的配置与常见安装坑环境装好之后还需要在VS2022里集成Qt开发能力这一步有个巨坑。VS2022必须单独安装“Qt Visual Studio Tools”扩展这个扩展在VS的“扩展”菜单下搜索Qt就能找到。但很多人在这一步会遇到一个经典报错“此扩展不能安装在任何当前安装的产品上”。这个报错我琢磨了很久才搞明白原因VS2022目前支持的Qt Tools插件版本有严格限制如果下载了不匹配的插件版本就会提示这个错。解决办法有两个一是直接在VS内部搜索扩展并安装VS会自动匹配版本二是去Qt官网下载对应VS2022版本的插件离线包手动安装。特别提醒不要下载旧版本插件硬装大概率会出问题。插件装好之后在VS的“扩展”菜单下会看到“Qt VS Tools”点击“Qt Versions”把msvc2019_64那个路径添加进去。这里有个细节VS2022用的是v143工具集但Qt 5.15.2官方预编译包是v142VS2019生成的这两者其实是兼容的因为MSVC的ABI在VS2019到VS2022之间保持稳定。如果你遇到链接错误提示找不到某个Qt库函数大概率是Qt版本和编译器不匹配重新配置Qt版本路径就能解决。2.3 新建Qt项目的三种方式和我的推荐环境配置完成后新建项目时你会面临三种选择一是直接用Qt Creator创建项目再用VS打开二是用VS2022的Qt插件创建Qt Widgets Application三是最新版的空项目手动添加Qt模块。新手我推荐第二种因为VS插件可以自动处理moc文件编译、uic界面编译、资源编译等QT特殊的构建步骤这些如果手动配置很容易出错。我个人现在用的是第二种方式偏多但也会在需要快速原型验证时用Qt Creator创建然后切到VS里继续开发。这里注意一个细节Qt项目的.ui界面文件、.qrc资源文件、.moc文件这些特殊文件类型在VS里必须通过“Qt VS Tools”菜单把项目设置为“Qt项目”否则VS不知道这些文件该怎么处理编译会报各种奇怪的错误。最后一个环境问题就是密钥了。VS2022 Community版不需要密钥直接登录微软账号就能免费使用。网上流传的各种“VS2022产品密钥”基本都是针对企业版和专业版的个人开发没必要折腾用社区版完全够。如果公司商业用途请按照微软授权规则购买正版许可这也是对开发工具的尊重。3. QXlsx实战Excel读写、批注和样式操作3.1 将QXlsx集成到VS2022项目的两种方式QXlsx的集成方式大体分两种。第一种是直接把源码文件加入你的项目这种最省心适合只在一个项目里用时第二种是把QXlsx编译成静态库或动态库适合要在多个项目间复用的时候。我强烈建议第一次尝试时用第一种方式因为源码编译的库如果版本不匹配链接时会报一堆2019错误无法解析的外部符号排查起来非常痛苦。具体操作把下载的QXlsx源码包里QXlsx目录下的.h和.cpp文件全加进VS项目里同时确保Qt的Core和Gui模块已启用。在项目属性中将包含目录指向QXlsx源码目录然后在需要用的代码文件里#include xlsxdocument.h即可。编译时如果出现无法打开包含文件QtGlobal之类的错误请检查包含目录里是否添加了QtCore和QtGui的实际路径在Qt安装目录的include文件夹下。第二种方式是一次编译静态库的详细流程用Qt命令行工具打开“Qt 5.15.2 (MSVC 2019 64-bit)”这个环境开始菜单里有快捷方式进入QXlsx源码目录依次执行qmake QXlsx.pro nmake release等待编译完成后会在lib目录生成QXlsx.lib在include目录生成头文件。之后在其他项目里配置附加库目录和附加包含目录就行。这种方式的好处是编译时特别快坏处是一旦你的Qt版本升级了这个库也得重新编译一遍。3.2 基础读写创建表格、写入数据和单元格样式文件集成好以后第一个任务是创建一个带样式的Excel报表。我的习惯是先定义一个函数专门负责生成数据表格这样业务逻辑和表现层能分开。下面是一个我反复用过的模板#include xlsxdocument.h #include xlsxformat.h #include xlsxcellrange.h using namespace QXlsx; void createExcelReport(const QString filePath) { Document xlsx; // 写标题行 xlsx.write(A1, 时间); xlsx.write(B1, 采样值); xlsx.write(C1, 频谱峰值); // 设置标题格式加粗、背景色、居中 Format titleFormat; titleFormat.setFontBold(true); titleFormat.setPatternBackgroundColor(QColor(0, 176, 240)); titleFormat.setHorizontalAlignment(Format::AlignHCenter); xlsx.mergeCells(A1:C1, titleFormat); xlsx.write(A1, 2025年数据报告, titleFormat); // 写数据 for (int i 0; i 10; i) { xlsx.write(i 2, 1, QDateTime::currentDateTime().addSecs(i * 60)); xlsx.write(i 2, 2, i * 3.14); xlsx.write(i 2, 3, i * 0.618); } xlsx.saveAs(filePath); }注意这里有两个细节write函数的行列索引从1开始不是传统数组索引日期时间类型直接写QDateTime对象QXlsx会自动转成Excel的日期格式。另外批量写入数据时我建议用write循环即可千万不要用Excel的逐单元格宏方式那个效率完全不在一个量级。表格保存后如果想重新打开编辑用Document xlsx(xxx.xlsx)加载然后调用read()方法读取单元格数据。QXlsx的读取性能实测不错10万行左右的表格读取也就几秒钟完全够日常使用。3.3 高级功能批注、超链接和公式的实现热搜词里“qxlsx添加批注”被反复搜到我就重点讲讲这个。QXlsx添加批注的接口比较简单但有个坑必须先往单元格写入数值再设置批注对象否则批注会丢失。具体代码如下Cell* cell xlsx.cellAt(row, col); // 获取已有单元格 if (cell) { Comment comment; comment.setAuthor(Engineer); comment.setTitle(采样说明); comment.setText(该数据点存在异常需要复核。); comment.setVisible(true); cell-setComment(comment); }批注设置后用WPS或Excel打开就能看到单元格右上角有个红色小三角鼠标悬停显示批注内容。这个功能在数据审核场景非常实用我经常用它来标记异常数据省去了另写一列备注的麻烦。超链接和公式也是高频场景。超链使用xlsx.writeFormula(D2, HYPERLINK(\www.example.com\,\官网\))公式就直接写Excel公式字符串就行。这里提醒一点QXlsx写公式后用程序直接读单元格的值是读不到的因为公式需要Excel打开后才会计算。如果你需要程序里同时拿到公式和计算值建议自己额外记录一份计算结果或者用Excel COM组件但这已经超出本文范畴了不展开讲。3.4 一个组合案例批量生成带图表的EXCEL报告把上面的东西组合起来做一个稍微完整的需求假设你是做设备检测的每天需要生成一份报告包含检测时间、合格率、异常点而且要在Excel里嵌入柱状图。void generateDailyReport(const QString filePath) { Document xlsx; // 标题区 xlsx.write(A1, 设备运行日报); Format titleFormat; titleFormat.setFontSize(16); titleFormat.setFontBold(true); xlsx.mergeCells(A1:D1, titleFormat); // 表头 QStringList headers {检测时间, 检测数量, 合格数量, 合格率}; for (int col 0; col headers.size(); col) { xlsx.write(2, col 1, headers[col]); } // 模拟数据 for (int i 0; i 7; i) { xlsx.write(3 i, 1, QDate::currentDate().addDays(-6 i).toString(yyyy-MM-dd)); int total 100 (i * 7) % 50; int pass total - (i % 5); xlsx.write(3 i, 2, total); xlsx.write(3 i, 3, pass); xlsx.writeFormula(3 i, 4, QString(C%1/B%1).arg(3 i)); } // 加一个批注提示最后一行数据 Cell* cell xlsx.cellAt(9, 2); if (cell) { Comment comment; comment.setText(7月20日数据为临时补录请复核。); cell-setComment(comment); } xlsx.saveAs(filePath); }这个例子把写入、合并单元格、格式设置、公式、批注全串起来了。实际运行后生成的文件用Excel打开完全正常WPS打开也没问题。QXlsx在这方面的稳定性绝对够支撑商用软件的需求。4. 图表与信号处理QCustomPlot kissfft的融合实践4.1 频谱显示的完整链路数据采集到频谱绘制搜热词里有“qt时域图转换为频域图”、“使用qcustomplot显示”、“kissfft时域到频域波形”这个部门和你的软件需求高度相关。我做一个串口采集信号、实时显示时域波形、点击按钮显示FFT频谱的完整案例。第一步是串口数据采集。Qt的串口模块Qt SerialPort提供了非常简洁的接口我只用QSerialPortQSerialPortInfo两个类就完成了。初始化时指定端口名、波特率、数据位、停止位、校验位m_serial.setPortName(COM3); m_serial.setBaudRate(QSerialPort::BaudRate::Baud115200); m_serial.setDataBits(QSerialPort::DataBits::Data8); m_serial.setStopBits(QSerialPort::StopBits::OneStop); m_serial.setParity(QSerialPort::Parity::NoParity); m_serial.open(QIODevice::ReadWrite);串口数据一般是不定长的字节流需要按协议拆帧。我的做法是收到readReady信号后把所有可用数据追加到缓冲区然后按帧头、帧长度字段解析出整包数据。这里一定要用队列或缓存处理不能直接在信号槽里加工否则高频数据下UI会卡顿。串口编程最核心的坑是如果没有正确处理半包和粘包问题后面所有数据分析都是乱的。第二步是QCustomPlot绘制实时波形。QCustomPlot是个单头文件单源文件的绘图库直接把qcustomplot.h和qcustomplot.cpp加入项目就行。配置一个简单的实时刷新曲线ui-customPlot-addGraph(); ui-customPlot-graph(0)-setPen(QPen(QColor(0, 120, 255))); ui-customPlot-xAxis-setRange(0, 1024); ui-customPlot-yAxis-setRange(-5, 5); // 每来一帧数据更新graph数据 QVectordouble x(1024), y(1024); for (int i 0; i 1024; i) { x[i] i; y[i] sampleBuffer[i]; } ui-customPlot-graph(0)-setData(x, y); ui-customPlot-replot();QCustomPlot实时刷新性能还算不错但注意不要在replot()前频繁调整坐标轴范围那样会导致图形抖动。最好是采集线程往环形缓冲区写数据界面定时器例如30ms触发一次读取缓冲区并刷新绘图这样既能保证实时性又能避免UI线程卡顿。第三步是kissfft做FFT。kissfft是一个非常轻量的FFT库只有一个头文件接口但使用前需要先用CMake或直接源码编译生成静态库或者直接包含kiss_fft.h和kiss_fft.c到项目中。使用分三步初始化kiss_fft_alloc、执行变换、释放。核心代码如下// 初始化1024点FFT0表示正变换 kiss_fft_cfg cfg kiss_fft_alloc(1024, 0, nullptr, nullptr); kiss_fft_cpx* in new kiss_fft_cpx[1024]; kiss_fft_cpx* out new kiss_fft_cpx[1024]; for (int i 0; i 1024; i) { in[i].r sampleBuffer[i]; in[i].i 0.0; } kiss_fft(cfg, in, out); // 计算幅值谱 QVectordouble freqAmp(512); for (int i 0; i 512; i) { freqAmp[i] sqrt(out[i].r * out[i].r out[i].i * out[i].i) / 512.0; } delete[] in; delete[] out; kiss_fft_free(cfg);这里涉及的原理是FFT的输入是时域采样序列输出是复数序列实部和虚部分别代表该频率分量的余弦和正弦分量幅值等于两者的欧几里得距离。对于1024点输入输出的对称性质决定了我们只取前512点0到采样率的一半采样率越高能分析的频率范围越宽这就是奈奎斯特采样定理。如果你只用了前N/2个点不要惊讶这是正常的。把这三步串起来就得到了一个从串口到频谱显示的完整链路。开关按钮控制采集启停绘制区上半部分显示时域波形下半部分显示实时频谱实测60fps无压力。4.2 界面优化的几个实用技巧界面设计上我建议用QVBoxLayout把CPU曲线区域和频谱区域左右分列下面是按钮区用QPushButton、开始采集、停止采集、导出Excel三个按钮。这种布局简洁明了用户一眼就能看懂怎么操作。如果界面太挤可以用QSplitter代替普通布局允许用户拖动分隔条调整区域比例。另一个技巧是绘图区背景色。QCustomPlot默认背景是白底改成深色背景并把网格线和曲线改成亮色频谱区域的对比度会好很多。这个改动很小但对用户体验影响非常大。实测很多客户专门问过这个界面很专业其实就是背景色和处理细节的功劳。5. 常见问题与排查技巧实录5.1 高频错误速查表我整理了这套组合里出现频率最高的报错和解决思路用表格列出来方便你对照排查。报错现象根本原因解决办法启动时提示windows no qt platform plugin could be initialized找不到Qt平台插件通常是部署时缺少platforms目录在exe同级目录建platforms文件夹把Qt安装目录plugins/platforms/qwindows.dll复制进去或重新用windeployqt打包Qt插件报此扩展不能安装在任何当前安装的产品上VS2022和插件版本不匹配在VS内直接搜索“Qt Visual Studio Tools”安装别去下载旧版离线包硬装链接时大量LNK2019无法解析的外部符号QXlsx库的编译器和当前项目的Qt/编译器版本不匹配换成源码方式把QXlsx源文件直接加入项目或重新编译适合当前Qt版本的静态库#include QtWidgets/QApplication无法打开项目属性里没有配置Qt模块的包含目录在项目属性 - VC目录 - 包含目录里添加Qt的include、include/QtWidgets等路径Qt打包后在别人电脑上启动失败缺少Visual C运行库或Qt运行库使用windeployqt自动收集依赖必要时同时打包VC Redistributable运行库崩溃报错看不出原因Debug和Release混用确保整个解决方案的配置完全一致全部Debug或全部ReleaseQt库和QXlsx库都要匹配Excel打开后公式显示为0或空白QXlsx写入公式后没自动计算缓存值程序里同时保存计算值作为冗余列或者用Excel打开后按F9刷新公式串口打不开串口号错误或占用用QSerialPortInfo::availablePorts()动态获取端口列表不要硬编码端口名5.2 QXlsx和表格处理相关的三个隐藏坑第一个隐藏坑是单元格类型问题。QXlsx在读Excel时如果单元格存的是数字但是以文本形式存的读取出来是字符串类型直接转double会失败。我的处理办法是优先用cell-value().toString()清理掉空格再判断转换或者用QVariant的toDouble()/toInt()看返回值。第二个坑是合并单元格的处理。合并单元格后被合并的其他单元格实际上是不存在的直接用cellAt访问会返回空指针。所以写代码时最好通过遍历CellRange的方式获取合并单元格的实际大小。如果你真不知道合并范围但想写值QXlsx会在合并区域左上角单元格写入值其余位置无法单独写入。第三个坑在公式上。QXlsx对公式的支持已经挺完善但Excel里的一些高级函数比如动态数组函数、LET函数可能在旧版文件中不兼容。如果目标用户使用的Excel版本不确定建议尽量用基础函数拼接少用新特性。5.3 打包发布全流程windeployqt的用法和验证方法打包发布是很多人忽略的最后一公里。Qt程序在开发机上能跑复制到别的电脑上却打不开就是这个环节出了问题。最常用的打包工具是Qt自带的windeployqt。完整流程是先用VS2022将项目编译成Release版本把生成的exe文件拷到一个干净目录然后用Qt命令行工具打开“Qt 5.15.2 (MSVC 2019 64-bit)”环境进入该目录执行windeployqt --release --no-translations yourapp.exe这个命令会自动分析exe的依赖把Qt的DLL、插件、平台文件、样式库等拷贝到对应位置。特别建议加个--no-translations参数否则会拷贝一大堆小语种翻译文件占空间不说还容易误导用户点错语言选项。执行完以后目录下会出现platforms、styles、imageformats等文件夹这些都是必需的。对于QXlsx这种第三方库windeployqt不认识需要手动把QXlsx的DLL如果用的是动态库或静态链接进exe。如果使用的是前面说的源码方式编译QXlsx已静态链进exe无需额外拷贝。如果你的程序依赖了串口模块windeployqt也会自动拷贝Qt5SerialPort.dll和qwindows.dll实测很稳。验证是否打包成功的最快方法找一台没装过Qt和VS的电脑直接把整个目录拷过去运行。如果弹出“缺少DLL”用 Dependencies.exe 这类工具检查exe的依赖项逐个补齐即可。大部分人容易漏掉的是VC运行库windeployqt不会自动打包这个需要在目标机器上安装“Microsoft Visual C 2015-2022 Redistributable”。6. 我踩过的几个深度坑及最终心得先说一个我一开始无比困惑的问题为什么在VS2022里把Qt项目生成出来了运行时却提示no qt platform plugin could be initialized。后来才发现问题不在代码而在部署。凡是用Qt做程序的人迟早会遇到这个报错而且基本都是在把程序复制到别的电脑或换了目录运行时出现。解决办法就是我前面写的要么用windeployqt自动处理要么手动补platforms/qwindows.dll二选一即可。补充一个细节这个报错还经常在Qt库版本混用时出现比如我的电脑装了Qt 5.15.2但某个第三方库带着Qt 6的某个DLL环境变量Path里又是别的Qt版本这时候系统会随机加载一个版本平台插件就可能对不上。排查这个问题的思路是打开系统环境变量把多余的Qt相关路径删掉只保留一套Qt环境。另一个让我抓狂的坑是QXlsx在Release模式下写Excel文件明明不报错但打开文件提示“文件已损坏”。排查了很久最终发现我用的QXlsx版本在MinGW编译器下编译时在Release模式有个已知的内存释放问题换成MSVC编译彻底解决。这也说明了一个真理编译器决定一切尽量保证你的所有库Qt、QXlsx、其他第三方库用的都是同一套编译器否则就是给自己埋雷。除此之外我再分享两条做Qt桌面项目的总体经验。第一条不要把太多逻辑塞进UI线程。我见过太多同行在按钮点击事件里直接做文件解析、Excel生成、网络请求界面瞬间卡死用户截图说“软件崩溃”——其实只是阻塞了。实际开发里数据解析放线程池Excel导出放子线程进度条实时反馈用户体验会好很多。第二条养成用信号槽做模块解耦的习惯。比如串口采集类只管发dataReady(QByteArray)信号频谱分析类只负责处理数据并发射spectrumReady(QVectordouble)信号UI层只负责订阅信号并绘图。这样任意一个模块出问题都不会拖垮整个项目。最后说说这套组合的后续扩展方向。如果你想做更复杂的报表可以把QXlsx和打印功能结合或者导出PDF如果你需要数据库支持Qt的SQL模块直接能连SQLite/MySQL如果客户要求Web端展示数据还可以用Qt的WebEngine做嵌入式浏览器。工程化做事先把基础打牢后面的路会越走越宽。希望这篇文章能帮你把这套环境真正跑起来写出让自己满意的桌面应用。本文还有配套的精品资源点击获取
返回列表