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。

实现CIP通讯批量写入数据,可以使用C++中的OpenOPC库和OPC UA库。这里以OpenOPC为例进行介绍。 首先,需要在计算机中安装相应的OPC Server,如KepServer等。然后,安装OpenOPC库。 下面是一个实现批量写入数据的示例代码: ```c++ #include <iostream> #include <vector> #include <string> #include <windows.h> #include <OpenOPC.h> int main() { std::string server_name = "KepServer"; std::string opc_item_path = "Channel1.Device1.Tag1"; //需要写入的OPC Item路径 std::vector<double> values{ 1.0, 2.0, 3.0 }; //需要写入的值 std::vector<std::string> item_paths(values.size(), opc_item_path); //将OPC Item路径扩展成与值相同的大小 std::vector<VARIANT> var_values(values.size()); for (size_t i = 0; i < values.size(); ++i) { var_values[i].vt = VT_R8; var_values[i].dblVal = values[i]; } HRESULT hr = CoInitialize(NULL); if (FAILED(hr)) { std::cerr << "CoInitialize failed!" << std::endl; return -1; } OPC::OpenOPC opc; try { opc.connect(server_name); opc.write(item_paths, var_values); std::cout << "Write data successfully!" << std::endl; } catch (const OPC::opc_exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } CoUninitialize(); return 0; } ``` 在该示例代码中,首先定义了OPC Server的名称和需要写入的OPC Item路径。然后,使用std::vector存储需要写入的值,并将OPC Item路径扩展成与值相同的大小。接着,使用VARIANT类型存储需要写入的值,并使用OpenOPC库中的write函数进行批量写入。最后,关闭连接并释放资源。 需要注意的是,需要在代码中进行错误处理,以确保程序的健壮性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值