C++可以使用COM对象来操作Excel应用程序,以下是一个示例代码,展示如何在Excel中同时插入多行,其中假设新插入的行数据存储在二维数组data
中,行数为rowCount
,列数为columnCount
:
c++
#include <Windows.h>
#include <iostream>
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
int main()
{
// 初始化COM库
CoInitialize(nullptr);
// 创建Excel应用程序对象
IDispatch* pExcel = nullptr;
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
CoCreateInstance(clsid, nullptr, CLSCTX_LOCAL_SERVER, IID_IDispatch, (LPVOID*)&pExcel);
// 创建新工作簿
VARIANT result;
VARIANT vtName;
VariantInit(&vtName);
vtName.vt = VT_BSTR;
vtName.bstrVal = SysAllocString(L"NewWorkbook");
pExcel->Invoke(
DISPID_WORKBOOKS_ADD,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&result,
nullptr,
1,
new VARIANT{ vtName }
);
IDispatch* pWorkbook = result.pdispVal;
// 获取第一个工作表
IDispatch* pWorksheet = nullptr;
{
VARIANT index;
VariantInit(&index);
index.vt = VT_I4;
index.lVal = 1;
VARIANT result;
VariantInit(&result);
pWorkbook->Invoke(
DISPID_WORKBOOK_SHEETS,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&result,
nullptr,
1,
&index
);
IDispatch* pSheets = result.pdispVal;
pSheets->Invoke(
DISPID_SHEETS_ITEM,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&result,
nullptr,
1,
&index
);
pWorksheet = result.pdispVal;
pSheets->Release();
}
// 在指定位置插入多行
int rowCount = 3;
int columnCount = 4;
VARIANT vtStartRow;
VARIANT vtEndRow;
VARIANT vtCount;
vtStartRow.vt = VT_I4;
vtEndRow.vt = VT_I4;
vtCount.vt = VT_I4;
vtStartRow.lVal = 2; // 起始行为第2行
vtEndRow.lVal = vtStartRow.lVal + rowCount - 1; // 结束行为要插入的最后一行
vtCount.lVal = rowCount;
SAFEARRAY* saData = nullptr;
{
SAFEARRAYBOUND bounds[2];
bounds[0].lLbound = 0;
bounds[0].cElements = rowCount;
bounds[1].lLbound = 0;
bounds[1].cElements = columnCount;
saData = SafeArrayCreate(VT_VARIANT, 2, bounds);
VARIANT* pData = nullptr;
SafeArrayAccessData(saData, (LPVOID*)&pData);
for (int i = 0; i < rowCount; ++i)
{
for (int j = 0; j < columnCount; ++j)
{
VariantInit(&pData[i * columnCount + j]);
pData[i * columnCount + j].vt = VT_BSTR;
std::wstring s = L"Data_" + std::to_wstring(i) + L"_" + std::to_wstring(j);
pData[i * columnCount + j].bstrVal = SysAllocString(s.c_str());
}
}
SafeArrayUnaccessData(saData);
}
pWorksheet->Invoke(
DISPID_WORKSHEET_RANGE,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYGET,
&result,
nullptr,
1,
new VARIANT{ bstr_t(L"A") + std::to_bstr(vtStartRow.lVal).c_str() + ":" + bstr_t(L"Z") + std::to_bstr(vtEndRow.lVal).c_str() }
);
IDispatch* pRange = result.pdispVal;
pRange->Invoke(
DISPID_RANGE_INSERT,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
nullptr,
new VARIANT{ vtCount },
0,
nullptr
);
pRange->Invoke(
DISPID_RANGE_VALUE,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYPUT,
nullptr,
new VARIANT{ vtMissing },
1,
new DISPPARAMS{ nullptr, nullptr, columnCount, 0 }
);
pRange->Invoke(
DISPID_RANGE_VALUE,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_PROPERTYPUTREF,
nullptr,
new VARIANT{ saData },
1,
new DISPPARAMS{ nullptr, nullptr, columnCount, 0 }
);
pRange->Release();
SafeArrayDestroy(saData);
// 关闭工作簿
pWorkbook->Invoke(
DISPID_WORKBOOK_CLOSE,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
nullptr,
new VARIANT{ false }, // 不保存修改
0,
nullptr
);
// 退出Excel应用程序
pExcel->Invoke(
DISPID_APPLICATION_QUIT,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
nullptr,
0,
nullptr
);
// 释放COM资源
pWorksheet->Release();
pWorkbook->Release();
pExcel->Release();
CoUninitialize();
return 0;
}
该示例代码插入了3行4列的数据,可根据实际需求修改。