Qt数据库应用1-数据导入导出csv
一、前言
在经历过大大小小十几个甚至几十个纯QtWidget项目后,涉及到数据库相关的项目,几乎都有一个需求,将少量的信息数据比如设备信息、防区信息等,导出到文件保存好,然后用户可以打开该表格进行编辑,编辑完成后保存,再重新导入到软件中,这样相当于安排专人录入数据,而不是在软件中一个个新增效率低了些,甚至有些软件运行在嵌入式板子上或者一些特殊场景,不大方便现场添加编辑信息,如果是提供模板之类的让用户添加好,然后再一次性导入,这个效率就大大提升了。
导入导出数据可以选择xls、也可以选择csv,为什么最后选择的是csv,因为xls很容易依赖本地office软件,就算用什么libxls啥的也没用,毕竟excel本身就不是标准的数据库,单元格数据可以任意指定的,一旦用户破坏了原有的格式要求,你要想按照规则读取导入数据几乎异想天开,而csv语法极其简单,就是按照指定的分隔符比如 ; 分割字符串就行,同理按照这个规则解析也是极其简单,所以在跨平台的场景下csv是首选,当然如果对格式有特殊的需要比如边框、对齐、颜色、分组等情况就必须用到xls了,本组件也封装了。
最开始做项目的时候遇到导入导出,都是直接功能源码写在对应的功能按钮函数中,后面随着项目数量的增多,就算是拷贝也是费时间的,而且这个功能还是不断改进的,一旦某个项目改进了,那相关这个功能的项目都想去改进,代码改动真大,不光是跨项目,就算是在同一个项目中,都会有多处多个信息表会要这个功能,于是想着把这个功能单独做一个通用的类,提供静态函数接口,可以指定分隔符、文件名、文件拓展名、过滤条件、表名、字段集合等。用法极其简单速度极快,导出的数据支持任意表格软件比如excel、wps等,导入数据直接到数据库,自动组织插入sql语句并执行。
二、功能特点
- 组件同时集成了导出数据到csv、xls、pdf和打印数据。
- 所有操作全部提供静态方法无需new,数据和属性等各种参数设置采用结构体数据,极为方便。
- 同时支持QTableView、QTableWidget、QStandardItemModel、QSqlTableModel等数据源。
- 提供静态方法直接传入QTableView、QTableWidget控件,自动识别列名、列宽和数据内容。
- 每组功能都提供单独的完整的示例,注释详细,非常适合各阶段Qter程序员。
- 原创导出数据机制,不依赖任何office组件或者操作系统等第三方库,支持嵌入式linux。
- 速度超快,9个字段10万行数据只需要2秒钟完成。
- 只需要四个步骤即可开始急速导出海量数据比如100W条记录到Excel。
- 同时提供直接写入数据接口和多线程写入数据接口,不卡主界面。
- 可设置标题、副标题、表名。
- 可设置导出数据的字段名、列名、列宽。
- 可设置末尾列自动拉伸填充,默认拉伸更美观。
- 可设置是否启用校验过滤数据,启用后符合规则的数据特殊颜色显示。
- 可指定校验的列、校验规则、校验值、校验值数据类型。
- 校验规则支持 精确等于==、大于>、大于等于>=、小于<、小于等于<=、不等于!=、包含contains。
- 校验值数据类型支持 整型int、浮点型float、双精度型double,默认文本字符串类型。
- 可设置随机背景颜色及需要随机背景色的列集合。
- 支持分组输出数据,比如按照设备分组输出数据,方便查看。
- 可设置csv分隔符、行内容分隔符、子内容分隔符。
- 可设置边框宽度、自动填数据类型,默认自动数据类型开启。
- 可设置是否开启数据单元格样式,默认不开启,不开启可以节约大概30%的文件体积。
- 可设置横向排版、纸张边距等,比如导出到pdf以及打印数据。
- 支持图文混排导出数据到pdf以及打印数据,自动分页。
- 灵活性超高,可自由更改源码设置对齐方式、文字颜色、背景颜色等。
- 支持任意excel表格软件,包括但不限于excel2003-2021、wps、openoffice等。
- 纯Qt编写,支持任意Qt版本+任意编译器+任意系统。
三、体验地址
- 体验地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取码:o05q 文件名:bin_dataout.zip
- 国内站点:https://gitee.com/feiyangqingyun
- 国际站点:https://github.com/feiyangqingyun
- 个人主页:https://blog.csdn.net/feiyangqingyun
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
四、效果图

五、相关代码
bool DataCsv::inputData(int columnCount,
                        const QString &columnNames,
                        const QString &tableName,
                        QString &fileName,
                        const QString &defaultDir,
                        bool existTitle)
{
    fileName = QFileDialog::getOpenFileName(0, "选择文件", defaultDir, DataCsv::CsvFilter);
    if (fileName.isEmpty()) {
        return false;
    }
    QFile file(fileName);
    bool ok = file.open(QIODevice::ReadOnly | QFile::Text);
    if (!ok) {
        return false;
    }
    //传入了字段集合则取字段
    if (!columnNames.isEmpty()) {
        columnCount = columnNames.split(",").count();
    }
    //先读取第一行判断列数是否和目标列数一致,不一致则返回
    QString line = QString::fromUtf8(file.readLine());
    QStringList list = line.split(DataCsv::CsvSpliter);
    if (list.count() != columnCount) {
        return false;
    }
    //先删除原来的数据
    QString sql = QString("delete from %1").arg(tableName);
    QSqlQuery query;
    query.exec(sql);
    //cvs格式需要gbk编码才能正常
    QTextStream in(&file);
    in.seek(0);
    if (fileName.endsWith(".csv")) {
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
        in.setCodec("gbk");
#endif
    }
    //开启数据库事务加速处理
    QSqlDatabase::database().transaction();
    bool isremoveTitle = false;
    while (!in.atEnd()) {
        QString line = in.readLine();
        QStringList list = line.split(DataCsv::CsvSpliter);
        //如果存在标题则不需要处理第一行标题
        if (existTitle && !isremoveTitle) {
            isremoveTitle = true;
            continue;
        }
        //列数必须完全一致才行
        if (list.count() == columnCount) {
            if (!columnNames.isEmpty()) {
                sql = QString("insert into %1(%2) values('").arg(tableName).arg(columnNames);
            } else {
                sql = QString("insert into %1 values('").arg(tableName);
            }
            for (int i = 0; i < columnCount - 1; i++) {
                sql = sql + list.at(i).trimmed() + "','";
            }
            sql = sql + list.at(columnCount - 1).trimmed() + "')";
            query.clear();
            query.exec(sql);
        }
    }
    //提交数据库事务
    if (!QSqlDatabase::database().commit()) {
        QSqlDatabase::database().rollback();
        return false;
    }
    file.close();
    return true;
}
bool DataCsv::outputData(const QString &defaultName,
                         const QStringList &content,
                         QString &fileName,
                         const QString &defaultDir)
{
    bool result = true;
    QString defaultPath = QString("%1/%2").arg(defaultDir).arg(defaultName);
    fileName = QFileDialog::getSaveFileName(0, "选择文件", defaultPath, DataCsv::CsvFilter);
    outputData(fileName, content);
    return result;
}
bool DataCsv::outputData(QString &fileName, const QStringList &content)
{
    if (fileName.isEmpty()) {
        return false;
    }
    int rowCount = content.count();
    if (rowCount == 0) {
        fileName.clear();
        return false;
    }
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly | QFile::Text)) {
        //cvs格式需要gbk编码才能正常
        QTextStream out(&file);
        if (fileName.endsWith(".csv")) {
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
            out.setCodec("gbk");
#endif
        }
        for (int i = 0; i < rowCount; i++) {
            out << content.at(i) << "\n";
        }
        file.close();
    }
    return true;
}
//最简单使用方法
void frmSimple::on_btnCsv1_clicked()
{
    QString file = QUIHelper::appPath() + "/db/dataout_tableview.csv";
    DataHelper::DataOut(ui->tableView, model, 0, file, "测试标题", "测试信息");
    //打开刚才导出的文件
    QUIHelper::openFile(file, "导出测试信息");
}
Qt数据库应用1-数据导入导出csv的更多相关文章
- SQL Server 之 在数据库之间进行数据导入导出
		1.同一服务器上数据库之间进行数据导入导出 (1).使用 SELECT INTO 导出数据 在SQL Server中使用最广泛的就是通过SELECT INTO语句导出数据,SELECT INTO语句同 ... 
- Oracle数据库的创建、数据导入导出
		如何结合Sql脚本和PL/SQL Developer工具来实现创建表空间.创建数据库.备份数据库.还原数据库等操作,然后实现Oracle对象创建.导入数据等操作,方便我们快速了解.创建所需要的部署Sq ... 
- 用NPOI实现导入导出csv、xls、xlsx数据功能
		用NPOI实现导入导出csv.xls.xlsx数据功能 直接上代码 首先定义一个接口 如果需要直接操作文件的话,就自己在封装一次 然后定义csv类的具体实现 这个需要引入命名空间LumenWo ... 
- sqoop工具介绍(hdfs与关系型数据库进行数据导入导出)
		数据表 第一类:数据库中的数据导入到HDFS上 #数据库驱动jar包用mysql-connector-java--bin,否则有可能报错! ./sqoop import --connect jdbc: ... 
- oracle数据库数据导入导出步骤(入门)
		oracle数据库数据导入导出步骤(入门) 说明: 1.数据库数据导入导出方法有多种,可以通过exp/imp命令导入导出,也可以用第三方工具导出,如:PLSQL 2.如果熟悉命令,建议用exp/imp ... 
- 数据库数据导入/导出报错:无法在只读列“Id”中插入数据。
		本文仅供小白参考,大佬请随意...... 本例是:从vs 2017自带的localDB数据库的数据---导出到---->Sql Server 2008中的相应数据库中 1. 导出数据库: 2. ... 
- 数据库数据导入导出系列之五 C#实现动态生成Word(转)
		1. 一个控制台例子,实现动态生成Word. 首先,添加引用:COM->Microsoft Word 11.0 Object Library. 2. 介绍几篇牛人写的关于操作Word的文章 [分 ... 
- 1、数据库与excel表格的数据导入导出
		1.居民用户界面中,excel数据导入导出: 2.其他5张表数据显示到本角色主页的container容器中. 
- 关于 Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法
		在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中2. 建立数据库间的 ... 
- MongoDB学习(三)数据导入导出及备份恢复
		这几天想着公司要用MongoDB,自然就要用到数据导入导出,就自己学习了一下. 在Mongo学习(二)中就讲到了在bin目录下有一些工具,本篇就是使用这些工具进行数据的导入导出及备份恢复. 注意:以下 ... 
随机推荐
- KubeSphere v4 开源并发布全新可插拔架构 LuBan
			2024 年 10 月 10 日,KubeSphere 开源社区激动地向大家宣布,KubeSphere v4(开源版)已正式发布,同时发布全新可插拔架构 KubeSphere LuBan. 相较于 K ... 
- 12C RAC 故障分析 - ORA-17503: ksfdopn:2 Failed to open file +DATA/EIC1/PASSWORD/pwdeic1.256.957086685
			一.故障描述 Oracle 12C PDBS(PDB NAME = WRYPC) 在note1节点上是MOUNTED状态,在note2节点上是READ WRITE状态.note1节点上启动该PDB长时 ... 
- Web渗透06_XSS
			XSS漏洞描述 XSS是非常厉害的漏洞,在OWASP TOP10中榜上有名. XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网 ... 
- 快速上手web前端开发(超详细教程)
			提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 第一步 下安装vscode 第二步 vscode汉化 第三步 安装前端所需插件 1.Live Server 2.Jav ... 
- linux不常用命令
			1.查看进程的内存资源占用 [root@abdi1 elasticsearch]# pidstat -r -p 1791 1 Linux 3.10.0-514.el7.x86_64 (abdi1) 0 ... 
- CerberusDet:不同任务共享不同的部分,新多任务目标检测方案
			传统的目标检测模型通常受到其训练数据和定义的类别逻辑的限制.随着语言-视觉模型的近期兴起,出现了不受这些固定类别限制的新方法.尽管这些开放词汇检测模型具有灵活性,但与传统的固定类别模型相比,仍然在准确 ... 
- 支持国产3A游戏大作 ——《黑神话:悟空》
- 制作并量化GGUF模型上传到HuggingFace和ModelScope
			llama.cpp 是 Ollama.LMStudio 和其他很多热门项目的底层实现,也是 GPUStack 所支持的推理引擎之一,它提供了 GGUF 模型文件格式.GGUF (General Gau ... 
- jenkins拉取github代码报错问题解决
			问题起因: 踩坑踩坑 用jenkins拉取github项目的代码时,配置完成点击构建时,报错信息为:Couldn't find any revision to build. Verify the re ... 
- 微服务探索之路05篇jenkins构建net6和vue docker镜像到Harbor自动更新k8s服务镜像
			从1-4篇已经学习了docker Harbor k8s的基本用法.接下来进阶一下使用jenkins结合起来做到自动部署项目. 1 安装jenkins 1.1前提条件 docker环境,可参考第01篇安 ... 
