qt使用qxlsx实现xlsx、xls表格文件快速写入和读取

news2024/9/27 5:48:34

一、前言

本片文章主要记录和分享一下qt使用qxlsx开源文件读写xlsx表格文件用法。

目录

  • 一、前言
  • 二、环境
  • 三、正文
    • 1.读取指定xlsx文件
    • 2.保存xlsx文件
    • 3.保存xlsx文件内容过大崩溃解决方案一
    • 4.保存xlsx文件内容过大崩溃解决方案二
  • 四、结语

二、环境

windows
linux
qt5.7

三、正文

首先安装和部署qxlsx文件我就不说了,网上很多很多,都是开源的pri文件夹,直接复制再pro文件调用添加即可。

1.读取指定xlsx文件

本样例是读取某个表格1、2列内容,读取全部1、2列有的内容,除去第一行标题行,只保留内容

        QString path=qApp->applicationDirPath()+"/code.xlsx";
        QFile file(path);
        if(!file.exists())
            massage_dialog(1,"提示","xxx信息!",1);
        else{
            QStringList code_nums;code_nums.clear();
            QStringList code_name;code_name.clear();
            QXlsx::Document xlsx(path);
            QXlsx::Workbook *workBook = xlsx.workbook();
            QXlsx::Worksheet *workSheet = static_cast<QXlsx::Worksheet*>(workBook->sheet(0));
            ulong xlsxrows=workSheet->dimension().rowCount();//读取文件行数
            ulong xlsxcloums=workSheet->dimension().columnCount();//读取文件列数
            for (int i=1;i<=xlsxrows;i++){
                code_nums.append(workSheet->cellAt(i, 1)->value().toString());
                code_name.append(workSheet->cellAt(i, 2)->value().toString());
            }
            code_nums.removeFirst();//去掉第一行标题行
            code_name.removeFirst();//去掉第一行标题行
			xlsx.deleteLater();

表格样例图片

2.保存xlsx文件

本样例是保存表格内容到指定名称的文件(新建),并生成某一列数据的曲线,从坐标1到坐标2

   QXlsx::Document xlsx;
   xlsx.addSheet(title_name[i]);
   xlsx.selectSheet(title_name[i]);
   ///写大标题,标题在第一行
   QXlsx::Format formatTitle;
   formatTitle.setFontBold(true);// 粗体
   formatTitle.setFontColor(QColor(Qt::black));//文字颜色
   formatTitle.setFontSize(20);//字体大小
   formatTitle.setBorderStyle(QXlsx::Format::BorderThin);//边框样式,细网格线
   formatTitle.setPatternBackgroundColor(Qt::lightGray);//单元格背景色
   formatTitle.setFillPattern(QXlsx::Format::PatternSolid);//填充样式
   formatTitle.setHorizontalAlignment(QXlsx::Format::AlignHCenter);//文本水平居中
   xlsx.mergeCells(QXlsx::CellRange(1,1,1,20), formatTitle);//合并单元格 第一行第1列到第一行第15列合并成一格
   QString code="未知设备";
   if(!ui->lineEdit->text().isEmpty())code=ui->lineEdit->text();
   xlsx.write(1,1,"设备号:"+code+",信号名称:"+title_name[i]+",数据组数:"+QString::number(r_groupdata.size()));//给合并后的单元格写数据, 注意参数 (1,1,"title")
   ///写小标题,标题在第一行
   QXlsx::Format format1;
   format1.setBorderStyle(QXlsx::Format::BorderThin);//边框样式,细网格线
   format1.setHorizontalAlignment(QXlsx::Format::AlignHCenter);//文本水平居中
   xlsx.write(2,1,"信号值",format1);
   xlsx.write(2,2,"时间戳",format1);

   ///写内容,从第三行开始,1-2列
   QXlsx::Format format2;
   format2.setBorderStyle(QXlsx::Format::BorderThin);//边框样式,细网格线
   format2.setHorizontalAlignment(QXlsx::Format::AlignHCenter);//文本水平居中
   //可以先按行写, 也可以按列写
   //...
   for (ulong row = 0; row < r_groupdata.size(); row++){
       xlsx.write(row+3,1,r_groupdata[row].box_zhidong[2],format2);//档位开始
       xlsx.write(row+3,2,r_groupdata[row].box_time.toString("yyyy-MM-dd hh:mm:ss"),format2);//时间
   }

   //生成曲线
   Chart * Crom = xlsx.insertChart( 3, 5, QSize(1200, 800) );
   Crom->setChartType( Chart::CT_ScatterChart );//CT_ScatterChart
   Crom->addSeries( CellRange(QString("A3:A%1").arg(r_groupdata.size()+2)) );
   Crom->setAxisTitle( Chart::Left, QString("数值") );
   Crom->setAxisTitle( Chart::Bottom, QString("时间线") );
   Crom->setChartTitle( QString(title_name[i]) );
   //保存数据
   bool res=false;
   res = xlsx.saveAs(dir+historydir+"/信号"+QString("%1").arg(i+1,2,10,QChar('0'))+"-"+title_name[i]+QString("-%1数据包.xlsx").arg(r_groupdata.size()));
   xlsx.deleteLater();

   MySleep(10000,1000);

mysleep函数如下

//延时usetime:非阻塞时间  waittime:阻塞时间
void MySleep(uint usetime,ulong waittime)
{
    QCoreApplication::processEvents(QEventLoop::AllEvents, usetime);//进入此函数内给之前数据usetime毫秒时间处理,处理完立马退出执行之后,超时立马退出
    QThread::msleep(waittime);//阻塞延时waittime毫秒
}

3.保存xlsx文件内容过大崩溃解决方案一

在使用qxlsx保存文件时,会遇到有的时候保存数据量过大时程序崩溃的问题, 这种问题由于源码过于复杂原因未深入研究寻找原因,暂时使用其他方式解决,方案一就是将数据按列分开保存, 假如数据有30列,有20万行,就1列保存一个xlsx文件,然后循环30列保存,中间加上mysleep延时函数,这样在保存一列之后再中间的等待时间会释放已经申请的内存,然后保存第二列再用,再任务管理器中看现象就是内存500M→1500M→500M→1500M。。。

4.保存xlsx文件内容过大崩溃解决方案二

方案二就是按行保存,再保存超过一定行数之后就换另外一个文件保存
下面是一部分示例代码,我通过spinBox设置单个文件保存行数,10000行为步长

//导出excel
void MainWindow::on_pushButton_4_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("选择信息导出文件目录"),"/home",QFileDialog::ShowDirsOnly|QFileDialog::DontResolveSymlinks);
    if(dir.isEmpty())
        QMessageBox::information(this,"提示","路径为空!设置保存报告路径失败!");
    else{
        bool exist;
        QDir *folder = new QDir();
        QString historydir="/histroy"+QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss");
        exist = folder->exists(dir+historydir);//文件夹是否存在
        if(!exist)folder->mkdir(dir+historydir);//不存在创建文件夹
        // 设置excel表头(第一行数据)
        QString groupname[27]={"时间","识别号","ID","度","度","角度","速","速度","半径","状态","卫星定位状态","状态","数","期","状态","状态","温度","据状态","据状态","模式态","路态","模式","指令","路件名","路编号","返航确认果","上态"};
        QStringList titleList;
        titleList.clear();
        for(int i=0;i<27;i++)
            titleList.append(groupname[i]);
        bool res;
        ulong allnum=ui->tableWidget->rowCount();
        ulong thisnum=0,afternum=0;
        QVector<ulong> savelistcount;
        char count=allnum/ui->spinBox->value();
        for(int i=0;i<count;i++)
            savelistcount.append(ui->spinBox->value());
        savelistcount.append(allnum%ui->spinBox->value());
        for(int time=0;time<savelistcount.size();time++){
            thisnum=afternum;
            afternum+=savelistcount.at(time);
            qDebug()<<thisnum<<afternum;
            QXlsx::Document xlsx;
            xlsx.setColumnWidth(1,10);//第一行,20列宽
            for (int i = 0; i < titleList.size(); i++){
                xlsx.write(1, i+1, titleList.at(i));//这里写第一行,第n列数据
                //开始写第n行数据
                for(int j = thisnum;j<afternum;j++){
                    xlsx.write(j+2-thisnum,i+1,ui->tableWidget->item(j,i)->text());
                }
            }
            // 最后,保存文件
            res=xlsx.saveAs(dir+historydir+"/"+QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss")+QString("(%1)").arg(time+1)+".xlsx");
            xlsx.deleteLater();
            QCoreApplication::processEvents(QEventLoop::AllEvents, 10000);//进入此函数内给之前数据usetime毫秒时间处理,处理完立马退出执行之后,超时立马退出
            QThread::msleep(1000);//阻塞延时waittime毫秒
        }
        if(res)
            QMessageBox::information(this,"提示","保存excel成功!");
        else
            QMessageBox::information(this,"提示","保存excel失败!");
    }
}

其中所有数据再控件tabelwidget中
当个文件行数在控件spinBox中

四、结语

新年第二篇文章,收尾一个去年计划中发表文章和实现功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/140018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【财务】FMS财务管理系统---对账平台

人工进行对账工作是非常繁杂的&#xff0c;此时&#xff0c;就非常有必要建设一个对账平台。笔者在本文介绍了对账平台的相关内容&#xff0c;分享给大家。 前面介绍过应收对账、财务应付结算两部分内容&#xff1b;应收对账主要是调用第三方支付的接口获取支付流水信息与我司的…

C++设计模式:三种工厂模式详解(简单工厂,工厂模式,抽象工厂)

文章目录简单工厂模式简单工厂实现步骤简单工厂优缺点工厂模式工厂模式和简单工厂模式有什么不同&#xff1f;工厂模式实现步骤实现代码工厂模式优缺点抽象工厂模式抽象工厂模式实现步骤实现代码抽象工厂模式优缺点简单工厂模式 简单工厂模式属于类的创建型模式,又叫做静态工厂…

【算法】算法分析技术(第一章习题解答)

1 算法分析技术 1.1 假设 fff 和 ggg 是定义在自然数集合上的函数, 若对某个其他函数 hhh 有 fO(h)f O(h)fO(h)和 gO(h)g O(h)gO(h) 成立, 那么证明 fgO(h)f g O(h)fgO(h) 证明&#xff1a; 根据已知条件 fO(h)f O(h)fO(h)&#xff0c;存在 c1>0c_{1}>0c1​>0 …

错题记录2:源码补码二进制转换

补码原码二进制一直是本人比较头疼的问题&#xff0c;今日找题目来做发现还是错得多&#xff0c;记录以下&#xff0c;再回顾一遍。 1.如下代码输出的是什么&#xff08; &#xff09; char a101; int sum200; a27;suma; printf("%d\n",sum); A: 327 B: 99 C: 3…

【MySQL】详解MySQL数据库事务

MySQL数据库事务数据库事务特性事务的并发问题事务的隔离级别分布式事务解决方案1.XA 协议2.TCC3.消息一致性方案4.阿里云中的全局事务服务 GTS数据库事务特性 数据库事务具备ACID四大特性&#xff1a; 原子性&#xff1a;是指事务操作时具备原子操作的&#xff0c;就是说整…

分布式系统架构

分布式系统定义 分布式系统&#xff1a;硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 为什么需要分布式系统 提升系统吞吐量&#xff1a;集群协同解决单机性能瓶颈提高系统可用性 &#xff1a;冗余部署&#xff0c;各…

OSS阿里云存储

一、开通“对象存储OSS”服务 2、进入管理控制台 二、控制台使用 点击Buket列名&#xff0c;Buket可以看作是一系列的虚拟内存空间它是一个独立的小个体 创建mystudent 创建成功后就有下面的样子了 &#xff0c;创建的时候读写权限&#xff0c;我们选择公共读&#xff0c…

matlab中sign函数的使用(提取符号)

仅用于记录自己学习过程中遇到的函数 matlab中sign函数的使用&#xff0c;提取符号 一、语法 Y sign(x) 返回与 x 大小相同的数组 Y&#xff0c;其中 Y 的每个元素是&#xff1a; 1&#xff0c;前提是 x 的对应元素大于 0。 0&#xff0c;前提是 x 的对应元素等于 0。 -1&am…

CAP定理与分布式事务理论

文章目录一、CAP定理1.1 一致性1.2 可用性1.3 分区容错1.4 定理的矛盾点二、分布式事务理论2.1 BASE理论2.2 解决分布式事务思路一、CAP定理 分布式系统有三个指标。 Consistency&#xff08;一致性&#xff09;Availability&#xff08;可用性&#xff09;Partition toleranc…

GBASE斩获2022科技赋能金融业数字化转型突出贡献奖

12月27日&#xff0c;由中国人民银行主管的《金融电子化》杂志社主办的“2022中国金融科技年会暨第十三届金融科技应用创新奖颁奖典礼”成功举办&#xff0c;在本次活动上&#xff0c;GBASE南大通用“多模多态分布式数据库GBase 8c”&#xff0c;荣获“2022科技赋能金融业数字化…

PyCharm高级配置

pycharm设置内存大小步骤1&#xff0c;Help -> FindAction -> (输入 “VM”) -> (点击)“Edit Custom VM options”2&#xff0c;Pycharm会在编辑器中打开适当的vmoptions文件&#xff08;pycharm.vmoptions或pycharm64.options&#xff09;。3&#xff0c;将**-Xms**…

CCIE重认证350-401

拖图题 QoS traffic policing: causes TCP retransmissions when traffic is dropped导致TCP重传时流量下降 introduces no delay and jitter引入无延迟和抖动 drops excessive traffic减少过多的流量 traffic shaping: buffers excessive traffic缓冲过多的流量 introduce…

Sensor+ISP专栏-Demosaic

SensorISP专栏-Demosaic 1.what is raw raw图指的是从cmos sensor直接输出的原始图像&#xff0c;它本身没有颜色分量。在CMOS Sensor中使用彩色滤镜阵列(color filter array&#xff0c;CFA) 的方式捕获彩色图像&#xff0c;每个感光像素的上面覆盖一个语物理像素相同面积大…

OpenStack-Mitaka版本部署

1.环境准备 centos7.2相关文件 镜像&#xff1a;https://mirrors.aliyun.com/centos-vault/7.2.1511/isos/x86_64/CentOS-7-x86_64-DVD-1511.iso?spma2c6h.25603864.0.0.5c565932JYniuU openstack-mitaka rpm包&#xff1a;https://mirrors.aliyun.com/centos-vault/7.2.15…

hadoop 3.x 案例7: hadoop大数据平台日志

文章目录一. Hadoop日志1.1 namenode日志1.2 datanode日志1.3 secondarynamenode日志1.4 yarn日志1.4.1 resourcemanger日志1.4.2 nodemanager日志1.5 historyServer日志二. Hive日志三. Spark日志四. Flink日志一. Hadoop日志 cd $HADOOP_HOME/logs日志分类: namenode日志 d…

【ROS】—— ROS通信机制进阶(七)

文章目录前言1. 常用API(C)1.1 初始化1.2 话题与服务相关对象1.3 回旋函数(重点)1.4 时间1.4.1 获取当前时刻and指定时刻1.4.2 持续时间1.4.3 时间运算1.4.4 设置运行频率1.4.5 定时器1.5 其他函数2. 常用API(python)2.1 初始化2.2 话题与服务相关对象2.3 回旋函数2.4 时间2.4.…

Bandit算法学习[网站优化]02——epsilon-Greedy 算法

Bandit算法学习[网站优化]02——epsilon-Greedy 算法 参考资料 White J. Bandit algorithms for website optimization[M]. " O’Reilly Media, Inc.", 2013.https://github.com/johnmyleswhite/BanditsBook 实验环境&#xff1a;jupyter python 3.7 项目地址&am…

twrp Xposed zip包脚本定制全解析

声明:本文不对印刷机导致的任何结果承担责任,请谨慎尝试 想要研究一个新技术,最好的办法就是read the fuck source code,读源码时最直接高效的方式,当然,这很难啃,所以通常也可以配合网上一些教程来理解,但是通常,值钱的技术一般人是不会在网上发布的,因为技术的价值就…

大厂必备Stream流、方法引用的使用

大厂必备Stream流、方法引用的使用 1 Stream的基本使用 1.1 思想 当需要对多个元素进行操作&#xff08;特别是多步操作&#xff09;的时候&#xff0c;考虑到性能及便利性&#xff0c;我们应该首先拼好一个“模型”步骤方案&#xff0c;然后再按照方案去执行它。【流水线】 …

spring源码-容器refresh

spring源码 铺垫 1.xml信息封装 我们可以预测的大致顺序 xml里的bean 封装成对象定义信息更容易进一步的 创建 注入 BeanDefinition的属性&#xff1a;可以看出是对xml里信息的封装 public interface BeanDefinitionReader 定义规范2.使用反射 为什么不用new创建对象&#x…