QT-功能--使用QAxObject和QAxBase将tableview或tablewidget数据导入导出为Excel

本文主要是介绍QT-功能--使用QAxObject和QAxBase将tableview或tablewidget数据导入导出为Excel,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

此中解决方式是为了将tableview和tablewidget中的数据进行导出为Excel文件和将Excel文件导入为tableview和tablewidget中。故将其构建成了一个封装类。附一封装好了的类文件导入导出类封装

1,使用操作Excel文件的类

为了能调用系统中的Excel应用(以office2016为例)在项目工程文件中,添加如下

QT       += axcontainer

2,构建一个名叫ExcelEngine的类。在其中写入对Excel文件的执行操作

excelengine.h
1)添加所需 头文件
#include <QObject>
#include <QFile>
#include <QString>
#include <QStringList>
#include <QVariant>
#include <QAxBase>
#include <QAxObject>
#include <QTableWidget>
#include <QTableView>
#include <QTableWidgetItem>
#include <QDebug>
2)头文件中函数声明与变量定义
public:ExcelEngine();ExcelEngine(QString xlsFile);~ExcelEngine();
public:bool Open(UINT nSheet = 1,bool visible = false);          //打开xls文件bool Open(QString xlsFile,UINT nSheet = 1,bool visible = false);void Save();                                              //保存xls报表void Close();                                             //关闭xls报表bool SaveDataFrTable(/*QTableWidget* tableWidget,*/QTableView *tableview,QString titile);          //保存数据到xlsbool ReadDataToTable(/*QTableWidget* tableWidget,*/QTableView *tableview);          //从xls读取数据到uiQVariant GetCellData(UINT row,UINT column);               //获取指定单元数据bool     SetCellData(UINT row,UINT column,QVariant data); //修改指定单元数据UINT GetRowCount()const;								  //获取行数UINT GetColumnCount()const;								  //获取列数bool IsOpen();											  //检验bool IsValid();											  //检验
protected:void Clear();
private:QAxObject *pExcel;       //指向整个excel应用程序QAxObject *pWorkbooks;   //指向工作簿集,excel有很多工作簿QAxObject *pWorkbook;    //指向sXlsFile对应的工作簿QAxObject *pWorksheet;   //指向工作簿中的某个sheet表单QString   sXlsFile;      //xls文件路径UINT      nCurrSheet;    //当前打开的第几个sheetbool      bIsVisible;    //excel是否可见int       nRowCount;     //行数int       nColumnCount;  //列数int       nStartRow;     //开始有数据的行下标值int       nStartColumn;  //开始有数据的列下标值bool      bIsOpen;       //是否已打开bool      bIsValid;      //是否有效bool      bIsANewFile;   //是否是一个新建xls文件,用来区分打开的excel是已存在文件还是有本类新建的bool      bIsSaveAlready;//防止重复保存
这里因为考虑到tablewidget和tableview的不同,所以将函数中注释了不同的参数,可以对比食用。
excelengine.cpp函数体
这里将最重要的导入导出函数进行实现
1)导出为excel文件
bool ExcelEngine::SaveDataFrTable(/*QTableWidget *tableWidget,*/QTableView *tableview,QString title)
{
//    /*第一种方法,暂时在tablewidget中可以实现*/
//    QString fileName = QFileDialog::getSaveFileName(tableview, "保存",QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xls *.xlsx)");
//    if(fileName != NULL);
//    {
//        QStandardItemModel *model = new QStandardItemModel();
//        tableview->setModel(model);
//        if(NULL == tableview)
//        {
//            return false;
//        }
//        if(!bIsOpen)
//        {
//            return false;
//        }
//    //    int tableR = tableWidget->rowCount();
//    //    int tableC = tableWidget->columnCount();
//        int tableR = model->rowCount();
//        int tableC = model->columnCount();//        //获取表头写做第一行
//        for(int i=0;i<tableC;i++)
//        {
//            //if(tableWidget->horizontalHeaderItem(i) != NULL)
//            if(model->horizontalHeaderItem(i) != NULL)
//            {
//                //this->SetCellData(1,i+1,tableWidget->horizontalHeaderItem(i)->text());
//                this->SetCellData(1,i+1,model->horizontalHeaderItem(i)->text());
//            }
//        }
//        //写数据
//        for(int i=0;i<tableR;i++)
//        {
//            for(int j=0;j<tableC;j++)
//            {
//                //if(tableWidget->item(i,j) != NULL)
//                if(model->item(i,j) != NULL)
//                {
//                    //this->SetCellData(i+2,j+1,tableWidget->item(i,j)->text());
//                    this->SetCellData(i+2,j+1,model->item(i,j)->text());
//                }
//            }
//        }
//        //保存
//        Save();
//        return true;
//    }/*第二种方法,针对于tableview*/QString fileName = QFileDialog::getSaveFileName(tableview, "保存",QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xls *.xlsx)");if (fileName!=""){QAxObject *excel = new QAxObject;if (excel->setControl("Excel.Application"))				    //连接Excel控件{excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体excel->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合workbooks->dynamicCall("Add");							 //新建一个工作簿QAxObject *workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿QAxObject *worksheet = workbook->querySubObject("Worksheets(int)", 1);int i,j;//QTableView 获取列数int colcount=tableview->model()->columnCount();int rowcount = tableview->model()->rowCount();QAxObject *cell,*col;//标题行cell=worksheet->querySubObject("Cells(int,int)", 1, 1);cell->dynamicCall("SetValue(const QString&)", title);cell->querySubObject("Font")->setProperty("Size", 18);//调整行高worksheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);//合并标题行QString cellTitle;cellTitle.append("A1:");cellTitle.append(QChar(colcount - 1 + 'A'));cellTitle.append(QString::number(1));QAxObject *range = worksheet->querySubObject("Range(const QString&)", cellTitle);range->setProperty("WrapText", true);range->setProperty("MergeCells", true);range->setProperty("HorizontalAlignment", -4108);//xlCenterrange->setProperty("VerticalAlignment", -4108);//xlCenter//列标题for(i=0;i<colcount;i++){QString columnName;columnName.append(QChar(i  + 'A'));columnName.append(":");columnName.append(QChar(i + 'A'));col = worksheet->querySubObject("Columns(const QString&)", columnName);col->setProperty("ColumnWidth", tableview->columnWidth(i)/6);cell=worksheet->querySubObject("Cells(int,int)", 2, i+1);columnName=tableview->model()->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString();cell->dynamicCall("SetValue(const QString&)", columnName);cell->querySubObject("Font")->setProperty("Bold", true);cell->querySubObject("Interior")->setProperty("Color",QColor(191, 191, 191));cell->setProperty("HorizontalAlignment", -4108);//xlCentercell->setProperty("VerticalAlignment", -4108);//xlCenter}//QTableView 获取表格数据部分for(i=0;i<rowcount;i++) //行数{for (j=0;j<colcount;j++)   //列数{QModelIndex index = tableview->model()->index(i, j);QString strdata=tableview->model()->data(index).toString();worksheet->querySubObject("Cells(int,int)", i+3, j+1)->dynamicCall("SetValue(const QString&)", strdata);}}//画框线QString lrange;lrange.append("A2:");lrange.append(colcount - 1 + 'A');//lrange.append(QString::number(table->rowCount() + 2));lrange.append(QString::number(tableview->model()->columnCount() + 2));range = worksheet->querySubObject("Range(const QString&)", lrange);range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));//调整数据区行高QString rowsName;rowsName.append("2:");rowsName.append(QString::number(tableview->model()->rowCount() + 2));range = worksheet->querySubObject("Range(const QString&)", rowsName);range->setProperty("RowHeight", 20);workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(fileName));//保存至fileNameworkbook->dynamicCall("Close()");//关闭工作簿excel->dynamicCall("Quit()");//关闭exceldelete excel;excel=NULL;if (QMessageBox::question(NULL,"完成","文件已经导出,是否现在打开?",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes){QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));}}else{QMessageBox::warning(NULL,"错误","未能创建 Excel 对象,请安装 Microsoft Excel。",QMessageBox::Apply);}}}
这里采用了两种不同的方式对表格文件中的数据进行在excel文件的的边框绘制和导出,方法一经检验可以在tablewidget中更好的绘制出数据,而方法二效果更显著。
2)导入Excel文件到tableview中
bool ExcelEngine::ReadDataToTable(/*QTableWidget *tableWidget,*/QTableView *tableview)
{QStandardItemModel *model = new QStandardItemModel();tableview->setModel(model);//model->setho//tableview->horizontalHeader()->setResizeMode(0,QHeaderView::Fixed);if(NULL == tableview){return false;}//先把table的内容清空// int tableColumn = tableWidget->columnCount();int tablecol = tableview->model()->columnCount();//tableWidget->clear();tableview->clearSpans();for(int n=0;n<tablecol;n++){//tableWidget->removeColumn(0);tableview->model()->removeColumn(0);}int rowcnt    = nStartRow + nRowCount;int columncnt = nStartColumn + nColumnCount;//获取excel中的第一行数据作为表头QStringList headerList;for(int n = nStartColumn;n<columncnt;n++){QAxObject* cell = pWorksheet->querySubObject("Cells(int,int)",nStartRow, n);if(cell){headerList<<cell->dynamicCall("Value2()").toString();}}//重新创建表头
//    tableWidget->setColumnCount(nColumnCount);
//    tableWidget->setHorizontalHeaderLabels(headerList);model->setColumnCount(nColumnCount);model->setHeaderData(0,Qt::Horizontal,headerList);//插入新数据for(int i=nStartRow+1,r=0;i<rowcnt;i++,r++)//行{//tableWidget->insertRow(r); //插入新行model->insertRow(r);for(int j=nStartColumn,c=0;j<columncnt;j++,c++)//列{QAxObject * cell = pWorksheet->querySubObject("Cells(int,int)",i,j);//获取单元格if(cell){//tableWidget->setItem(r,c,new QTableWidgetItem(cell->dynamicCall("Value2()").toString()));model->setItem(r,c, new QStandardItem(cell->dynamicCall("Value2()").toString()));}}}return true;
}
将导入导出功能设置为bool函数,故成功与否只有true和false
3)类调用实例
//导入
void mywidget::on_button_import_clicked()
{QString fileName = QFileDialog::getOpenFileName(this,"打开",QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xls *.xlsx)");ExcelEngine excel(fileName);excel.Open();excel.ReadDataToTable(ui->tableView); //导入到widget中excel.Close();
}//导出
void mywidget::on_button_export_clicked()
{//第二种方法成功对tableview保存QString fileName = " ";ExcelEngine excel(fileName);excel.SaveDataFrTable(ui->tableView,"简单测试"); //导出到widget中//第一种方法试验对tableview保存出现bug
//    QString filename = QFileDialog::getSaveFileName(this, "保存",QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"Excel 文件(*.xls *.xlsx)");
//    ExcelEngine excel(filename);
//    excel.SaveDataFrTable(ui->tableView," ");
//    //excel.Close();}
如果想成功运行的话只需要忽略注释即可,由于篇幅问题,导入功能中的open和close函数这里没有给出,有兴趣的可以自己按照这个方式激发灵感写一下,或者可以去康康鄙人上传至csdn上的封装好了类封装类。

3.效果展示

在这里插入图片描述

这个界面由两个button和一个tableview显示区域构成,这里主要以tableview为例做主要展示,tablewidget只需要改变一下就行了。
1)导入展示

在这里插入图片描述

我这里有一个excel文件。直接将其导入进去
2)导出展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4,注意

用此种方式操作的excel文件,容易使杀毒软件检测出"有程序正在修改文件"之类的提示项,建议允许或者将杀毒软件关闭,即可成功导出文件。

这篇关于QT-功能--使用QAxObject和QAxBase将tableview或tablewidget数据导入导出为Excel的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/226095

相关文章

Qt之QMessageBox的具体使用

《Qt之QMessageBox的具体使用》本文介绍Qt中QMessageBox类的使用,用于弹出提示、警告、错误等模态对话框,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.简单介绍3.常见函数4.按钮类型(QMessage::StandardButton)5.分步骤实现弹窗6.总结1.引言

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

Qt中Qfile类的使用

《Qt中Qfile类的使用》很多应用程序都具备操作文件的能力,包括对文件进行写入和读取,创建和删除文件,本文主要介绍了Qt中Qfile类的使用,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.QFile文件操作3.演示示例3.1实验一3.2实验二【演示 QFile 读写二进制文件的过程】4.

spring security 超详细使用教程及如何接入springboot、前后端分离

《springsecurity超详细使用教程及如何接入springboot、前后端分离》SpringSecurity是一个强大且可扩展的框架,用于保护Java应用程序,尤其是基于Spring的应用... 目录1、准备工作1.1 引入依赖1.2 用户认证的配置1.3 基本的配置1.4 常用配置2、加密1. 密

Python处理超大规模数据的4大方法详解

《Python处理超大规模数据的4大方法详解》在数据的奇妙世界里,数据量就像滚雪球一样,越变越大,从最初的GB级别的小数据堆,逐渐演变成TB级别的数据大山,所以本文我们就来看看Python处理... 目录1. Mars:数据处理界的 “变形金刚”2. Dask:分布式计算的 “指挥家”3. CuPy:GPU

WinForms中主要控件的详细使用教程

《WinForms中主要控件的详细使用教程》WinForms(WindowsForms)是Microsoft提供的用于构建Windows桌面应用程序的框架,它提供了丰富的控件集合,可以满足各种UI设计... 目录一、基础控件1. Button (按钮)2. Label (标签)3. TextBox (文本框

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

MySQL Workbench工具导出导入数据库方式

《MySQLWorkbench工具导出导入数据库方式》:本文主要介绍MySQLWorkbench工具导出导入数据库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录mysql Workbench工具导出导入数据库第一步 www.chinasem.cn数据库导出第二步

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

如何合理使用Spring的事务方式

《如何合理使用Spring的事务方式》:本文主要介绍如何合理使用Spring的事务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、底层构造1.1.事务管理器1.2.事务定义信息1.3.事务状态1.4.联系1.2、特点1.3、原理2. Sprin