第四个小收获:
众所周知,qt可以使用tableWidget来显示表格数据,但是有时候需要将数据保存起来,那么该如何保存呢,之前的项目中有遇到过这种需求,就是将表格内容导出为excel表,直接了当看数据,自己也是在东找西找翻了很久~
直接上代码:
目录
首先:随便搭建一个tableWidget的随便几条数据
并且要在.pro文件 内引入QT += axcontainer(必须)
.h头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
signals:
/**
* @brief sendExportPercent 导出表格内容时的进度信号
* @param iValue 进度值
*/
void SignalExportPercent(const int iValue);
private slots:
/**
* @brief on_pushButton_clicked 点击导出槽函数
*/
void on_pushButton_export_clicked();
private:
/**
* @brief ExportTableWidgetToExcel 导出table表内的内容为excel表函数
* @return true成功 false失败
*/
bool ExportTableWidgetToExcel();
private:
Ui::Widget *ui;
/**
* @brief m_strPath 保存路径
*/
QString m_strPath;
};
#endif // WIDGET_H
.cpp文件
#include "Widget.h"
#include "ui_Widget.h"
#include <QDesktopServices>
#include <QTableWidget>
#include <QAxObject>
#include <QDebug>
#include <Ole2.h>
#include <QDir>
#include <QScopedPointer>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),
m_strPath("")
{
ui->setupUi(this);
// 导出路径随便写的 可按需写函数更改 要把文件名带上
m_strPath = QDir::currentPath() + "/test.xlsx";
// 连接导出进度信号供界面显示
connect(this, &Widget::SignalExportPercent, ui->progressBar, [=](const int iValue){
ui->progressBar->setValue(iValue);
});
}
Widget::~Widget()
{
delete ui;
}
/**
* @brief ExportTableWidgetToExcel 导出table表内的内容为excel表函数
* @return true成功 false失败
*/
bool Widget::ExportTableWidgetToExcel()
{
bool bRTN = true;
// win7系统兼容
HRESULT Hresult = OleInitialize(nullptr); // 头文件ole2.h
// 进度是比较随意的写的 可以自行更改
int iPercent = 10;
if(m_strPath != "")
{
QScopedPointer<QAxObject> pAoExcel(new QAxObject);
if(pAoExcel->setControl("Excel.Application"))
{
// 发送加载进度
emit SignalExportPercent(iPercent);
pAoExcel->dynamicCall("SetVisible (bool Visible)",false);
pAoExcel->setProperty("DisplayAlerts",false);
// 获取工作簿集合
QAxObject *pWorkbooks = pAoExcel->querySubObject("Workbooks");
// 新建一个工作簿
pWorkbooks->dynamicCall("Add");
// 获取当前工作簿
QAxObject *pWorkbook = pAoExcel->querySubObject("ActiveWorkBook");
QAxObject *pWorksheet = pWorkbook->querySubObject("Worksheets(int)", 1);
QAxObject *pCell;
//添加Excel表头数据
for(int i = 1; i <= ui->tableWidget->columnCount(); i++)
{
pCell = pWorksheet->querySubObject("Cells(int,int)", 1, i);
// 设置表头高度
pCell->setProperty("RowHeight", 40);
pCell->dynamicCall("SetValue(const QString&)",ui->tableWidget->
horizontalHeaderItem(i-1)->data(0).toString());
if(iPercent <= 50)
{
emit SignalExportPercent(10 + i * 5);
iPercent = 10 + i * 5;
}
}
//添加Excel内容数据
for(int j = 2; j<=ui->tableWidget->rowCount()+1;j++)
{
for(int k = 1;k<=ui->tableWidget->columnCount();k++)
{
pCell = pWorksheet->querySubObject("Cells(int,int)", j, k);
// 设置每行高度
pCell->setProperty("RowHeight", 20);
// 设置每行宽度
pCell->setProperty("ColumnWidth",20);
if(ui->tableWidget->item(j-2,k-1)!=NULL)
{
pCell->dynamicCall("SetValue(const QString&)",
ui->tableWidget->item(j-2,k-1)->text()+ "\t");
}
}
if(iPercent<80)
{
emit SignalExportPercent(50+j * 5);
}
}
iPercent = 100;
emit SignalExportPercent(iPercent);
// 将生成的Excel文件保存到指定目录下m_strPath下
pWorkbook->dynamicCall("SaveAs(const QString&)",
QDir::toNativeSeparators(m_strPath));
// 关闭工作簿
pWorkbook->dynamicCall("Close()");
// 关闭excel
pAoExcel->dynamicCall("Quit()");
}
}
else
{
bRTN = false;
}
return bRTN;
}
/**
* @brief on_pushButton_clicked 点击导出槽函数
*/
void Widget::on_pushButton_export_clicked()
{
// 运行导出
this->ExportTableWidgetToExcel();
}
运行结果
表格数据如下(因为我路径写在根目录的,所以保存在运行目录里面)
最后:使用的时候,一般是放在线程内的,不然数据多了,会很耗时,出现未响应等问题。
使用的时候创个线程,加个接口更改下文件保存路径即可,还有要值得注意的是,我的实例化指针用的是智能指针,因为我写测试程序的时候,发现,如果电脑上的excel未激活,我的就是未激活的,会频繁导致程序崩溃并弹窗警告未激活,偶尔会成功-.-!不知道如何解决还...所以用智能指针,能自己释放一下内存
再记录一个超级好用的清空表格内容的做法,一直在用~因为直接pTable->clear()不会删除行内容,只会清除数据,所以需要清空的时候,就照如下写
QTableWidget *pTable = ui->tableWidget;
//清除表格内容
for(int row = pTable->rowCount() - 1;row >= 0; row--)
{
pTable->removeRow(row);
}