首先在.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; ihorizontalHeaderItem(i) != NULL )
{
this->SetCellData(1, i+1, tableWidget->horizontalHeaderItem(i)->text());
}
}
//写数据
for (int i=0; iitem(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; nremoveColumn(0);
}
int rowcnt = nStartRow + nRowCount;
int columncnt = nStartColumn + nColumnCount;
//获取excel中的第一行数据作为表头
QStringList headerList;
for (int n = nStartColumn; nquerySubObject("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; iSetCellData(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
#include
#include
#include
#include
#include
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提示", "导入成功");
}