Qt读写Excel--QXlsx通过Document对象 *** 作工作表3

Qt读写Excel--QXlsx通过Document对象 *** 作工作表3,第1张

Qt读写Excel–QXlsx通过Document对象 *** 作工作表3🌍 文章目录
  • Qt读写Excel--QXlsx通过Document对象 *** 作工作表3🌍
    • @[toc]
    • 1、概述🧭
    • 2、准备工作🌋
    • 3、函数说明🗻
    • 4、示例代码⛲
      • 4.1 .h文件🌄
      • 4.2 .cpp文件🌇
    • 5、实现效果🎡
    • 6、源代码🏠
👉Qt读写Excel–QXlsx基本使用1👈
👉Qt读写Excel–QXlsx编译为静态库2👈
👉Qt读写Excel–QXlsx通过Document对象 *** 作工作表3👈
1、概述🧭
  • QXlsx是一个可以读写Excel文件的库。

    不依赖office以及wps组件,可以在Qt5支持的任何平台上使用;

  • 使用方式

    1. QXlsx可以编译为动态库使用(使用动态库不用每次的编译,也可以让项目代码量更少,不用一打开工程就几十个文件);
    2. 直接将QXlsx.pri加入代码中使用(我比较推荐直接使用源码,因为QXlsx的注释信息基本在cpp文件中,可以通过阅读源码和注释来学习QXlsx的功能,当然,如果你已经熟悉了QXlsx的使用方式那编译成库使用会更方便,可以使工程的代码量变少);
  • 本文中实现的功能:

    1. 查询打开的Excel中所有可用的工作表(Sheet)名称;
    2. 创建指定名称的工作表(Sheet),自动添加到最末尾,支持ST_WorkSheet、ST_ChartSheet两种类型;
    3. 在指定位置插入一个新的指定名称的工作表(Sheet),支持ST_WorkSheet、ST_ChartSheet两种类型;
    4. 将某个工作表(Sheet)设置为当前活动工作表,并写入数据(ST_WorkSheet类型);
    5. 将指定名称的工作表(Sheet)重命名为一个新的名称,不改变其它因素;
    6. 将指定名称的工作表(Sheet)拷贝为一个新的指定名称的工作表,两个工作表内容相同;
    7. 将指定名称的工作表(Sheet)移动到指定位置;
    8. 删除指定名称的工作表(Sheet)。

2、准备工作🌋
  • 👉👉👉👉👉👉👉看前几章内容。

3、函数说明🗻

注意:执行了 *** 作要保存才生效。

  • QStringList sheetNames() const
    • 功能说明: 查询Excel中所有的工作表(Sheet)名称;
    • 返回值: 所有工作表的名称列表;
  • bool addSheet(const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
    • 功能说明: 在末尾创建一个名称为name,类型为type的工作表;
    • 参数name: 创建的工作表的名称;
    • 参数type: 创建的工作表的类型,可省略;
      • ST_WorkSheet:表格工作表
      • ST_ChartSheet:图表工作表
      • ST_DialogSheet:还不支持
      • ST_MacroSheet:还不支持
    • 返回值: 创建成功则返回true,失败返回false;
      • 如果名称已存在则创建失败;
      • 如果是ST_DialogSheet、ST_MacroSheet也创建失败;(注意这种创建失败有bug,创建失败后输入的name会被保存,下次不能再创建这个名称的工作表,不过不影响使用, 修复方法:xlsxworkbook.cpp文件中的Q_ASSERT(false);下一行添加return sheet;即可)
  • bool insertSheet(int index, const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
    • 功能说明: 在指定位置插入工作表,可设置工作表名称和类型
    • 参数index: 插入工作表的位置,如果>=0则在开始位置插入工作表,如果0
    • 参数name: 工作表名称;
    • 参数type: 工作表类型;
    • 返回值: 插入成功返回true,失败返回false;
      • 失败原因与addSheet相同;
      • 如果插入工作表位置>工作表总数则插入失败;
  • bool selectSheet(const QString &name)
    • 功能说明: 将指定名称的工作表设置未活动工作表(可编辑);
    • 参数name: 工作表名称;
    • 返回值: 设置成功返回true,失败返回false;
      • 如果指定名称的工作表不存在则设置失败;
  • bool renameSheet(const QString &oldName, const QString &newName)
    • 功能说明: 将名为oldName的工作表重命名未newName;
    • 参数oldName: 已有工作表名称;
    • 参数newName: 重命名后的工作表名称;
    • 返回值: 重命名成功返回true,失败返回false;
      • 如果oldName不存在则重命名失败;
      • 如果newName已存在则重命名失败;
      • 如果oldName等于newName则重命名失败;
  • bool copySheet(const QString &srcName, const QString &distName = QString())
    • 功能说明: 将指定的srcName工作表拷贝为distName,两个工作表内容相同;
    • 参数srcName: 已有的需要拷贝的工作表名称;
    • 参数distName: 拷贝后的工作表名称;
    • 返回值: 拷贝成功返回true,失败返回false;
      • 如果srcName不存在则拷贝失败;
      • 如果distName已存在则拷贝失败;
      • 如果srcName等于distName则拷贝失败;
  • bool moveSheet(const QString &srcName, int distIndex)
    • 功能说明: 根据输入的工作表名称,将工作表移动到指定位置;
    • 参数srcName: 需要移动的工作表名称;
    • 参数distIndex: 需要将工作表移动到的位置,distIndex<=0则移动到开始位置,distIndex>=sheet总数则移动到最后位置,如果0< distIndex
    • 返回值: 移动成功返回true,失败返回false;
      • 如果需要移动的工作表名称不存在则失败;
  • bool deleteSheet(const QString &name)
    • 功能说明: 删除指定名称的工作表;
    • 参数name: 需要参数的工作表名称;
    • 返回值: 删除成功返回true,失败返回false;
      • 如果指定名称的工作表不存在则返回失败。

4、示例代码⛲ 4.1 .h文件🌄
#ifndef TEST2_H
#define TEST2_H

#include 
#include "xlsxdocument.h"

namespace Ui {
class Test2;
}

class Test2 : public QWidget
{
    Q_OBJECT

public:
    explicit Test2(QWidget *parent = nullptr);
    ~Test2();

private slots:
    void on_but_open_clicked();

    void on_but_querySheet_clicked();

    void on_but_addSheet_clicked();

    void on_but_insert_clicked();

    void on_but_select_clicked();

    void on_but_rename_clicked();

    void on_but_close_clicked();

    void on_but_copy_clicked();

    void on_but_move_clicked();

    void on_but_delete_clicked();

private:
    Ui::Test2 *ui;

    QXlsx::Document* m_xlsx = nullptr;
};

#endif // TEST2_H

4.2 .cpp文件🌇
#include "test2.h"
#include "ui_test2.h"
#include 
#include 
#include "xlsxabstractsheet.h"

QXLSX_USE_NAMESPACE            // 添加Xlsx命名空间
#define EXCEL_NAME "./1.xlsx"  // 本demo中用到的excel文件路径文件名

Test2::Test2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Test2)
{
    ui->setupUi(this);

    this->setWindowTitle("QXlsx中通过Document对象 *** 作工作表Demo");
}

Test2::~Test2()
{
    on_but_close_clicked();
    delete ui;
}

#if 0            // 使用到的函数
QStringList sheetNames() const;
bool addSheet(const QString &name = QString(),
              AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet);
bool insertSheet(int index, const QString &name = QString(),
                 AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet);
bool selectSheet(const QString &name);
bool renameSheet(const QString &oldName, const QString &newName);
bool copySheet(const QString &srcName, const QString &distName = QString());
bool moveSheet(const QString &srcName, int distIndex);
bool deleteSheet(const QString &name);
#endif

/**
 * @brief 打开Excel
 */
void Test2::on_but_open_clicked()
{
    if(!m_xlsx)
    {
        m_xlsx = new Document(EXCEL_NAME, this);        // 打开EXCEL_NAME文件,将所有数据读取到内存中,然后关闭excel文件
    }
    if(m_xlsx->load())  // 判断文件是否打开成功(也可以使用isLoadPackage)
    {
        qInfo() << "excel打开成功!";
        // 基于范围的for从容器中获取迭代器。

但是因为容器不是const迭代器,所以迭代器将是非的const,这显然足以让容器分离 const QList<QWidget*> objects = this->findChildren<QWidget*>(); for(auto object: objects) { object->setEnabled(true); } } else { qWarning() << "excel打开失败!"; } } /** * @brief 释放Excel内存 */ void Test2::on_but_close_clicked() { if(m_xlsx) { delete m_xlsx; m_xlsx = nullptr; const QList<QWidget*> objects = this->findChildren<QWidget*>(); for(auto object: objects) { object->setEnabled(false); } ui->widget1->setEnabled(true); ui->but_open->setEnabled(true); } } /** * @brief 查询Excel中所有的工作表(Sheet)名称 */ void Test2::on_but_querySheet_clicked() { ui->com_sheets->clear(); ui->com_sheets->addItems(m_xlsx->sheetNames()); } /** * @brief 创建不同类型的工作表 * QXlsx 的SheetType定义了四种类型,但是目前只支持ST_WorkSheet, ST_ChartSheet两种; * 如果创建了不支持的两种在Debug模式下会报错(Q_ASSERT断言),在Release下会返回失败; * 注意:这里有一个小bug * 由于还不支持ST_DialogSheet和ST_MacroSheet; * 如果在Release模式下如果创建了ST_DialogSheet或者ST_MacroSheet将会失败, * 而Q_ASSERT在Release下如果失效则会导致sheetNames添加未创建的sheetName; * */ void Test2::on_but_addSheet_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } AbstractSheet::SheetType type = (AbstractSheet::SheetType)ui->com_sheetType->currentIndex(); bool ret = m_xlsx->addSheet(strName, type); // 创建一个新的工作表,参数二可以省略 if(ret && m_xlsx->save()) // 执行完 *** 作后需要保存到原有Excel中,不保存则无效 { qInfo() << QString("创建工作表:%1 %2 成功!").arg(strName).arg(type); } else { qWarning() << QString("创建工作表:%1 %2 失败!").arg(strName).arg(type); } } /** * @brief 在指定位置插入工作表,可设置工作表名称和类型 */ void Test2::on_but_insert_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } AbstractSheet::SheetType type = (AbstractSheet::SheetType)ui->com_sheetType->currentIndex(); int index = ui->spin_index->value(); bool ret = m_xlsx->insertSheet(index, strName, type); if(ret && m_xlsx->save()) { qInfo() << QString("在%1位置插入工作表:%2 %3 成功!").arg(index).arg(strName).arg(type); } else { qWarning() << QString("在%1位置插入工作表:%2 %3 失败!").arg(index).arg(strName).arg(type); } } /** * @brief 将输入名称的工作表设置为活动工作表,并写入数据,如果工作表不存在或者不是ST_WorkSheet类型则不写入 */ void Test2::on_but_select_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } bool ret = m_xlsx->selectSheet(strName); // 将strName设置为活动工作表 if(ret) { qInfo() << QString("设置活动工作表%1成功!").arg(strName); AbstractSheet::SheetType type = m_xlsx->currentSheet()->sheetType(); // 获取当前工作表的类型 if(type == AbstractSheet::ST_WorkSheet) { ret = m_xlsx->write(1, 1, "设置获取工作表!"); if(ret && m_xlsx->save()) { qInfo() << "将数据写入选择的工作表成功!"; } else { qInfo() << "将数据写入选择的工作表失败!"; } } else { qInfo() << "其它类型sheet,不写入数据"; } } else { qWarning() << QString("设置活动工作表%1失败,可能不存在!").arg(strName); } } /** * @brief 重命名sheet */ void Test2::on_but_rename_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } QString strNewName = ui->line_newSheetName->text(); if(strNewName.isEmpty()) { qWarning() << "新的工作表名称不能为空!"; return; } bool ret = m_xlsx->renameSheet(strName, strNewName); if(ret && m_xlsx->save()) { qInfo() << QString("将%1重命名为%2成功!").arg(strName, strNewName); } else { qWarning() << QString("将%1重命名为%2失败!").arg(strName, strNewName); } } /** * @brief 将指定的strName工作表拷贝为strNewName,如果strNewName已存在则拷贝失败 */ void Test2::on_but_copy_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } QString strNewName = ui->line_newSheetName->text(); if(strNewName.isEmpty()) { qWarning() << "新的工作表名称不能为空!"; return; } bool ret = m_xlsx->copySheet(strName, strNewName); // 开始拷贝工作表 if(ret && m_xlsx->save()) { qInfo() << QString("将%1拷贝为%2成功!").arg(strName, strNewName); } else { qWarning() << QString("将%1拷贝为%2失败!").arg(strName, strNewName); } } /** * @brief 根据输入的工作表名称,将工作表移动到指定位置,如果工作表不存在或移动到当前位置则失败 * 移动位置从0开始,如果大于sheet总数则移动到最后位置,如果小于0则移动到最开始位置 */ void Test2::on_but_move_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } int index = ui->spin_index->value(); bool ret = m_xlsx->moveSheet(strName, index); // 开始移动工作表位置 if(ret && m_xlsx->save()) { qInfo() << QString("将%1移动到%2位置成功!").arg(strName).arg(index); } else { qWarning() << QString("将%1移动到%2位置失败!").arg(strName).arg(index); } } /** * @brief 删除指定名称的工作表,如果指定名称的工作表不存在则返回失败 */ void Test2::on_but_delete_clicked() { QString strName = ui->line_sheetName->text(); if(strName.isEmpty()) { qWarning() << "工作表名称不能为空!"; return; } bool ret = m_xlsx->deleteSheet(strName); // 开始删除 if(ret && m_xlsx->save()) { qInfo() << QString("删除工作表%1成功!").arg(strName); } else { qWarning() << QString("删除工作表%1失败!").arg(strName); } }

5、实现效果🎡
  • 功能较多,没有一一演示

6、源代码🏠

gitee
github

⛹🏋🚴🤸🤸‍♂️🤼🤾

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/673377.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存