一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

 1、概述

  QXlsx是一个可以读写Excel文件的库。不依赖office以及wps组件,可以在Qt5支持的任何平台上使用;

使用方式:

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

本文中实现的功能:

1 创建一个新的Excel,并具有一个默认的Sheet;
2 打开Excel文件,并判断是否打开成功;
3 分别使用单元格引用和行列号两种方式将数据写入Excel;
4 分别使用单元格引用和行列行两种方式读取Excel所有数据;
5 将Excel数据另存为2.xlsx;
6 释放Excel数据。

2、QXlsx和QAxObject 读写Excel比较
  QAxObject使用需要系统中安装了offie或wps,这种方法不推荐使用;
  因为如果安装了wps,可能部分功能用不了;
  同时安装了office、wps在使用时可能有问题;
  或者电脑里安装了一些pdf阅读器则直接不能使用了;
  QXlsx不依赖于系统环境,使用时打开excel文件将所有数据读入内存,然后就关闭文件了,也不存在文件被占用的情况。

3、准备工作

3.1 下载源码

https://github.com/QtExcel/QXlsx

本文中使用到的QXlsx版本为:1.4.3

3.2 使用QXlsx

下载后如下图所示:里面的QXlsx为我们需要用到的源码,其它的为一些官方的示例代码;

 打开QXlsx文件夹后如下图所示:通过QXlsx.pro打开可以编译为动态库使用,在程序里加载QXlsx.pri可以直接使用源码。

 将QXlsx源码文件夹拷贝到创建的Qt工程路径下(也可以是其它路径)

4、示例代码🍌

4.1 加载QXlsx源码🍍

在工程的.pro文件中添加下列代码,

注意QXlsx文件夹的路径改成自己的

1 include($$PWD/QXlsx/QXlsx.pri)             # QXlsx源代码
2 INCLUDEPATH += $$PWD/QXlsx

4.2 .h文件

 1 #ifndef TEST1_H
 2 #define TEST1_H
 3 
 4 #include <QWidget>
 5 #include "xlsxdocument.h"
 6 
 7 
 8 namespace Ui {
 9 class Test1;
10 }
11 
12 class Test1 : public QWidget
13 {
14     Q_OBJECT
15 
16 public:
17     explicit Test1(QWidget *parent = nullptr);
18     ~Test1();
19 
20 private slots:
21     void on_but_open_clicked();
22 
23     void on_but_init_clicked();
24     void on_but_write_clicked();
25 
26     void on_but_recv_clicked();
27 
28     void on_but_saveAs_clicked();
29 
30     void on_but_close_clicked();
31 
32 private:
33     Ui::Test1 *ui;
34 
35     QXlsx::Document* m_xlsx = nullptr;
36 };
37 
38 #endif // TEST1_H

4.3 .cpp文件

  1 #include "test1.h"
  2 #include "ui_test1.h"
  3 #include <QDebug>
  4 
  5 QXLSX_USE_NAMESPACE            // 添加Xlsx命名空间
  6 
  7 #define EXCEL_NAME "./1.xlsx"  // 本demo中用到的excel文件路径文件名
  8 
  9 Test1::Test1(QWidget *parent) :
 10     QWidget(parent),
 11     ui(new Ui::Test1)
 12 {
 13     ui->setupUi(this);
 14     this->setWindowTitle("QXlsx基本读写Excel");
 15 
 16 }
 17 
 18 Test1::~Test1()
 19 {
 20     delete ui;
 21 }
 22 
 23 /**
 24  * @brief 创建一个excel文件
 25  */
 26 void Test1::on_but_init_clicked()
 27 {
 28     Document xlsx;                      // 初始化后默认有一个sheet1
 29 //    doc.addSheet("第一个sheet", AbstractSheet::ST_WorkSheet);  // 添加第一个sheet,如果不添加则会有一个默认的
 30     bool ret = xlsx.saveAs(EXCEL_NAME); // 保存到EXCEL_NAME,如果已经存在则覆盖
 31     if(ret)
 32     {
 33         qInfo() << "创建excel成功!";
 34     }
 35     else
 36     {
 37         qWarning() << "创建excel失败!";
 38     }
 39 }
 40 
 41 /**
 42  * @brief 打开文件并判断是否打开成功
 43  */
 44 void Test1::on_but_open_clicked()
 45 {
 46     if(!m_xlsx)
 47     {
 48         m_xlsx = new Document(EXCEL_NAME, this);        // 打开EXCEL_NAME文件,将所有数据读取到内存中,然后关闭excel文件
 49     }
 50     if(m_xlsx->load())  // 判断文件是否打开成功(也可以使用isLoadPackage)
 51     {
 52         qInfo() << "excel打开成功!";
 53 
 54         ui->but_write->setEnabled(true);
 55         ui->but_recv->setEnabled(true);
 56         ui->but_saveAs->setEnabled(true);
 57         ui->but_close->setEnabled(true);
 58     }
 59     else
 60     {
 61         qWarning() << "excel打开失败!";
 62     }
 63 }
 64 
 65 /**
 66  * @brief 使用两种不同的方式将数据写入excel,未指定sheet则默认为sheet1
 67  */
 68 void Test1::on_but_write_clicked()
 69 {
 70 #if 0
 71     m_xlsx->write("A2", 123);         // 从A1开始
 72     m_xlsx->write("B2", 0.001);
 73     m_xlsx->write("C2", "abc");
 74     m_xlsx->write("D2", true);
 75     m_xlsx->write("E2", "你好");
 76 #else
 77     m_xlsx->write(1, 1, 456);        // 从1,1开始
 78     m_xlsx->write(1, 2, 0.002);
 79     m_xlsx->write(1, 3, "aaa");
 80     m_xlsx->write(1, 4, false);
 81     m_xlsx->write(1, 5, "阿斯蒂芬");
 82 #endif
 83     if(m_xlsx->save())
 84     {
 85         qInfo() << "数据写入成功!";
 86     }
 87     else
 88     {
 89         qWarning() << "数据写入失败!";
 90     }
 91 }
 92 
 93 /**
 94  * @brief 读取excel中所有数据
 95  */
 96 void Test1::on_but_recv_clicked()
 97 {
 98     int rowLen = m_xlsx->dimension().rowCount();           // 获取最大行数
 99     int columnLen = m_xlsx->dimension().columnCount();     // 获取最大列数
100     for(int i = 1; i <= rowLen; i++)                       // 遍历每一行
101     {
102         QString data = QString("第%1行:").arg(i);
103         for(int j = 1; j <= columnLen; j++)                // 遍历每一个单元格(列)
104         {
105 #if 1
106             QVariant value = m_xlsx->read(i, j);                                         // 通过单元格行号、列号读取数据
107 #else
108             QVariant value = m_xlsx->read(QString("%1%2").arg((char)(64 + i)).arg(j));   // 通过单元格引用读取数据
109 #endif
110             if(!value.isNull())
111             {
112                 data.append(value.toString()).append(" ");
113             }
114             else
115             {
116                 data.append("NULL ");
117             }
118         }
119         qInfo() << data;
120     }
121 
122 }
123 
124 /**
125  * @brief 将数据另存到2.xlsx
126  */
127 void Test1::on_but_saveAs_clicked()
128 {
129     if(m_xlsx->saveAs("./2.xlsx"))
130     {
131         qInfo() << "另存为2.xlsx";
132     }
133     else
134     {
135         qWarning() << "文件另存为失败!";
136     }
137 }
138 
139 /**
140  * @brief 释放数据
141  */
142 void Test1::on_but_close_clicked()
143 {
144     delete m_xlsx;
145     m_xlsx = nullptr;
146     ui->but_write->setEnabled(false);
147     ui->but_recv->setEnabled(false);
148     ui->but_saveAs->setEnabled(false);
149     ui->but_close->setEnabled(false);
150 }

5、实现效果

 

 

posted on 2023-03-22 15:49  一杯清酒邀明月  阅读(4414)  评论(1编辑  收藏  举报