C++实现批量快速写入数据到Excel

网上有很多C++利用OLE读取Excel的例子,其中有提到利用COleSafeArray类来预加载数据来提升效率,但是没有实现快速的写入大量数据到Excel,今天专门写了一个方法,同样利用COleSafeArray类将大量数据一次性的写入Excel,提高了效率,参考代码如下:

void CExcelFile::SetString(long startRow, long startCol, long RowCount, long ColCount, vector< vector<CComBSTR> >& writeData)
{
    if (startRow < 1 || startCol < 1)
    {
        return;
    }

    VARTYPE vt = VT_BSTR; /*数组元素的类型,string*/
    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/
    sabWrite[0].cElements = RowCount;
    sabWrite[0].lLbound = 0;
    sabWrite[1].cElements = ColCount;
    sabWrite[1].lLbound = 0;

    COleSafeArray olesaWrite;
    olesaWrite.Create(vt, sizeof(sabWrite) / sizeof(SAFEARRAYBOUND), sabWrite);
    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
    long(*pArray)[2] = NULL;
    olesaWrite.AccessData((void **)&pArray);
    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
    /*释放指向数组的指针*/
    olesaWrite.UnaccessData();
    pArray = NULL;

    /*对二维数组的元素进行逐个赋值*/
    long index[2] = { 0, 0 };
    long lFirstLBound = 0;
    long lFirstUBound = 0;
    long lSecondLBound = 0;
    long lSecondUBound = 0;
    olesaWrite.GetLBound(1, &lFirstLBound);
    olesaWrite.GetUBound(1, &lFirstUBound);
    olesaWrite.GetLBound(2, &lSecondLBound);
    olesaWrite.GetUBound(2, &lSecondUBound);
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
    {
        index[0] = i;
        for (long j = lSecondLBound; j <= lSecondUBound; j++)
        {
            index[1] = j;
            
            //防止越界而且不写入空值
            if ((i < writeData.size()) && (j < writeData[i].size()) && (writeData[i][j].Length() != 0))
            {
                olesaWrite.PutElement(index, (void*)writeData[i][j]);
            }
        }
    }
    
    CString strStartRow;
    CString strStartCol;
    strStartRow.Format(_T("%d"), startRow);
    strStartCol = ConvertNumColtoStringCol(startCol);
    CString strRange1;
    strRange1 = strStartCol + strStartRow;
    
    CString strEndRow;
    CString strEndCol;
    strEndRow.Format(_T("%d"), startRow + RowCount - 1);
    strEndCol = ConvertNumColtoStringCol(startCol + ColCount - 1);
    CString strRange2;
    strRange2 = strEndCol + strEndRow;
    ///
    CRange start_range = excel_work_sheet_.get_Range(COleVariant(strRange1), COleVariant(strRange2));
    start_range.put_Value2((VARIANT)olesaWrite);
    start_range.ReleaseDispatch();
}

//将Excel数字列转为字符串列,1--A
CString CExcelFile::ConvertNumColtoStringCol(long Col)
{
    CString strBack;
    do {
        Col--;
        int n = Col % 26;
        CString strTemp;
        strTemp.Format(_T("%c"), n + (int) 'A');
        strBack += strTemp;
        Col = (int)((Col - n) / 26);
    } while (Col > 0);
    return strBack;
}

需要注意的地方是,字符串必须要要BSTR类型,不然会提示内存不足,我这里用的是CComBSTR。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值