此方法需电脑安装office 或者wps ,原理为调用office软件的接口。若想更快的提升速度,可以只打开一次QAxObject* excel = new QAxObject(),然后进行其他操作。
- 函数参数为QVector 数据和要保存文件的文件名(全路径文件名),Qvector 数据写入一列,第一行为整列数据的表头,其余行依次对数据进行排列写入。
bool exportToExcel(const QVector<float> ch1,const QString fileName)
{
QString filepath = QString(fileName);
if (!filepath.isEmpty())
{
QAxObject* excel = new QAxObject();
if (excel->setControl("Excel.Application")) { // 使用office
qDebug() << "使用Office";
} else if (excel->setControl("ket.Application")) { // 使用wps
qDebug() << "使用WPS";
} else {
qDebug() << "未安装Office或WPS";
// QMessageBox::warning(this, tr("错误"), tr("未安装Office或WPS"));
return false;
}
//连接Excel控件
//excel->dynamicCall("SetVisible (bool Visible)", "true");
//不显示窗体
excel->dynamicCall("SetVisible (bool Visible)", "false");
//不显示窗体
excel->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
QAxObject* workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
//workbooks->dynamicCall("Add");//新建一个工作簿
workbooks->dynamicCall("Add");//新建一个工作簿
//4) 打开已存在的工作簿:
//workbooks->dynamicCall("Open(const QString&)", QString("c:/test.xls"));
workbooks->dynamicCall("Open(const QString&)", filepath);
QAxObject* workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
QAxObject* worksheets = workbook->querySubObject("Sheets");//获取工作表集合
QAxObject* worksheet = worksheets->querySubObject("Item(int)", 1);//获取工作表集合的工作表1,即sheet1
QAxObject* used_range = worksheet->querySubObject("UsedRange"); //获得利用的范围
QAxObject* rows_1 = used_range->querySubObject("Rows");
QAxObject* columns = used_range->querySubObject("Columns");
int row_start = used_range->property("Row").toInt(); //获得开始行
int row_end = rows_1->property("Count").toInt();
int column_start = used_range->property("Column").toInt(); //获得开始列
int column_end = columns->property("Count").toInt();
int columnCount = 0;
columnCount = column_start + column_end;
if (1 == row_start&& row_end ==1)
{
columnCount = 1;
}
qDebug()<<QString().sprintf("********row_start = %d, row_end = %d, column_start = %d, column_end = %d********",row_start,row_end, column_start, column_end);
QAxObject* cellA, * cellB, * cellC, * cellD;
//设置标题
int cellrow = 1;
cellB = worksheet->querySubObject("Cells(int,int)", 1, columnCount /*column_end+2*/);
if(columnCount ==1)
{
cellB->dynamicCall("SetValue(const QVariant&)", QVariant("Fibre Length (m THF)"));
}
else {
QString time_t = QDateTime::currentDateTime().toString("yyyy/M/d hh:mm:ss");
cellB->dynamicCall("SetValue(const QVariant&)", QVariant(time_t));
}
cellrow++;
qint64 start_time =QDateTime::currentMSecsSinceEpoch();
// int rows = ch1.size();
// for (int i = 0; i < rows; i++) {
// //获取单元格
// cellB = worksheet->querySubObject("Cells(int, int", i+2, columnCount /*column_end+2*/);
// //储存一个字符串数据至表格
// cellB->dynamicCall("setValue(const QVariant&", QVariant(ch1[i]));
// cellrow++;
// if(i %100 == 0)
// {
// qDebug()<<QString("write row = %1\n").arg(cellrow);
// }
// }
QString ColName="";
convertToColName2(columnCount,ColName);
QString str =QString("%1%2:%1%3").arg(ColName).arg(2).arg(ch1.size()+1);
qDebug()<<str;
QVariantList vars;//行数据
const int m_rows = ch1.size();//行数
for(int i=0;i< m_rows;++i)
{
QList<QVariant> m_column_num;//每列数据
m_column_num.append(QString::number(ch1[i],'f',4));
vars.append(QVariant(m_column_num));
}
QAxObject *rangeAx = worksheet->querySubObject("Range(const QString&)", str);
rangeAx->dynamicCall("Value", QVariant(vars));
qDebug()<<QDateTime::currentMSecsSinceEpoch()-start_time;
workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(filepath));//保存至filepath,注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
workbook->dynamicCall("Close()");//关闭工作簿
excel->dynamicCall("Quit()");//关闭excel
delete excel;
excel = NULL;
}
return true;
}
- 内部使用函数,用来计算excel列数跟字母的对应关系。
void convertToColName2(int data, QString &res)
{
int a = data;
do {
a--;
res = char(a % 26 + 'A') + res;
a /= 26;
} while (a > 0);
}
- 导出的数据如图所示。
默认的第一行标题为如下图所示,可进行更改为任意想要的标题。