- 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👈 |
-
QXlsx是一个可以读写Excel文件的库。
不依赖office以及wps组件,可以在Qt5支持的任何平台上使用;
-
使用方式
- QXlsx可以编译为动态库使用(使用动态库不用每次的编译,也可以让项目代码量更少,不用一打开工程就几十个文件);
- 直接将QXlsx.pri加入代码中使用(我比较推荐直接使用源码,因为QXlsx的注释信息基本在cpp文件中,可以通过阅读源码和注释来学习QXlsx的功能,当然,如果你已经熟悉了QXlsx的使用方式那编译成库使用会更方便,可以使工程的代码量变少);
-
本文中实现的功能:
- 查询打开的Excel中所有可用的工作表(Sheet)名称;
- 创建指定名称的工作表(Sheet),自动添加到最末尾,支持ST_WorkSheet、ST_ChartSheet两种类型;
- 在指定位置插入一个新的指定名称的工作表(Sheet),支持ST_WorkSheet、ST_ChartSheet两种类型;
- 将某个工作表(Sheet)设置为当前活动工作表,并写入数据(ST_WorkSheet类型);
- 将指定名称的工作表(Sheet)重命名为一个新的名称,不改变其它因素;
- 将指定名称的工作表(Sheet)拷贝为一个新的指定名称的工作表,两个工作表内容相同;
- 将指定名称的工作表(Sheet)移动到指定位置;
- 删除指定名称的工作表(Sheet)。
- 👉👉👉👉👉👉👉看前几章内容。
注意:执行了 *** 作要保存才生效。
⛔
-
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;
- 如果需要移动的工作表名称不存在则失败;
- 返回值: 移动成功返回true,失败返回false;
-
bool deleteSheet(const QString &name) - 功能说明: 删除指定名称的工作表;
- 参数name: 需要参数的工作表名称;
- 返回值: 删除成功返回true,失败返回false;
- 如果指定名称的工作表不存在则返回失败。
- 如果指定名称的工作表不存在则返回失败。
#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、实现效果🎡
-
功能较多,没有一一演示
gitee
github
⛹🏋🚴🤸🤸♂️🤼🤾
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)