最近用Qt对Excel文件进行操作,出现了程序中释放了Excel进程,而任务管理器中仍存在未关闭的Excel进程的现象。
查找了之后,发现是由于我在调用完Excel进程之后,没有彻底关闭Excel进程。
以下是对Excel文件操作的代码:
//获取文件名称
void MainWindow::GetFileName()
{
QString FileName = QFileDialog::getOpenFileName(this,"打开Excel文件",QDir::currentPath(),tr("Excel file(*.xls *.xlsx)"));
QString Printf = QString("添加Excel文件为:%1").arg(FileName);
ui->textBrowser->append(Printf);
if(FileName.isEmpty())
{
QMessageBox::information(this,"错误信息","没有选择波形文件");
return;
}
QFile *file = new QFile;
file->setFileName(FileName);
bool OK = false;
OK = file->open(QIODevice::ReadOnly);
if(OK)
{
OpenDataFile(FileName);
}
else
{
QMessageBox::information(this,"错误信息","无法读取所选择的文件");
return;
}
}
void MainWindow::OpenDataFile(QString FileName)
{
//加载Excel驱动
// QAxObject excel("Excel.Application");
//20181027:Tengfei:修改加载excel驱动的方式,以便于后面delete excel进程
QAxObject *excel = new QAxObject(this);
excel->setControl("Excel.Application");
//不显示Excel界面,如果为true会看到启动的Excel界面
excel->setProperty("Visible",false);
QAxObject *pWorkBooks = excel->querySubObject("WorkBooks");
pWorkBooks->dynamicCall("Open(const QString&)",FileName);//打开指定文件
QAxObject *pWorkBook = excel->querySubObject("ActiveWorkBook");
QAxObject *pWorkSheets = pWorkBook->querySubObject("Sheets");//获取工作表
int nSheetCount = pWorkSheets->property("Count").toInt();//获取工作表的数目
if((nSheetCount > 0))
{
//读取第一张工作表
Timer.start();
QAxObject *pWorkSheet = pWorkBook->querySubObject("Sheets(int)",1);//获取第一张表
QAxObject *usedRange = pWorkSheet->querySubObject("UsedRange");//获取该sheet的使用范围对象
QAxObject *rows = usedRange->querySubObject("Rows");
QAxObject *columns = usedRange->querySubObject("Columns");
int intRows = rows->property("Count").toInt();
int intColumns = columns->property("Count").toInt();
QVariant cell = usedRange->dynamicCall("Value");
QVariantList cellList = cell.toList();
ui->textBrowser->append(QString("选取的文件第一张工作表的大小为:%1*%2").arg(intRows).arg(intColumns));
//20181027:Tengfei:获取第一张表的第一列的第一行,作为DataName
QVariantList cellList_i = cellList[0].toList();
DataName = cellList_i[0].toString();
//释放Excel进程
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel->dynamicCall("Quit(void)");
delete excel;
for(int i = 1;i < intRows;i++)
{
cellList_i = cellList[i].toList();
Data.append(cellList_i[0].toFloat());
}
ui->textBrowser->append(QString("完成读取波形数据,用时:%1s").arg(Timer.elapsed()/1000.0));
}
else
{
}
}
先说说加载Excel驱动,加载Excel驱动的方式有两种:
第一种:
QAxObject excel("Excel.Application");
用这种方式加载Excel驱动的话,在关闭Excel线程时,只需要关闭文档并退出Excel进程就可以了,执行以下代码:
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
第二种:
QAxObject *excel = new QAxObject(this);
excel->setControl("Excel.Application");
这种方式与第一种的不同在于,创建了一个QAxObject类的指针,然后将指针指向了Excel.Application;
用这种方式加载Excel驱动的话,在关闭Excel线程时,需要关闭文档,退出Excel进程,以及释放指针;执行以下代码:
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel->dynamicCall("Quit(void)");
delete excel;
正常按照以上关闭Excel线程的方式,是能够正常关闭Excel进程,同时任务栏管理器中也不会存在未关闭的Excel线程。
但是执行我上面的获取文件名称以及打开文件的代码时,任务管理器中存在未关闭的Excel进程。经过查找,是由于我在得到文件名称之后,检查该文件是否可读的时候:
QFile *file = new QFile;
file->setFileName(FileName);
bool OK = false;
OK = file->open(QIODevice::ReadOnly);
我在检查完该文件是否可读之后,并没有将*file释放掉,从而导致了还存在未关闭的Excel进程。
修改:
QFile *file = new QFile;
file->setFileName(FileName);
bool OK = false;
OK = file->open(QIODevice::ReadOnly);
delete file;