请注意,在工程文件pro里,增加CONFIG += qaxcontainer。
有的网帖上写的是CONFIG += axcontainer,经测试,通不过。
或者在工程配置如下图修改:
源代码:
#ifndef QTEXCEL_H
#define QTEXCEL_H
#include
#include
#include
#include
#include
#include
#include
typedef unsigned int UINT;
class QtExcel
{
public:
QtExcel();
QtExcel(QString xlsFile);
~QtExcel();
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报表
QVariant GetCellData(UINT row, UINT column); //获取指定单元数据
QVariantList GetCellData(QString strRange); //获取多个单元数据,写法为“A2:C60”
bool SetCellData(UINT row, UINT column, QVariant data); //修改指定单元数据
bool IsOpen();
bool IsValid();
protected:
void Clear();
private:
QAxObject *m_pExcel; //指向整个excel应用程序
QAxObject *m_pWorkbooks; //指向工作簿集,excel有很多工作簿
QAxObject *m_pWorkbook; //指向sXlsFile对应的工作簿
QAxObject *m_pWorksheet; //指向工作簿中的某个sheet表单
QString m_strXlsFile; //xls文件路径
UINT m_nCurrSheet; //当前打开的第几个sheet
bool m_bIsVisible; //excel是否可见
int m_nRowCount; //行数
int m_nColumnCount; //列数
int m_nStartRow; //开始有数据的行下标值
int m_nStartColumn; //开始有数据的列下标值
bool m_bIsOpen; //是否已打开
bool m_bIsValid; //是否有效
bool m_bIsANewFile; //是否是一个新建xls文件,用来区分打开的excel是已存在文件还是有本类新建的
bool m_bIsSaveAlready;//防止重复保存
};
#endif // QTEXCEL_H
源文件CPP
#include "QtExceL.h"
#include
QtExcel::QtExcel()
{
m_pExcel = NULL;
m_pWorkbooks = NULL;
m_pWorkbook = NULL;
m_pWorksheet = NULL;
m_strXlsFile = "";
m_nRowCount = 0;
m_nColumnCount = 0;
m_nStartRow = 0;
m_nStartColumn = 0;
m_bIsOpen = false;
m_bIsValid = false;
m_bIsANewFile = false;
m_bIsSaveAlready = false;
HRESULT r = OleInitialize(0);
if (r != S_OK && r != S_FALSE)
{
qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
}
}
QtExcel::QtExcel(QString xlsFile)
{
m_pExcel = NULL;
m_pWorkbooks = NULL;
m_pWorkbook = NULL;
m_pWorksheet = NULL;
m_strXlsFile = xlsFile;
m_nRowCount = 0;
m_nColumnCount = 0;
m_nStartRow = 0;
m_nStartColumn = 0;
m_bIsOpen = false;
m_bIsValid = false;
m_bIsANewFile = false;
m_bIsSaveAlready = false;
HRESULT r = OleInitialize(0);
if (r != S_OK && r != S_FALSE)
{
qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
}
}
QtExcel::~QtExcel()
{
if (m_bIsOpen)
{
//析构前,先保存数据,然后关闭workbook
Close();
}
OleUninitialize();
}
bool QtExcel::Open(UINT nSheet, bool visible)
{
if (m_bIsOpen)
{
Close();
}
m_nCurrSheet = nSheet;
m_bIsVisible = visible;
if (NULL == m_pExcel)
{
m_pExcel = new QAxObject("Excel.Application");
if (m_pExcel)
{
m_bIsValid = true;
}
else
{
m_bIsValid = false;
m_bIsOpen = false;
return m_bIsOpen;
}
m_pExcel->dynamicCall("SetVisible(bool)", m_bIsVisible);
}
if (!m_bIsValid)
{
m_bIsOpen = false;
return m_bIsOpen;
}
if (m_strXlsFile.isEmpty())
{
m_bIsOpen = false;
return m_bIsOpen;
}
/*如果指向的文件不存在,则需要新建一个*/
QFile f(m_strXlsFile);
if (!f.exists())
{
m_bIsANewFile = true;
}
else
{
m_bIsANewFile = false;
}
if (!m_bIsANewFile)
{
m_pWorkbooks = m_pExcel->querySubObject("WorkBooks"); //获取工作簿
m_pWorkbook = m_pWorkbooks->querySubObject("Open(QString, QVariant)", m_strXlsFile, QVariant(0)); //打开xls对应的工作簿
}
else
{
m_pWorkbooks = m_pExcel->querySubObject("WorkBooks"); //获取工作簿
m_pWorkbooks->dynamicCall("Add"); //添加一个新的工作薄
m_pWorkbook = m_pExcel->querySubObject("ActiveWorkBook"); //新建一个xls
}
m_pWorksheet = m_pWorkbook->querySubObject("WorkSheets(int)", m_nCurrSheet);//打开第一个sheet
//至此已打开,开始获取相应属性
QAxObject *usedrange = m_pWorksheet->querySubObject("UsedRange"); //获取该sheet的使用范围对象
QAxObject *rows = usedrange->querySubObject("Rows");
QAxObject *columns = usedrange->querySubObject("Columns");
//因为excel可以从任意行列填数据而不一定是从0,0开始,因此要获取首行列下标
m_nStartRow = usedrange->property("Row").toInt(); //第一行的起始位置
m_nStartColumn = usedrange->property("Column").toInt(); //第一列的起始位置
m_nRowCount = rows->property("Count").toInt(); //获取行数
m_nColumnCount = columns->property("Count").toInt(); //获取列数
m_bIsOpen = true;
return m_bIsOpen;
}
bool QtExcel::Open(QString xlsFile, UINT nSheet, bool visible)
{
m_strXlsFile = xlsFile;
m_nCurrSheet = nSheet;
m_bIsVisible = visible;
return Open(m_nCurrSheet, m_bIsVisible);
}
void QtExcel::Save()
{
if (m_pWorkbook)
{
if (m_bIsSaveAlready)
{
return;
}
if (!m_bIsANewFile)
{
m_pWorkbook->dynamicCall("Save()");
}
else /*如果该文档是新建出来的,则使用另存为COM接口*/
{
m_pWorkbook->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)",
m_strXlsFile, 56, QString(""), QString(""), false, false);
}
m_bIsSaveAlready = true;
}
}
void QtExcel::Close()
{
Save();//关闭前先保存数据
if (m_pExcel && m_pWorkbook)
{
m_pWorkbook->dynamicCall("Close(bool)", true);
m_pExcel->dynamicCall("Quit()");
delete m_pExcel;
m_pExcel = NULL;
m_bIsOpen = false;
m_bIsValid = false;
m_bIsANewFile = false;
m_bIsSaveAlready = true;
}
}
QVariant QtExcel::GetCellData(UINT row, UINT column)
{
QVariant data;
QAxObject *cell = m_pWorksheet->querySubObject("Cells(int,int)", row, column);//获取单元格对象
if (cell)
{
data = cell->dynamicCall("Value2()");
}
return data;
}
QVariantList QtExcel::GetCellData(QString strRange)
{
QVariantList data;
// strRange = "a1:C10"
QAxObject *cell = m_pWorksheet->querySubObject("Range(QString)", strRange);//获取单元格对象
if (cell)
{
data = cell->property("Value").toList();
}
return data;
}
bool QtExcel::SetCellData(UINT row, UINT column, QVariant data)
{
bool op = false;
QAxObject *cell = m_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;
}
void QtExcel::Clear()
{
m_strXlsFile = "";
m_nRowCount = 0;
m_nColumnCount = 0;
m_nStartRow = 0;
m_nStartColumn = 0;
}
bool QtExcel::IsOpen()
{
return m_bIsOpen;
}
bool QtExcel::IsValid()
{
return m_bIsValid;
}