QT读取Excel表格内容到Table Widget

QT读取Excel表格内容到Table Widget

前言

有一个需求是要把Excel的数据导入到QT的Table Widget表格中。我是一个QT新手,在网上找了很多方法,在这里汇总记录一下。

导读

目前总共有四种方法:

一、ODBC 导入
二、QAxObject 导入
三、QXlsx 导入
四、复制导入

其中方法一至三适用于不加密的Excel文件,如果公司的Excel文件是加密过的,这三个方法是处理不了的,在我使用时是这样,如果有大佬懂的话请多指教。复制导入加密的Excel也能处理的,除非连复制黏贴都加密了,那真是离谱。

一、ODBC 导入

首先需要确认是否存在处理Excel的DSN
我们可以在C:\Windows\SysWOW64文件夹中找到odbcad32.exe,打开
如果有下面这个就可以了,没有的话看看添加里面有没有,还是没有就再找其他文章安装对应的东西吧,这里就不扩展了
在这里插入图片描述
然后就直接写代码就好了,先随便建个QT项目,随便搞个界面
在这里插入图片描述

在.pro文件中加入sql
在这里插入图片描述
头文件中加入这些

#include <QStandardPaths>
#include <QFileDialog>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QMessageBox>
#include <QDebug>

随便在界面中加个按钮,然后创建一个**clicked()**的槽函数
函数代码如下:

void MainWindow::on_pushButton_clicked()
{
    //桌面打开//Qt4
    //QString desktopDir=QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
    //Qt 5
    QString desktopDir=QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    //选择Excel文件,并获取路径
    QString filePath=QFileDialog::getOpenFileName(NULL,"选择Excel",desktopDir,"*.xlsx *.xls");
    if(filePath.isNull()){
        QMessageBox::warning(NULL, "错误提示", "无法打开excel文件");
        return;
    }
    
    //读取excel
    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC","excel");
    if(!db.isValid())
    {
        QMessageBox::warning(NULL, "错误提示", "数据库驱动异常");
        db.close();
        return;
    }

    QString dsn = QString("Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Readonly=TRUE;DBQ=%1;").arg(filePath);
    db.setDatabaseName(dsn);
    if(!db.open())
    {
        QMessageBox::warning(NULL, "错误提示", "无法打开数据库");
        db.close();
        return;
    }
    QSqlQuery query(db);
    QString tableName = "Sheet1$"; //sheet名,$是必须的
    QString sql="select * from ["+tableName+"]";
    query.exec(sql);

    int row = 1; //行号
    while (query.next()) {
        //每次query就是一行数据
        for (int i = 0; i < ui->tableWidget->columnCount() - 1; i++)
        {
            QTableWidgetItem *item = new QTableWidgetItem(QString::number(query.value(i).toDouble(), 'f', 2));
            ui->tableWidget->setItem(row, i + 1, item);
        }
        row++;
    }
    query.clear();
    db.close();
}

使用ODBC时,Excel中的数据格式:
在这里插入图片描述
第一行是字段名,格式比较固定

二、QAxObject 导入

这个需要在.pro文件中加入axcontainer
在这里插入图片描述
头文件中需要加入

#include <QStandardPaths>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QAxObject>

代码:

void MainWindow::on_pushButton_2_clicked()
{
    QString desktopDir=QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString path=QFileDialog::getOpenFileName(NULL,"选择Excel",desktopDir,"*.xlsx *.xls");
    QAxObject *excel = NULL;
    QAxObject *workbooks = NULL;
    QAxObject *workbook = NULL;
    excel = new QAxObject(this);
    if (!excel->setControl("Excel.Application"))
    {
        excel->setControl("ket.Application");
    }
    if (!excel)
    {
        QMessageBox::critical(NULL, "错误信息", "EXCEL对象丢失");
        return;
    }
    excel->dynamicCall("SetVisible(bool)", false);
    workbooks = excel->querySubObject("WorkBooks");
    workbook = workbooks->querySubObject("Open(const QString&)",path);
    QAxObject * worksheet = workbook->querySubObject("WorkSheets(int)", 1); // 获取第一个工作sheet
    QAxObject * usedrange = worksheet->querySubObject("UsedRange");//获取该sheet的使用范围对象
    QAxObject * rows = usedrange->querySubObject("Rows");
    QAxObject * columns = usedrange->querySubObject("Columns");

    /*获取行数和列数*/
    int intCols = columns->property("Count").toInt();
    int intRows = rows->property("Count").toInt();
    int intRowStart = usedrange->property("Row").toInt();
    int intColStart = usedrange->property("Column").toInt();

    /*获取excel内容*/
    for (int i = intRowStart; i < intRowStart + intRows; i++)  //行
    {
        for (int j = intColStart; j < intColStart + intCols; j++)
        {
            QAxObject *cell = worksheet->querySubObject("Cells(int,int)", i, j);
            QTableWidgetItem *item = new QTableWidgetItem(QString::number(cell->dynamicCall("Value2()").toDouble(), 'f', 2));
            ui->tableWidget->setItem(i, j, item);
            delete cell;
        }
    }
    // 关闭excel
    workbook->dynamicCall("Close(Boolean)",true);
    excel->dynamicCall("Quit(void)");
    delete excel;
    excel = NULL;
}

wps使用的是ket.Application
使用这个时Excel表格的数据格式是这样的:
在这里插入图片描述
不需要第一行那个字段名了,直接全是数据就行,但是这种方法处理的速度很慢,可以说是四种方法中最慢的了

三、QXlsx导入

这是QT官方推荐的一个开源项目,看github上好像是一个韩国人开发的
项目的github地址:https://github.com/QtExcel/QXlsx
当然他也有告诉我们安装的步骤:https://github.com/QtExcel/QXlsx/blob/master/HowToSetProject.md
那我就大致翻译一下吧
首先我们先把项目克隆到本地
在一个新建的文件夹中打开cmd
在这里插入图片描述
然后在字符界面中输入下面的命令,回车

git clone https://github.com/j2doll/QXlsx.git

在这里插入图片描述
下载完成就是一个QXlsx的文件夹
在这里插入图片描述
然后打开这个文件夹,里面还有一个QXlsx,把里面的
在这里插入图片描述
复制到自己项目的主目录下面
在这里插入图片描述
在自己项目的.pro文件中添加

# QXlsx code for Application Qt project
QXLSX_PARENTPATH=./         # current QXlsx path is . (. means curret directory)
QXLSX_HEADERPATH=./header/  # current QXlsx header path is ./header/
QXLSX_SOURCEPATH=./source/  # current QXlsx source path is ./source/
include(./QXlsx.pri)

在这里插入图片描述
然后头文件添加

#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"
using namespace QXlsx;

完整代码:

void MainWindow::on_pushButton_3_clicked()
{
    QString desktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString filepath = QFileDialog::getOpenFileName(NULL,"选择Excel",desktopDir,"*.xlsx *.xls");
    Document xlsxR(filepath);
    if (xlsxR.load()) //加载Excel文件
    {
        for (int row = 1; row <= 4; row++)
        {
            for (int col = 1; col <= 4; col++)
            {
                Cell* cell = xlsxR.cellAt(row, col); //获取具体位置单元格
                if (cell != NULL)
                {
                    QVariant var = cell->readValue(); // 读取单元格的内容
                    QTableWidgetItem *item = new QTableWidgetItem(QString::number(var.toDouble(), 'f', 2));
                    ui->tableWidget->setItem(row, col, item);
                }
                else
                {
                    QMessageBox::warning(NULL, "错误提示", "Excel表格数据格式错误");
                    return;
                }
            }
        }
    }
}

注意:它的第一个数据的下标是从1开始的
这种方法的代码量比前面的少,看起来很简洁,速度也快

四、复制导入

我用上面的三种方法都发现无法处理公司的加密Excel。虽然可以先解密再导入,但是解密要申请太麻烦了,所以我就想到这种逆天的做法:直接手动复制Excel中想要导入的内容,然后处理系统剪切板中复制到的内容形成一个数组,再依次绘制在表格中,这样就不用管加不加密了。不过面对连复制黏贴都加密的,也是没用的。而且逼格看起来就没用前面那些看起来高级,显得有点low,哈哈哈
需要导入的头文件:

//获取剪切板内容
#include <QClipboard>
#include <QApplication>
#include <QMimeData>
#include <QMessageBox>

代码:

void MainWindow::on_pushButton_4_clicked()
{
    //获取剪切板内容
    QClipboard *clipboard = QApplication::clipboard();
    QString copyContent = clipboard->text();
	
	//更新 2022-08-03 :在实际应用中出现复制到粘贴板的数据是以"\n"和"\t"连接,少了一个空格,所以会有两种情况
	//我们需要先判断能否使用" \n"分割,若不匹配则改为使用"\n"分割
	QString regex1 = " \n";
	QString regex2 = " \t";
	if (copyContent.split(" \n").size() <= 1)
	{
		regex1 = "\n";
		regex2 = "\t";
	}
    QStringList splitList = copyContent.split(regex1);
    QStringList dataList;
    for (int i = 0; i < splitList.size() - 1; i++)
    {
        dataList.append(splitList.at(i).split(regex2));
    }
    if (dataList.size() != 4 * 4)
    {
        QMessageBox::warning(NULL, "错误提示", "请复制正确的表格内容");
        return;
    }
    for (int i = 0; i < dataList.size(); i++)
    {
        qDebug()<<dataList.at(i);
    }

    for (int i = 0; i < ui->tableWidget->rowCount() - 1; i++)
    {
        for (int j = 0; j < ui->tableWidget->columnCount() - 1; j++)
        {
            QTableWidgetItem *item = new QTableWidgetItem(dataList.at(i * 4 + j));
            ui->tableWidget->setItem(i + 1, j + 1, item);
        }
    }
}

剪切板中的内容是这样的:
注意:可能会出现"\t","\n"前面没有空格的情况

"2.00 \t5.00 \t10.00 \t9.00 \n10.00 \t0.00 \t0.00 \t11.00 \n0.00 \t0.00 \t0.00 \t12.00 \n6.00 \t7.00 \t8.00 \t88.00 \n"

所以就先用 \n 来分割成每一行,再用 \t 分割成每个单元格存入数组列表中,注意前面还有个空格
由于是复制的,所以数据在哪个位置都没问题
在这里插入图片描述
我这个操作是先手动复制数据,然后点击界面的按钮进行处理
在这里插入图片描述

结尾

ok,就这么多了,不知道大伙儿还有什么其他方法吗?如果对我这篇文章有不解和建议的话,可以直接评论或者私信我哦。

补充-QT选cmake创建的项目如何使用QXlsx

首先我是直接用Qt自带的IDE选cmake创建的项目。创建完成后编译运行看看有没有问题(一般都不会有问题吧,我选的mingw编译)。
确认项目正常后,从克隆下来的QXlsx项目文件夹中,把QXlsx文件夹拷到我们的项目目录下:
在这里插入图片描述
在QXlsx中也有一个CMakeLists.txt文件,把里面include(CPackConfig)这一句#注释掉并保存,不然后面编译的时候会报错:
在这里插入图片描述在这里插入图片描述
现在回到我们自己项目的CMakeLists.txt中,在add_executable之前添加一句add_subdirectory(QXlsx),在自动生成的target_link_libraries({您的项目名称} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)中空格添加QXlsx,如:target_link_libraries({您的项目名称} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets QXlsx)
在这里插入图片描述
在这里插入图片描述
OK,现在我们再尝试编译项目,如果没有报错,那么就成功连接了QXlsx项目了,项目结构也会多出来QXlsx
在这里插入图片描述
这边也提供了简单的Demo,大家可以看看有没有用,QT版本是5.15.2的,在下面附件中

附件

这个演示的项目下载地址(免费的免费的)
https://download.csdn.net/download/qq_16186465/85847594
QXlsx资源下载地址(这是我自己上传的,也可以去github正版官网下)
https://download.csdn.net/download/qq_16186465/85847616
QT选择cmake创建的项目使用QXlsx Demo
https://download.csdn.net/download/qq_16186465/89695939

### 回答1: Python有很多工具可以用来读取Excel文件,其一种常用的方法是使用pandas库的read_excel()函数。 要读取Excel文件表格数据,我们首先需要安装pandas库。可以使用以下命令在Python环境安装pandas: ```python pip install pandas ``` 安装完成后,我们可以使用下面的代码来读取Excel文件表格数据: ```python import pandas as pd # 读取Excel文件 dataframe = pd.read_excel('filename.xlsx', sheet_name='sheet_name') # 打印表格数据 print(dataframe) ``` 在上面的代码,'filename.xlsx'表示Excel文件的路径和文件名,'sheet_name'表示要读取的工作表名称。如果Excel文件只有一个工作表,可以将'sheet_name'参数省略不写。 read_excel()函数返回的是一个DataFrame对象,它是pandas库用于操作和分析表格数据的一种数据结构。可以使用DataFrame的各种方法和属性来进一步处理数据,比如对表格进行切片、筛选数据等。 需要注意的是,pandas库还提供了许多其他的参数和选项,可以用来处理不同的情况和需求。通过查阅pandas官方文档,可以获取更详细的信息和示例代码。 以上就是使用Python的pandas库来读取Excel文件表格数据的简单介绍。希望对你有帮助! ### 回答2: Python的Table Widget是一个强大的工具,可以读取和处理Excel文件。在Python,我们可以使用openpyxl库来操作Excel文件。这个库允许我们读取、写入和修改Excel文件内容。 要读取Excel文件并在Table Widget显示数据,我们需要先安装openpyxl库。可以使用pip命令来安装它:pip install openpyxl。 一旦安装了openpyxl库,我们就可以使用它来读取Excel文件并将数据加载到Table Widget。首先,我们需要导入相应的库和模块: import openpyxl from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem 然后,我们需要打开Excel文件读取并加载数据到Table Widget: app = QApplication([]) table = QTableWidget() wb = openpyxl.load_workbook('example.xlsx') sheet = wb.active 第一行是表头,我们需要读取表头数据并设置表头行数和列数: table.setColumnCount(sheet.max_column) table.setRowCount(sheet.max_row - 1) 接下来,我们需要将Excel的数据写入Table Widget: # 读取表头数据 for column in range(sheet.max_column): header_item = sheet.cell(row=1, column=column+1).value table.setHorizontalHeaderItem(column, QTableWidgetItem(str(header_item))) # 读取数据行并写入Table Widget for row in range(2, sheet.max_row + 1): for column in range(sheet.max_column): cell_data = sheet.cell(row=row, column=column+1).value table_item = QTableWidgetItem(str(cell_data)) table.setItem(row-2, column, table_item) 最后,我们将Table Widget显示在应用程序table.show() app.exec_() 上述代码可以实现读取Excel文件并将数据加载到Table Widget,方便我们对数据进行展示和处理。当然,还可以利用其他库和模块对Excel数据进行更多复杂的操作,比如筛选、排序和计算等。 ### 回答3: Python的Table Widget可以使用一些库来读取Excel文件。其,openpyxl和pandas是两个常用的库。下面将分别介绍这两个库的用法。 1. 使用openpyxl库读取Excel文件: - 首先,需要先安装openpyxl库。可以使用pip命令进行安装:pip install openpyxl。 - 下面的代码片段演示了如何使用openpyxl库读取Excel文件的数据,并打印出表格内容: ```python import openpyxl # 打开Excel文件 wb = openpyxl.load_workbook('文件路径.xlsx') # 选择Sheet sheet = wb['Sheet1'] # 遍历表格的行 for row in sheet.iter_rows(): # 遍历每行的单元格 for cell in row: # 打印单元格的 print(cell.value) ``` 2. 使用pandas库读取Excel文件: - 首先,需要先安装pandas库。可以使用pip命令进行安装:pip install pandas。 - 下面的代码片段演示了如何使用pandas库读取Excel文件的数据,并打印出表格内容: ```python import pandas as pd # 读取Excel文件,并选择Sheet df = pd.read_excel('文件路径.xlsx', sheet_name='Sheet1') # 打印表格内容 print(df) ``` - 上述代码,使用pandas的read_excel函数读取Excel文件,并将结果存储在DataFrame对象。最后,使用print函数打印出DataFrame对象内容。 以上两种方法都可以用于读取Excel文件表格数据。具体使用哪个方法,可以根据自己的需求和喜好来选择。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1594231563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值