QT快速写Excel的问题之全是第一行数据
这里我不再多叙述关于QT快速读取Excel的方法,请自行baidu或者在CSDN搜索。
至于为什么要快速写Excel,其实对于数据量不大的Excel写入,cell(int,int)的方式,没有问题,对于大量数据,尤其是超过1w条后,时间长到无法接受!!
原因还是不能反复调用QAxObject的接口。
所以,我们应该将一张表的数据一次性准备好后,一次写入,这样就能飞快的写完。
废话少说,先上代码。
//1->A 26->Z 27->AA
void convertToColName(int data, QString& res)
{
Q_ASSERT(data > 0 && data < 65535);
int tempData = data / 26;
if (tempData > 0)
{
int mode = data % 26;
convertToColName(mode, res);
convertToColName(tempData, res);
}
else
{
res = (to26AlphabetString(data) + res);
}
}
QString to26AlphabetString(int data)
{
QChar ch = data + 0x40;//A对应0x41
return QString(ch);
}
bool WriteOneTable(const QString &filepath, QVector<QVector<QVariant>> & table)
{
if (!table.isEmpty() && !filepath.isEmpty())
{
//新建excel表
QAxObject excel("Excel.Application");
excel.dynamicCall("SetVisible (bool Visible)", "false");
excel.setProperty("DisplayAlerts", false);
QAxObject* workbooks = excel.querySubObject("WorkBooks");
workbooks->dynamicCall("Add");
QAxObject* workbook = excel.querySubObject("ActiveWorkBook");
QAxObject* sheet = workbook.querySubObject("WorkSheets(int)", 1);
//数据转换
QVariantList tdata;
QVariant var;
int row = table.count();
int col = table[0].count();
for (int i = 0; i < row; i++)
{
//tdata << table[i].toList(); //这个地方一定要注意!!!这种写法是错误的
tdata << QVariant(table[i].toList());//ok
}
var = tdata; //注意!
//写入单元格范围A1:L2243
QString crange;
convertToColName(col, crange);
crange = QString("A1:%1%2").arg(crange).arg(row);
//写入数据
QAxObject* range = sheet.querySubObject("Range(const QString &)", crange);
QVariant res = range->setProperty("Value", var);
delete range;
//退出
workbook->dynamicCall("SaveAs(const QString&)", filepath);
workbook->dynamicCall("Close(Boolean)", false);
excel.dynamicCall("Quit(void)");
}
}
上面需要注意的是,WriteOneTable()函数中的tdata << table[i].toList();这句话是错误的!!为什么错误,亲们可以自己试试,在指定Excel区域,全是同一行数据结果。
类似上图,结果每行重复。
仔细比对之后,我后来才明白,原来需要这样写tdata << QVariant(table[i].toList());
是因为每一行数据要打包成一个QVariant,然后再写入多行,tdata << table[i].toList();只是写成了一行,所以超出的区域被抛掉,指定区域全是同一行。
最保险的做法是全文复制,小小的细节,让我百思不得其解。这个是为了提醒自己也为了提醒你!