Excel表格在日常工作中使会经常用的,有时候程序中需要生成测试报告就需要用到Excel,在此封装了一个类QExcel,方便后续使用。示例如下:

excel = new QExcel(); //新建对象

excel->open("C:\\Users\\Administrator\\Desktop\\www.xls"); //打开一个Excel文件
for (int i=1; i<=10; i++)
{
for (int j=1; j<=10; j++)
{
excel->setCellString(i,j,QString::number(i+j));
}
}
excel->setCellBackground(1,1,Qt::red);
excel->setCellBackground(2,2,Qt::green);
excel->setCellBackground(3,3,Qt::blue);
excel->setCellBackground(4,4,Qt::yellow);
excel->setCellBackground(5,5,Qt::gray);
excel->save(); //保存文件

//=================================================================
注意:
1、打开文件和创建文件,二选一,即可使用所有提供的功能;
2、操作完成之后记得保存文件(调用save()函数)和退出Excel(调用quit()函数)
3、行、列都是从1开始,填0行0列,程序崩溃
//=================================================================

excel->createFile("C:\\Users\\Administrator\\Desktop\\Test.xls"); //创建一个Excel文件
for (int i=1; i<=10; i++)
{
for (int j=1; j<=10; j++)
{
excel->setCellString(i,j,QString::number(i+j));
}
}
excel->setCellBackground(1,1,Qt::red);
excel->setCellBackground(2,2,Qt::green);
excel->setCellBackground(3,3,Qt::blue);
excel->setCellBackground(4,4,Qt::yellow);
excel->setCellBackground(5,5,Qt::gray);
excel->save(); //保存文件

excel->quit(); //退出Excel

需在​​.pro​​​工程文件中添加​​axcontainer​​库

QT       +=

头文件

#ifndef QEXCEL_H
#define QEXCEL_H

#include <QString>
#include <QColor>
#include <QVariant>
#include <QAxObject>
#include <QFile>
#include <QStringList>
#include <QDebug>

class QAxObject;

class QExcel : public QObject
{
public:
QExcel(QObject *parent = nullptr);
~QExcel();

public:
QAxObject * getWorkBooks();
QAxObject * getWorkBook();
QAxObject * getWorkSheets();
QAxObject * getWorkSheet();

public:
/***************************************************************************/
/* 文件操作 */
/**************************************************************************/

void open(QString FileName); //打开文件
void createFile(QString FileName); //创建文件
void save(); //保存Excel文件
void quit(); //退出Excel

/**************************************************************************/
/* 工作表操作 */
/*************************************************************************/
void selectSheet(const QString& sheetName); //根据名字选择工作表
void selectSheet(int sheetIndex); //根据下标索引选择工作表,下标从1开始
void deleteSheet(const QString& sheetName); //根据名字删除工作表
void deleteSheet(int sheetIndex); //根据下标索引删除工作表,下标从1开始
void insertSheet(QString sheetName); //新建工作表
int getSheetsCount(); //获取工作表数量
QString getSheetName(); //获取当前活跃工作表的名字
QString getSheetName(int sheetIndex); //根据下标索引获取工作表名字

/***************************************************************************/
/* 单元格操作 */
/**************************************************************************/
void mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn); //根据行列编号合并单元格
void mergeCells(const QString& range); //根据字母编号合并单元格,例如(A5:C7)
void setCellString(int row, int column, const QString& value); //根据行列编号设置单元格数据,例如(1,1,"xxx")
void setCellString(const QString& cell, const QString& value); //根据字母编号设置单元格数据,例如("A5","xxx")
bool setRowData(int row,int colum_start,int column_end,QVariant vData); //批量写入一行数据
QString getRange_fromColumn(int column); //根据列值计算出字母值
QVariant getCellValue(int row, int column); //根据行列编号获取单元格数值
QVariant getCellValue(const QString& cell); //根据字母编号获取单元格数值
void clearCell(int row, int column); //根据行列编号清空单元格
void clearCell(const QString& cell); //根据字母编号清空单元格
void setCellFontBold(int row, int column, bool isBold); //根据行列编号设置单元格字体是否加粗
void setCellFontBold(const QString& cell, bool isBold); //根据字母编号设置单元格字体是否加粗
void setCellFontSize(int row, int column, int size); //根据行列编号设置单元格字体大小
void setCellFontSize(const QString& cell, int size); //根据字母编号设置单元格字体大小
void setCellTextCenter(int row, int column); //根据行列编号设置单元格内容居中
void setCellTextCenter(const QString& cell); //根据字母编号设置单元格内容居中
void setCellTextWrap(int row, int column, bool isWrap); //根据行列编号设置单元格内容是否换行
void setCellTextWrap(const QString& cell, bool isWrap); //根据字母编号设置单元格内容是否换行
void setCellBackground(int row, int column, QColor color); //根据行列编号设置单元格背景色
void setCellBackground(const QString& cell, QColor color); //根据字母编号设置单元格背景色
void setCellFontColor(int row, int column, QColor color); //根据行列编号设置单元格字体颜色
void setCellFontColor(const QString& cell, QColor color); //根据字母编号设置单元格字体颜色
void setCellBorderColor(int row, int column, QColor color); //根据行列编号设置单元格边框颜色
void setCellBorderColor(const QString& cell, QColor color); //根据字母编号设置单元格边框颜色

void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn); //取得工作表已使用范围
void setColumnWidth(int column, int width); //设置列宽
void setRowHeight(int row, int height); //设置行高
void setAutoFitRow(int row); //设置自适应行高
void mergeSerialSameCellsInAColumn(int column, int topRow); //合并一列中相同连续的单元格
int getUsedRowsCount(); //获取总行数
int getUsedColumnCount(); //获取总列数


private:
QAxObject * excel; //Excel指针
QAxObject * workBooks; //工作簿集合
QAxObject * workBook; //工作簿
QAxObject * sheets; //工作表集合
QAxObject * sheet; //工作表
};

#endif

源文件

#include "qexcel.h"

QExcel::QExcel(QObject *parent):QObject(parent)
{
excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;
}

QExcel::~QExcel()
{

}

/***************************************************************************/
/* 文件操作 */
/**************************************************************************/

void QExcel::open(QString FileName)
{
if(excel==nullptr)
{
excel = new QAxObject();
excel->setControl("Excel.Application"); //连接Excel控件
excel->setProperty("DisplayAlerts", false); //禁止显示警告
workBooks = excel->querySubObject("Workbooks"); //获取工作簿集合
QFile file(FileName);
if(file.exists())
{
workBooks->dynamicCall("Open(const QString&)", FileName); //打开指定文件
workBook = excel->querySubObject("ActiveWorkBook"); //获取活跃工作簿
sheets = workBook->querySubObject("WorkSheets"); //获取工作表集合
sheet = workBook->querySubObject("ActiveSheet"); //获取活跃工作表
}
}
else
{
workBooks = excel->querySubObject("Workbooks"); //获取工作簿集合
QFile file(FileName);
if(file.exists())
{
workBooks->dynamicCall("Open(const QString&)", FileName); //打开指定文件
workBook = excel->querySubObject("ActiveWorkBook"); //获取活跃工作簿
sheets = workBook->querySubObject("WorkSheets"); //获取工作表集合
sheet = workBook->querySubObject("ActiveSheet"); //获取活跃工作表
}
}
}

void QExcel::createFile(QString FileName)
{
if(excel==nullptr)
{
excel = new QAxObject();
excel->setControl("Excel.Application"); //连接Excel控件
excel->setProperty("DisplayAlerts", false); //禁止显示警告
workBooks = excel->querySubObject("Workbooks"); //获取工作簿集合
QFile file(FileName);
if(!file.exists())
{
workBooks->dynamicCall("Add"); //新建文件
workBook=excel->querySubObject("ActiveWorkBook"); //获取活跃工作簿
workBook->dynamicCall("SaveAs(const QString&)",FileName); //按指定文件名保存文件
sheets = workBook->querySubObject("WorkSheets"); //获取工作表集合
sheet = workBook->querySubObject("ActiveSheet"); //获取活跃工作表
}
}
else
{
workBooks = excel->querySubObject("Workbooks"); //获取工作簿集合
QFile file(FileName);
if(!file.exists())
{
workBooks->dynamicCall("Add"); //新建文件
workBook=excel->querySubObject("ActiveWorkBook"); //获取活跃工作簿
workBook->dynamicCall("SaveAs(const QString&)",FileName); //按指定文件名保存文件
sheets = workBook->querySubObject("WorkSheets"); //获取工作表集合
sheet = workBook->querySubObject("ActiveSheet"); //获取活跃工作表
}
}
}

void QExcel::save() //保存Excel文件
{
workBook->dynamicCall("Save()");
qDebug()<<"文件已保存";
}

void QExcel::quit() //退出Excel
{
excel->dynamicCall("Quit()");

delete sheet;
delete sheets;
delete workBook;
delete workBooks;
delete excel;

excel = nullptr;
workBooks = nullptr;
workBook = nullptr;
sheets = nullptr;
sheet = nullptr;

qDebug()<<"退出Excel";
}

/**************************************************************************/
/* 工作表操作 */
/*************************************************************************/

void QExcel::selectSheet(const QString& sheetName) //根据名字选择工作表
{
sheet = sheets->querySubObject("Item(const QString&)", sheetName);
}

void QExcel::selectSheet(int sheetIndex) //根据下标索引选择工作表,下标从1开始
{
sheet = sheets->querySubObject("Item(int)", sheetIndex);
}

void QExcel::deleteSheet(const QString& sheetName) //根据名字删除工作表
{
QAxObject * a = sheets->querySubObject("Item(const QString&)", sheetName);
a->dynamicCall("delete");
}

void QExcel::deleteSheet(int sheetIndex) //根据下标索引删除工作表,下标从1开始
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
a->dynamicCall("delete");
}

void QExcel::insertSheet(QString sheetName) //新建工作表
{
sheets->querySubObject("Add()");
QAxObject * a = sheets->querySubObject("Item(int)", 1);
a->setProperty("Name", sheetName);
}

int QExcel::getSheetsCount() //获取工作表数量
{
return sheets->property("Count").toInt();
}

QString QExcel::getSheetName() //获取当前活跃工作表的名字
{
return sheet->property("Name").toString();
}

QString QExcel::getSheetName(int sheetIndex) //根据下标索引获取工作表名字
{
QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex);
return a->property("Name").toString();
}

/***************************************************************************/
/* 单元格操作 */
/**************************************************************************/

void QExcel::mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn) //根据行列编号合并单元格
{
QString cell;
cell.append(QChar(topLeftColumn - 1 + 'A'));
cell.append(QString::number(topLeftRow));
cell.append(":");
cell.append(QChar(bottomRightColumn - 1 + 'A'));
cell.append(QString::number(bottomRightRow));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}

void QExcel::mergeCells(const QString& cell) //根据字母编号合并单元格
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("VerticalAlignment", -4108);//xlCenter
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
}

void QExcel::setCellString(int row, int column, const QString& value) //根据行列编号设置单元格数据
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
range->dynamicCall("SetValue(const QString&)", value);
}

void QExcel::setCellString(const QString& cell, const QString& value) //根据字母编号设置单元格数据
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("SetValue(const QString&)", value);
}

bool QExcel::setRowData(int row,int colum_start,int column_end,QVariant vData) //批量写入一行数据
{
bool op = false;
QString start,end;
start=getRange_fromColumn(colum_start);
end=getRange_fromColumn(column_end);
QVariant qstrRange = start+QString::number(row,10)+":"+end+QString::number(row,10);
QAxObject *range = sheet->querySubObject("Range(const QString&)", qstrRange);
if ( range )
{
range->dynamicCall("SetValue(const QVariant&)",QVariant(vData)); //修改单元格的数据
op = true;
}
else
{
op = false;
}

delete range;
return op;
}

QString QExcel::getRange_fromColumn(int column) //根据列值计算出字母值
{
if(column <= 0) //列值必须大于等于1
return "";

QString ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
QString result="";
QVector<int> pos;
if(column>=1 && column<=26)
{
result += ABC[column-1];
return result;
}
else
{
int high = column;
int low;
int last_high;
while(high>0)
{
last_high=high;
high = high / 26;
low = last_high % 26;
if(low==0 && high!=0)
{
low=26;
high=high-1;
}
pos.push_front(low);
}

for(int i=0; i<pos.size(); i++)
{
result += ABC[pos[i]-1];
}
}
return result;
}

QVariant QExcel::getCellValue(int row, int column) //根据行列编号获取单元格数值
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
return range->property("Value");
}

QVariant QExcel::getCellValue(const QString& cell) //根据字母编号获取单元格数值
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
return range->property("Value");
}

void QExcel::clearCell(int row, int column) //根据行列编号清空单元格
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}

void QExcel::clearCell(const QString& cell) //根据字母编号清空单元格
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->dynamicCall("ClearContents()");
}

void QExcel::setCellFontBold(int row, int column, bool isBold) //根据行列编号设置单元格字体是否加粗
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}

void QExcel::setCellFontBold(const QString &cell, bool isBold) //根据字母编号设置单元格字体是否加粗
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Bold", isBold);
}

void QExcel::setCellFontSize(int row, int column, int size) //根据行列编号设置单元格字体大小
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}

void QExcel::setCellFontSize(const QString &cell, int size) //根据字母编号设置单元格字体大小
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range = range->querySubObject("Font");
range->setProperty("Size", size);
}

void QExcel::setCellTextCenter(int row, int column) //根据行列编号设置单元格内容居中
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}

void QExcel::setCellTextCenter(const QString &cell) //根据字母编号设置单元格内容居中
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
}

void QExcel::setCellTextWrap(int row, int column, bool isWrap) //根据行列编号设置单元格内容是否换行
{
QString cell;
cell.append(QChar(column - 1 + 'A'));
cell.append(QString::number(row));

QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}

void QExcel::setCellTextWrap(const QString &cell, bool isWrap) //根据字母编号设置单元格内容是否换行
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
range->setProperty("WrapText", isWrap);
}

void QExcel::setCellBackground(int row, int column, QColor color) //根据行列编号设置单元格背景颜色
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
QAxObject *interior =range->querySubObject("Interior");
interior->setProperty("Color", color);
}

void QExcel::setCellBackground(const QString& cell, QColor color) //根据字母编号设置单元格背景颜色
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
QAxObject *interior =range->querySubObject("Interior");
interior->setProperty("Color", color);
}

void QExcel::setCellFontColor(int row, int column, QColor color) //根据行列编号设置单元格字体颜色
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
QAxObject *font =range->querySubObject("Font");
font->setProperty("Color", color);
}

void QExcel::setCellFontColor(const QString& cell, QColor color) //根据字母编号设置单元格字体颜色
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
QAxObject *font =range->querySubObject("Font");
font->setProperty("Color", color);
}

void QExcel::setCellBorderColor(int row, int column, QColor color) //根据行列编号设置单元格边框颜色
{
QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column);
QAxObject* border = range->querySubObject("Borders");
border->setProperty("Color", color);
}

void QExcel::setCellBorderColor(const QString& cell, QColor color) //根据字母编号设置单元格边框颜色
{
QAxObject *range = sheet->querySubObject("Range(const QString&)", cell);
QAxObject* border = range->querySubObject("Borders");
border->setProperty("Color", color);
}

void QExcel::getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn) //取得工作表已使用范围
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
*topLeftRow = usedRange->property("Row").toInt();
*topLeftColumn = usedRange->property("Column").toInt();

QAxObject *rows = usedRange->querySubObject("Rows");
*bottomRightRow = *topLeftRow + rows->property("Count").toInt() - 1;

QAxObject *columns = usedRange->querySubObject("Columns");
*bottomRightColumn = *topLeftColumn + columns->property("Count").toInt() - 1;
}

void QExcel::setColumnWidth(int column, int width) //设置列宽
{
QString columnName;
columnName.append(QChar(column - 1 + 'A'));
columnName.append(":");
columnName.append(QChar(column - 1 + 'A'));

QAxObject * col = sheet->querySubObject("Columns(const QString&)", columnName);
col->setProperty("ColumnWidth", width);
}

void QExcel::setRowHeight(int row, int height) //设置行高
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));

QAxObject * r = sheet->querySubObject("Rows(const QString &)", rowsName);
r->setProperty("RowHeight", height);
}

void QExcel::setAutoFitRow(int row) //设置自适应行高
{
QString rowsName;
rowsName.append(QString::number(row));
rowsName.append(":");
rowsName.append(QString::number(row));

QAxObject * rows = sheet->querySubObject("Rows(const QString &)", rowsName);
rows->dynamicCall("AutoFit()");
}

void QExcel::mergeSerialSameCellsInAColumn(int column, int topRow) //合并一列中相同连续的单元格
{
int a,b,c,rowsCount;
getUsedRange(&a, &b, &rowsCount, &c);

int aMergeStart = topRow, aMergeEnd = topRow + 1;

QString value;
while(aMergeEnd <= rowsCount)
{
value = getCellValue(aMergeStart, column).toString();
while(value == getCellValue(aMergeEnd, column).toString())
{
clearCell(aMergeEnd, column);
aMergeEnd++;
}
aMergeEnd--;
mergeCells(aMergeStart, column, aMergeEnd, column);

aMergeStart = aMergeEnd + 1;
aMergeEnd = aMergeStart + 1;
}
}

int QExcel::getUsedRowsCount() //获取总行数
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
int topRow = usedRange->property("Row").toInt();
QAxObject *rows = usedRange->querySubObject("Rows");
int bottomRow = topRow + rows->property("Count").toInt() - 1;
return bottomRow;
}

int QExcel::getUsedColumnCount() //获取总列数
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
int leftColumn = usedRange->property("Column").toInt();
QAxObject *columns = usedRange->querySubObject("Columns");
int rightColumn = leftColumn + columns->property("Count").toInt() - 1;
return rightColumn;
}

QAxObject *QExcel::getWorkBooks()
{
return workBooks;
}

QAxObject *QExcel::getWorkBook()
{
return workBook;
}

QAxObject *QExcel::getWorkSheets()
{
return sheets;
}

QAxObject *QExcel::getWorkSheet()
{
return sheet;
}