首先在.pro文件中添加以下代码:
CONFIG += \ qaxcontainer #excel
接下来就是Excel代码:cpp文件:
#include "excelengine.h" #include "qt_windows.h" QExcelEngine::QExcelEngine() { pExcel = NULL; pWorkbooks = NULL; pWorkbook = NULL; pWorksheet = NULL; sXlsFile = ""; nRowCount = 0; nColumnCount = 0; nStartRow = 0; nStartColumn = 0; bIsOpen = false; bIsValid = false; bIsANewFile = false; bIsSaveAlready = false; HRESULT r = OleInitialize(0); if (r != S_OK && r != S_FALSE) { qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r); } } QExcelEngine::QExcelEngine(QString xlsFile) { pExcel = NULL; pWorkbooks = NULL; pWorkbook = NULL; pWorksheet = NULL; sXlsFile = xlsFile; nRowCount = 0; nColumnCount = 0; nStartRow = 0; nStartColumn = 0; bIsOpen = false; bIsValid = false; bIsANewFile = false; bIsSaveAlready = false; HRESULT r = OleInitialize(0); if (r != S_OK && r != S_FALSE) { qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r); } } QExcelEngine::~QExcelEngine() { if ( bIsOpen ) { //析构前,先保存数据,然后关闭workbook Close(); } OleUninitialize(); } /** *@brief 打开sXlsFile指定的excel报表 *@return true : 打开成功 * false: 打开失败 */ bool QExcelEngine::Open(int nSheet, bool visible) { if ( bIsOpen ) { Close(); } nCurrSheet = nSheet; bIsVisible = visible; if ( NULL == pExcel ) { pExcel = new QAxObject("Excel.Application"); //连接Excel控件 if ( pExcel ) { bIsValid = true; } else { bIsValid = false; bIsOpen = false; return bIsOpen; } pExcel->dynamicCall("SetVisible(bool)", bIsVisible); //bIsVisible 是否显示窗体 pExcel->setProperty("DisplayAlerts", false); //不显示任何警告信息 pWorkbooks = pExcel->querySubObject("WorkBooks"); //获取工作簿 } if ( !bIsValid ) { bIsOpen = false; return bIsOpen; } if ( sXlsFile.isEmpty() ) { bIsOpen = false; return bIsOpen; } //如果指向的文件不存在,则需要新建一个 QFile f(sXlsFile); if (!f.exists()) { bIsANewFile = true; } else { bIsANewFile = false; } if (!bIsANewFile) { pWorkbook = pWorkbooks->querySubObject("Open(QString, QVariant)", sXlsFile, QVariant(0)); //打开xls对应的工作簿 } else { pWorkbooks->dynamicCall("Add"); //添加一个新的工作薄 pWorkbook = pExcel->querySubObject("ActiveWorkBook"); //新建一个xls } pWorksheet = pWorkbook->querySubObject("WorkSheets(int)", nCurrSheet);//打开第一个sheet //至此已打开,开始获取相应属性 QAxObject *usedrange = pWorksheet->querySubObject("UsedRange");//获取该sheet的使用范围对象 QAxObject *rows = usedrange->querySubObject("Rows"); QAxObject *columns = usedrange->querySubObject("Columns"); //因为excel可以从任意行列填数据而不一定是从0,0开始,因此要获取首行列下标 nStartRow = usedrange->property("Row").toInt(); //第一行的起始位置 nStartColumn = usedrange->property("Column").toInt(); //第一列的起始位置 nRowCount = rows->property("Count").toInt(); //获取行数 nColumnCount = columns->property("Count").toInt(); //获取列数 bIsOpen = true; return bIsOpen; } /** *@brief Open()的重载函数 */ bool QExcelEngine::Open(QString xlsFile, int nSheet, bool visible) { sXlsFile = xlsFile; nCurrSheet = nSheet; bIsVisible = visible; return Open(nCurrSheet,bIsVisible); } /** *@brief 保存表格数据,把数据写入文件 */ void QExcelEngine::Save() { if ( pWorkbook ) { if (bIsSaveAlready) { return ; } if (!bIsANewFile) { pWorkbook->dynamicCall("Save()"); } else /*如果该文档是新建出来的,则使用另存为COM接口*/ { // pWorkbook->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)", // sXlsFile,56,QString(""),QString(""),false,false); pWorkbook->dynamicCall("SaveAs(const QString&)", sXlsFile); } bIsSaveAlready = true; } } /** *@brief 关闭前先保存数据,然后关闭当前Excel COM对象,并释放内存 */ void QExcelEngine::Close() { //关闭前先保存数据 // Save(); if ( pExcel && pWorkbook ) { pWorkbook->dynamicCall("Close(bool)", true); pExcel->dynamicCall("Quit()"); delete pExcel; pExcel = NULL; bIsOpen = false; bIsValid = false; bIsANewFile = false; bIsSaveAlready = true; } } /** *@brief 把tableWidget中的数据保存到excel中 *@param tableWidget : 指向GUI中的tablewidget指针 *@return 保存成功与否 true : 成功 * false: 失败 */ bool QExcelEngine::SaveDataFrTable(QTableWidget *tableWidget) { if ( NULL == tableWidget ) { return false; } if ( !bIsOpen ) { return false; } int tableR = tableWidget->rowCount(); int tableC = tableWidget->columnCount(); //获取表头写做第一行 for (int i=0; i<tableC; i++) { if ( tableWidget->horizontalHeaderItem(i) != NULL ) { this->SetCellData(1, i+1, tableWidget->horizontalHeaderItem(i)->text()); } } //写数据 for (int i=0; i<tableR; i++) { for (int j=0; j<tableC; j++) { if ( tableWidget->item(i,j) != NULL ) { this->SetCellData(i+2, j+1, tableWidget->item(i,j)->text()); } } } //保存 Save(); return true; } /** *@brief 从指定的xls文件中把数据导入到tableWidget中 *@param tableWidget : 执行要导入到的tablewidget指针 *@return 导入成功与否 true : 成功 * false: 失败 */ bool QExcelEngine::ReadDataToTable(QTableWidget *tableWidget) { if ( NULL == tableWidget ) { return false; } //先把table的内容清空 int tableColumn = tableWidget->columnCount(); tableWidget->clear(); for (int n=0; n<tableColumn; n++) { tableWidget->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); //插入新数据 for (int i = nStartRow + 1, r = 0; i < rowcnt; i++, r++ ) //行 { tableWidget->insertRow(r); //插入新行 for (int j = nStartColumn, c = 0; j < columncnt; j++, c++ ) //列 { QAxObject * cell = pWorksheet->querySubObject("Cells(int,int)", i, j );//获取单元格 //在r新行中添加子项数据 if ( cell ) { tableWidget->setItem(r,c,new QTableWidgetItem(cell->dynamicCall("Value2()").toString())); tableWidget->item(r, c)->setTextAlignment(Qt::AlignCenter); } } } return true; } /** *@brief 获取指定单元格的数据 *@param row : 单元格的行号 *@param column : 单元格的列号 *@return [row,column]单元格对应的数据 */ QVariant QExcelEngine::GetCellData(int row, int column) { QVariant data; QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//获取单元格对象 if ( cell ) { data = cell->dynamicCall("Value2()"); } return data; } /** *@brief 修改指定单元格的数据 *@param row : 单元格的行号 *@param column : 单元格指定的列号 *@param data : 单元格要修改为的新数据 *@return 修改是否成功 true : 成功 * false: 失败 */ bool QExcelEngine::SetCellData(int row, int column, QVariant data) { bool op = false; QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//获取单元格对象 if ( cell ) { QString strData = data.toString(); //excel 居然只能插入字符串和整型,浮点型无法插入 cell->dynamicCall("SetValue(const QVariant&)",strData); //修改单元格的数据 op = true; } else { op = false; } return op; } /** * @brief 清空整个Excel表格 */ void QExcelEngine::ClearAllData(QString strData) { for (int i=0; i<nStartRow+nRowCount; i++) { for (int j=0; j<nStartColumn+nColumnCount; j++) { this->SetCellData(i, j, strData); } } //保存 Save(); } /** *@brief 清空除报表之外的数据 */ void QExcelEngine::Clear() { sXlsFile = ""; nRowCount = 0; nColumnCount = 0; nStartRow = 0; nStartColumn = 0; } /** *@brief 判断excel是否已被打开 *@return true : 已打开 * false: 未打开 */ bool QExcelEngine::IsOpen() { return bIsOpen; } /** *@brief 判断excel COM对象是否调用成功,excel是否可用 *@return true : 可用 * false: 不可用 */ bool QExcelEngine::IsValid() { return bIsValid; } /** *@brief 获取excel的行数 */ int QExcelEngine::GetRowCount() const { return nRowCount; } /** *@brief 获取excel的列数 */ int QExcelEngine::GetColumnCount() const { return nColumnCount; }
.h文件:
#include <QFile> #include <QMessageBox> #include <QString> #include <QDebug> #include <QTableWidget> #include <QAxObject> class QExcelEngine { public: QExcelEngine(); QExcelEngine(QString xlsFile); ~QExcelEngine(); public: bool Open(int nSheet, bool visible); bool Open(QString xlsFile, int nSheet, bool visible); void Save(); void Close(); bool SaveDataFrTable(QTableWidget *tableWidget); bool ReadDataToTable(QTableWidget *tableWidget); QVariant GetCellData(int row, int column); bool SetCellData(int row, int column, QVariant data); void ClearAllData(QString strData); void Clear(); bool IsOpen(); bool IsValid(); int GetRowCount() const; int GetColumnCount() const; private: QAxObject *pExcel; QAxObject *pWorkbooks; QAxObject *pWorkbook; QAxObject *pWorksheet; QString sXlsFile; int nRowCount; int nColumnCount; int nStartRow; int nStartColumn; int nCurrSheet; bool bIsVisible; bool bIsOpen; bool bIsValid; bool bIsANewFile; bool bIsSaveAlready; };
接下来就是调用了,首先从Excel表格导入到tableWeight,我这里是点击按钮实现,代码如下:
void QEnteringWidget::slotExcelInto() { QMessageBox::StandardButton rb = QMessageBox::information(this, "warning", "从excel文件中导入数据将会覆盖之前所有内容,\n确定导入吗?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(rb == QMessageBox::Yes) { //从Excel中将表格导入到TableWidget excelEngine = new QExcelEngine; m_fileName = QFileDialog::getOpenFileName(this, tr("select file"), "../datafile/", tr("*.xls *.xlsx")); if(m_fileName.isEmpty()) return; loadingWidget.show(); bool b = excelEngine->Open(m_fileName, 1, false); //flase为不显示窗体 if(b == false) { QMessageBox::information(this, "excel提示", "文件打开失败"); return; } excelEngine->ReadDataToTable(tableWidget); excelEngine->Close(); loadingWidget.close(); } }
调用tableweight导入到Excel表格,代码如下:
void QDemandWidget::slotIntoExcel() { excelEngine = new QExcelEngine; filename = QFileDialog::getSaveFileName(this, tr("Save as..."), "../datafile", tr("EXCEL files (*.xls *.xlsx);;HTML-Files (*.txt);;")); if(filename.isEmpty()) return; loadingWidget.show(); bool b = excelEngine->Open(filename, 1, false); //flase为不显示窗体 if(b == false) { QMessageBox::information(this, "excel提示", "文件打开失败"); return; } //清空表格之前的所有内容 excelEngine->ClearAllData(" "); excelEngine->Close(); //打开数据库,并保存数据 // excelEngine->Open(filename, 1, false); // excelEngine->SaveDataFrTable(tableWidget); // excelEngine->Close(); loadingWidget.close(); QMessageBox::information(this, "excel提示", "导入成功"); }