QT快速写Excel的问题之全是第一行数据

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());
ok
因为每一行数据要打包成一个QVariant,然后再写入多行,tdata << table[i].toList();只是写成了一行,所以超出的区域被抛掉,指定区域全是同一行。
最保险的做法是全文复制,小小的细节,让我百思不得其解。这个是为了提醒自己也为了提醒你!

猜你喜欢

转载自blog.csdn.net/myhappyandy/article/details/120232879