QXlsx读写数据库

2023-10-27

最近写读写xlsx文件的工具,用了Qt自带的比较卡,操作也不舒服,最后选择用了QXlsx

QXlsx源码地址:github  https://github.com/dbzhang800/QtXlsxWriter

QXlsx官网连接: Documentation: http://qtxlsx.debao.me 

 主要用到了sqlite3 跟 QXlsx:

以下是记录使用过程:

1. pro文件中导入QXlsx源码,这里没有使用动态库,直接将代码编译到程序了
    添加:
        include(xlsx/qtxlsx.pri)
    
    如下图结构:

 

将对头文件加入即可

#include "xlsxdocument.h"
#include "xlsxworkbook.h"
#include "xlsxworksheet.h"

using namespace QXlsx;

读取xlsx写入数据库:

/* 导入处理 */
void xlsxProcTask::inportXlsx(const QString &xlsxName) {
  QStringList list = threadSqlite.getTableInfo("test");
  QXlsx::Document doc(xlsxName);

  int sheetCount = doc.sheetNames().count();
  int row, coulmn;
  QXlsx::CellRange range;
  QStringList rowListData; /* 记录一行数据 */
  QStringList headList;    /* 记录表头 */
  QList<int> delList;      /* 记录删除列 */
  QString tableName, valueData, tmpName, tmpValue;

  threadSqlite.openTransaction();
  for (int cnt = 0; cnt < sheetCount; cnt++) {
    rowListData.clear();
    tableName.clear();
    valueData.clear();
    delList.clear();
    headList.clear();
    tmpName.clear();
    tmpValue.clear();
    tableName = QString("INSERT INTO test (");
    valueData = QString(" VALUES ( ");
    doc.selectSheet(doc.sheetNames().at(cnt));

    range = doc.dimension();
    row = range.lastRow();
    coulmn = range.lastColumn();

    /* 表头查询 */
    for (int cCnt = 1; cCnt <= coulmn; cCnt++) {
      headList.append(doc.read(1, cCnt).toString());
    }

    /* 表头通过数据库过滤 */
    for (int cCnt = headList.count() - 1; cCnt >= 0; cCnt--) {
      if (-1 == list.indexOf(headList.at(cCnt))) {
        delList.append(cCnt);
        headList.removeAt(cCnt);
        continue;
      }
    }

    /* 写sql语句 表项 */
    for (int cCnt = 0; cCnt < headList.count(); cCnt++) {
      if (cCnt == 0) {
        tableName += QString(" %1 ").arg(headList.at(cCnt));
      } else {
        tableName += QString(" , %1 ").arg(headList.at(cCnt));
      }
    }
    tableName += QString(" ) ");

    /* 按照行写入 */
    for (int rCnt = 2; rCnt <= row; rCnt++) {
      tmpName = tableName;
      tmpValue = valueData;
      rowListData.clear();

      /* 列处理一个单元格 */
      for (int cCoumn = 1; cCoumn <= coulmn; cCoumn++) {
        if (0 != delList.count()) {/*  */
          if (-1 != delList.indexOf(cCoumn)) {
            continue;
          }
        }
        rowListData.append(doc.read(rCnt, cCoumn).toString());
      }

      for (int cCnt = 0; cCnt < rowListData.count(); cCnt++) {
        if (cCnt == 0) {
          tmpValue += QString("'%1'").arg(procString(rowListData.at(cCnt)));
        } else {
          tmpValue += QString(", '%1' ").arg(procString(rowListData.at(cCnt)));
        }
      }

      tmpValue += QString(")");
      tmpName += tmpValue;

      threadSqlite.write(tmpName);
    }
  }

  threadSqlite.closeTransaction();

  emit importFinished();
}

数据库操作函数:

.h

#ifndef OPERASQLITE_H
#define OPERASQLITE_H

#include <QObject>
#include <QSqlDatabase>
#include <QSqlDriver>
#include <QSqlError>
#include <QSqlRecord>
#include <QtSql>

static QString clearSeq = QString("delete from ");
class operaSqlite : QObject {
  Q_OBJECT
public:
  operaSqlite();
  ~operaSqlite();
  void setContain(QString);
  void openTransaction();
  void closeTransaction();
  void write(const QString &);
  bool openSqlite(QString myDb, QString &error);
  bool closeSqlite();
  QStringList getTableInfo(QString tabName);
  void clearSqlite(QString &tableName);
  bool isOpen();
  QSqlDatabase getDb();

private:
  QSqlDatabase sqliteDb;
  QString sqlContain;
  QString contions;
};

#endif // OPERASQLITE_H
.cpp
#include "operasqlite.h"

operaSqlite::operaSqlite() {}

void operaSqlite::setContain(QString contain) { sqlContain = contain; }

operaSqlite::~operaSqlite() { closeSqlite(); }

bool operaSqlite::openSqlite(QString myDb, QString &error) {
  bool bRet = false;
  do {
    if (myDb.isEmpty()) {
      break;
    }

    if (QSqlDatabase::contains(sqlContain)) {
      sqliteDb = QSqlDatabase::database(sqlContain);
      if (false == sqliteDb.isOpen()) {
        sqliteDb.open();
      } else {
        error = QString("数据库打开错误:%1").arg(sqliteDb.lastError().text());
      }
    } else {
      sqliteDb = QSqlDatabase::addDatabase("QSQLITE", sqlContain);
      sqliteDb.setDatabaseName(myDb);
      if (false == sqliteDb.open("root", "Smaller")) {
        error = QString("数据库打开错误:%1").arg(sqliteDb.lastError().text());
        break;
      }
    }
    bRet = true;
  } while (0);

  return bRet;
}

bool operaSqlite::closeSqlite() {
  bool bRet = false;
  QSqlDatabase db;
  do {
    if (QSqlDatabase::contains(sqlContain)) {
      db = QSqlDatabase::database(sqlContain);
      if (true == db.isOpen()) {
        db.close();
      }
    }
    bRet = true;
  } while (0);
  return bRet;
}

QStringList operaSqlite::getTableInfo(QString tabName) {
  QStringList nameList;
  QSqlQuery query(sqliteDb);
  QString getTableInfo = "PRAGMA table_info(" + tabName + ")";

  query.prepare(getTableInfo);

  if (query.exec()) {
    while (query.next()) {
      nameList.append(
          query.value(query.record().indexOf(QString("name"))).toString());
    }
  } else {
    qDebug() << query.lastError();
  }

  return nameList;
}

void operaSqlite::openTransaction() { sqliteDb.transaction(); }
void operaSqlite::closeTransaction() { sqliteDb.commit(); }

void operaSqlite::write(const QString &data) {
  QSqlQuery query(sqliteDb);
  if (false == query.exec(data)) {
    qDebug() << query.lastError().text();
  }
}

void operaSqlite::clearSqlite(QString &tableName) {
  QString execSql = clearSeq + tableName;
  do {
    QSqlQuery query(sqliteDb);

    if (false == query.exec(execSql)) {
      qDebug() << query.lastError().text();
      break;
    }

    execSql = QString("select * from sqlite_sequence");
    if (false == query.exec(execSql)) {
      qDebug() << query.lastError().text();
      break;
    }

    execSql = QString("update sqlite_sequence set seq=0 where name='%1'")
                  .arg(tableName);
    if (false == query.exec(execSql)) {
      qDebug() << query.lastError().text();
      break;
    }
  } while (0);
}

bool operaSqlite::isOpen() { return sqliteDb.isOpen(); }

QSqlDatabase operaSqlite::getDb() { return sqliteDb; }

写出xlsx函数:

/* 写表格处理 */
bool xlsxProcTask::writeXlsx(const QString &sql, const QStringList &head,
                             const QString &xlsxName) {
  bool bRet = false;
  QString error;
  operaSqlite sqlWriteXlsx;
  sqlWriteXlsx.setContain("79288789");
  sqlWriteXlsx.openSqlite("wx.db", error);
  QString saveFileName;
  do {
    if (sql.isEmpty())
      break;

    Document xlsx;
    Format formatXls;
    formatXls.setFontSize(11);
    formatXls.setHorizontalAlignment(QXlsx::Format::AlignHCenter);

    /* 写入head */
    for (int cnt = 0; cnt < head.count(); cnt++) {
      xlsx.write(1, cnt + 1, head.at(cnt), formatXls);
    }

    /* 查询数据库 */
    QSqlQuery query(sqlWriteXlsx.getDb());
    if (false == query.exec(sql)) {
      break;
    }

    int row = 2;/* 第一行是表头, 表格处理默认是从(1,1)起始 */
    while (query.next()) {
      for (int i = 0; i < head.count(); i++) { /* 写入一行 */

        xlsx.write(row, i + 1,
                   query.value(query.record().indexOf(head.at(i))).toString());
      }
      row++; /* 多行写入,查询多少行就写入多少 */
    }

    /* 保存文件 */
    saveFileName += (xlsxParam.savePath + "/" + xlsxName + QString(".xlsx"));

    CellRange range = xlsx.dimension();
    row = range.lastRow();
    if (row == 1)/* 1行主要是空表格 直接不保存了 */
      break;

    /* 有数据的表格保存 */
    xlsx.saveAs(saveFileName);
    bRet = true;
  } while (0);

  if (sqlWriteXlsx.isOpen()) {
    sqlWriteXlsx.closeSqlite();
  }
  return bRet;
}

文中使用的结构体(自用的定义自己可以随便换 对应的处理换掉就行了):

enum {
  noUse = 0,
  fiveSplit = 1,
  fiveGet,
  sixSplit,
  sixGet,
  fiveUserGet,
  sixUserGet
};

typedef struct {
  qint8 classType; 
  QStringList classList;
} sectorClass_t;

typedef struct {
  bool isDel; /* true 删除,false 不操作 */
  QStringList delCoumnList;
} delColumn_t;

typedef struct {
  bool isAdd;               /* true 删除,false 不操作 */
  QString coumnName;        /* 列名 */
  QStringList AddCoumnList; /* 计算公式 */
} calculation_t;

typedef struct {
  QString xlsxName;         /* 表格名称 */
  QString savePath;         /* 保存路径 */
  QString sheetName;        /* sheet名称 */
  QString tabName;          /* 数据库表名 */
  sectorClass_t sector;     /* 提取信息 */
  delColumn_t delColumn;    /* 待删除信息 */
  calculation_t calulation; /* 添加信息 */
  QXlsx::Document *doc;
} xlsxParam_t;

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QXlsx读写数据库 的相关文章

  • ormlite 将日期读取为 'yyyy-MM-dd'

    我需要读取给我的 sqlite 数据库 因此我无法更改表中的日期格式 yyyy MM dd 当我尝试使用 ormlite 为我生成对象时 使用以下注释 DatabaseField columnName REVISION DATE dataT
  • 如何在android中批量插入sqlite

    我正在使用 SQLiteOpenHelper 进行数据插入 我需要插入2500个id和2500个名字 所以花费了太多时间 请任何人帮助我如何减少插入时间 我们可以一次插入多条记录吗 任何人都可以帮助我 先感谢您 代码 public clas
  • Android SQLite 从代码中转储数据库以进行错误报告

    我正在为我的一个 Android 程序开发一种诊断工具 本质上 如果用户遇到问题 我想做一些类似 SQLite 的事情dump 参考 http www sqlite org sqlite html http www sqlite org s
  • 如何在sqlite中添加特定数量的空行?

    我有一个SQLite文件 我想添加2550 empty NULL rows 我可以使用此代码添加一个空行 INSERT INTO my table DEFAULT VALUES 但我需要 2550 行 有什么捷径吗 我不想执行相同的代码 2
  • 如何将现有的 SQLite3 数据库导入 Room?

    好吧 我在桌面上使用 SQLite3 创建了一个只需要读取的某些信息的数据库 我正在制作的应用程序不需要在此表中插入或删除信息 我在 Room 数据库层上做了相当多的谷歌搜索 所有文档都需要在构建应用程序时在 Room 中创建一个新的数据库
  • 了解 FTS3/FTS4:什么是虚拟表并从中搜索具有可搜索的非虚拟表?

    阅读 SQLite3 的 FTS3 FTS4 文档的第一部分后 我现在感到非常困惑 我感到困惑的原因是散布在网络上的示例 我相信它没有涵盖所有可能的用例 另一个原因是我目前所处的情况 话虽如此 我有一个名为 Note 的表 其中包含两个类型
  • sqlite.net + monotouch = SIGSEGV 崩溃

    我们正在使用以下内容 Xamarin 3 Xamarin 表单 单点触控 sqlite net iOS模拟器 硬件 该应用程序在后台线程上与服务器同步数据 整个应用程序只共享一个 SQLite 连接对象 前台查询在后台同步运行的同时执行 所
  • NumPy 数组与 SQLite

    我在 Python 中见过的最常见的 SQLite 接口是sqlite3 但是有什么东西可以很好地与 NumPy 数组或 rearray 配合使用吗 我的意思是 它可以识别数据类型 不需要逐行插入 并提取到 NumPy rec 数组中 有点
  • 将数据库(例如 sqlite)与 cocos2d-x 一起使用

    我开始在 iPhone 上构建游戏应用程序 我正在使用 cocos2d x 游戏引擎 因为它很容易从那里移植到 Android 而且编码是用我非常熟悉的C 编写的 我想知道是否有办法在 cocos2d x 中使用任何数据库 虽然sqlite
  • 如何从 SQLite 的异步 PCL 版本使用 SQLiteAsyncConnection?

    我使用的是 Sqlite net 的 PCL 版本https github com oysteinkrog SQLite Net PCL https github com oysteinkrog SQLite Net PCL 但是 我无法获
  • SQLite。无法添加超过 1000 行

    我试图向我的 SQLite 数据库 使用 fmdb 添加 10k 行 但写入在 1000 行处停止 我没有任何错误或警告 我的代码 NSString queryString NSString stringWithFormat insert
  • 在 Google App Engine 中使用 sqlite3?

    我正在尝试将我的 Python Django 项目部署到 Google App Engine 现在它在我的本地计算机上运行良好 但是当我尝试将其作为 Google App Engine 中的项目运行时 出现以下错误 ImproperlyCo
  • SQLite 更新很多行非常慢

    我相信我已经使用了很多方法来加速许多行的更新 但到目前为止没有任何帮助 我们正在开立交易 像这样 private SQLiteTransaction BeginTransaction SQLiteConnection connection
  • 使用 SQLite.Net.Async 的 Xamarin.Forms

    我已按照此处的说明进行操作http developer xamarin com guides cross platform xamarin forms working with databases http developer xamari
  • sqlite android 中的波斯语/阿拉伯语搜索给出了错误的结果

    我的 sqlite 数据库有问题 它似乎不支持完整的波斯 阿拉伯字符 当我根据波斯字符搜索某些字段时 大多数时候 Sqlite 无法识别这些字符 我通过从 HTML 文件复制数据将数据插入数据库 所以当我输入字符串并搜索时 没有结果显示 但
  • SQLite 性能基准 - 为什么 :memory: 这么慢...只有磁盘速度的 1.5 倍?

    为什么 sqlite 中的 memory 这么慢 我一直在尝试查看使用内存中的 sqlite 与基于磁盘的 sqlite 是否可以获得任何性能改进 基本上我想用启动时间和内存来换取非常快速的查询not在应用程序过程中击中磁盘 然而 以下基准
  • 将 SQLite 与经典 ASP 结合使用

    我正在构建一个 快速小 应用程序 它需要一个小型数据库 我想使用经典 ASP 即不是 ASP NET 并且我想知道 SQLite 用于数据库 可以使用 Classic ASP 中的 SQLite 吗 如何从 ASP 打开 创建 使用 SQL
  • Android sqlite 缺少列

    我的 SQLite 数据库缺少一个我知道存在的列 我将无法从 Android 模拟器中提取数据库 因为如果不重写大量代码 就无法使用模拟器填充数据库 logcat 返回sqlite returned error code 1 msg tab
  • 在 Python 中使用 SQLCipher - 最简单的方法 [重复]

    这个问题在这里已经有答案了 我正在编写一个可以在加密的 SQLite 数据库上运行的 Python 实用程序 最终我会将此类实用程序转换为可执行文件 以便更轻松地交付给团队的其他成员 我读了很多关于 SQLCipher 的页面 但他们都谈论
  • SQlite 获取最近的位置(带有纬度和经度)

    我的 SQLite 数据库中存储有纬度和经度的数据 我想获取距我输入的参数最近的位置 例如我当前的位置 纬度 经度等 我知道这在 MySQL 中是可能的 并且我已经做了相当多的研究 SQLite 需要一个自定义外部函数来实现半正弦公式 计算

随机推荐

  • 【.NET 6】使用EF Core 访问Oracle+Mysql+PostgreSQL并进行简单增改操作与性能比较

    前言 唠嗑一下 都在说去O或者开源 但是对于数据库选型来说 很多人却存在着误区 例如 去O 狭义上讲 是去Oracle数据库 但是从广义上来说 是去Oracle公司产品或者具有漂亮国垄断地位和需要商业授权的数据库产品 去O 目前国内有一个现
  • DBA 面试题

    一 SQL tuning 类 1 列举几种表连接方式 2 不借助第三方工具 怎样查看sql的执行计划 3 如何使用CBO CBO与RULE的区别 4 如何定位重要 消耗资源多 的SQL 5 如何跟踪某个session的SQL 6 SQL调整
  • echarts分享(四):双y轴图表刻度均匀分布问题

    今天分享一个小问题 内容不多 双y轴图表中 为了图表的美观 经常会隐藏一侧的y轴刻度线 仅显示一侧的刻度线 那么问题就来了 两个y轴的数据数值大小不同 常常会导致刻度线的刻度分布不均匀 该如何解决呢 这里分享下我在项目中所作的处理 首先是要
  • ESP32彩屏开发板(WT32-SC01),除了买买买,你还可以参与一起设计了

    基于ESP32彩屏的开发板已在Git Hub平台上开源给所有的开发者了 硬件参数 显示屏 3 5 英尺 LCD 屏幕 分辨率 320 480 SoC ESP32 WROVER B 模组 CPU 双核 Xtensa 32 bit LX6 MC
  • ESP8266测试Wi-Fi通讯安全

    创建Arduino Sketch include
  • 5.荔枝派 zero(全志V3S)-buildroot配置播放视频

    上面是我的微信和QQ群 欢迎新朋友的加入 1 开启ALSA和MPLAY 编译烧录 2 测试 amixer c 0 sset Headphone 0 100 unmute cd usr bin mplayer root test mp4 3
  • is too old (format 10, created by Subversion 1.6)的解决方案

    svn Working copy E aliyun spirit spiritmap0916 is too old format 10 created by Subversion 1 6 解决方案 对项目进行upgrade 等待刷新完成即可
  • Android SDK+Appium安装及环境配置

    Android SDK环境搭建Xmind思维导图 一 安装SDK先配置环境变量 1 创建 JAVA HOME D Program Files Java jdk1 8 0 05 2 创建 CLASSPATH D Program Files J
  • uniapp 拍照和从相册选择的弹窗

    1 在common创建一个vue 把下列代码复制进去
  • linux安装 MySQL 5.7

    我的是CentOS 7 虚拟机 因为之前一直安装失败 浪费了不少时间 特此记录一下正确安装步骤 亲测可用 1 下载命令 wget https dev mysql com get mysql57 community release el7 9
  • 微信小程序云开发——图片展示,视频播放案例

    这次是帮朋友写的一个简单的小程序 考虑到成本和页面简单的问题 我就决定用小程序云开发来进行开发 后来实际开发的时候发现 页面用到图片实在是太多 CDN流量一个月5G根本不够用 但是我看到了数据库一天可以免费访问5万次 我就决定用base64
  • 区块链存证原理

    公证通 Factom公证通 一本由共识算法维护的账本 网录科技 网录科技CTO汪波 区块链做存证的原理及方式 专注区块链技术开发 网录科技千万级天使轮融资 Blockstack 官网 https blockstack org 白皮书 htt
  • 用python编写daemon监控进程并自动恢复

    用python编写daemon监控进程并自动恢复 下面这个程序是用于python编写daemon监控进程并自动恢复 参考http pythonhosted org KiTT modules kitt daemon html usr bin
  • mac下 docker 挂载目录权限问题(operation not permitted)

    在docker run 或者 docker compose yml 添加privileged true privileged的含义是让容器内的root拥有真正root用户的权限 否则它只是一个名为root的普通用户 但是在macos下 即使
  • select函数使用时应注意的问题

    问题一 fd set和timeval的重置 select函数的使用一般分为以下几步 1 FD ZERO fd set 2 FD SET int fd fd set 3 int select int n fd set readfds fd s
  • VSCode批量代码比较

    前言 最近因为工作原因 需要找出一个工程里面修改过的地方 VSCode里自带代码比较功能 可以高亮代码不同的地方 然而手动一个个打开文件来比较显然非常的繁琐 在网上检索后发现并没有相关的方法 因此 为了解决这个问题 在查阅了官方文档后 决定
  • 操作系统笔记整理12——磁盘存储器的管理

    点此链接可跳转到 操作系统笔记整理 目录索引页 参考书籍 计算机操作系统 第四版 汤小丹等编著 文章目录 点此链接可跳转到 操作系统笔记整理 目录索引页 外存的组织方式 连续组织方式 链接组织方式 隐式链接 显示链接 FAT File Al
  • [架构之路-200]- 性能需求与性能分析:影响性能的主要因素

    目录 前言 关于性能的几点说明 第一章 性能需求 提出各种性能指标 1 1 可靠性或可用性 stablity 1 2 处理能力或效率 Performance 1 2 1 指标是吞吐率 1 2 2 指标是响应时间 1 2 3 指标是资源利用率
  • 数据库SQL查询(一)

    本文介绍SQL查询 如何在海量数据中筛选想要数据 数据库管理系统选择 关系型数据库mysql 数据库管理工具选择 navicat 本文中查询语句和查询案例参考自 https edu csdn net course detail 27673
  • QXlsx读写数据库

    最近写读写xlsx文件的工具 用了Qt自带的比较卡 操作也不舒服 最后选择用了QXlsx QXlsx源码地址 github https github com dbzhang800 QtXlsxWriter QXlsx官网连接 Documen