目的:C++打开加密的Excel表格读\写数据
求问1:有加了密的Excel文档,如何在代码打开的时候直接打开(不会弹窗让人输入密码)
已经有打开的代码了,部分代码如下,但是不知道怎么在打开的时候设置打开的密码(问就是我看不懂这部分代码,代码也不是我写的)
{
CoInitialize(NULL);
// 获得EXCEL的CLSID
CLSID clsid;
hr = CLSIDFromProgID(L"Excel.Application", &clsid);
// 创建实例
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);//
if(!SUCCEEDED(hr))
{
return hr;
}
VARIANT x;
x.vt = VT_I4;
x.lVal = IsVi;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible", 1, x);
VARIANT k;
k.vt = VT_BOOL;
k.boolVal = false;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"DisplayAlerts", 1, k);
}
// 获取Workbooks集合
{
VARIANT result;
VariantInit(&result);
hr = AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
pXlBooks = result.pdispVal;
}
// 调用Workbooks.Add()方法,创建一个新的Workbook
{
VARIANT vFilename;
vFilename.vt = VT_BSTR;
vFilename.bstrVal = ::SysAllocString(fileName);
VARIANT result;
VariantInit(&result);
hr = AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Open",1, vFilename);
pXlBook = result.pdispVal;
}
// AutoWrap() - Automation helper function...
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
bool isNeed = NotDele;
try
{
// Begin variable-argument list...
va_list marker;
va_start(marker, cArgs);
HRESULT hr=S_FALSE;
if(!pDisp) {
return hr;
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1];
//VARIANT pArgs[10];
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
if(FAILED(hr))
{
return hr;
}
// End variable-argument section...
va_end(marker);
delete [] pArgs;
/*if(isNeed == false)
{
}*/
return hr;
}catch(_com_error e)
{
return S_FALSE;
}
}
更新时间2023.9.7 9:45
补充说明,希望答案打开的方式是按照上述,因为后续要进行一些读写操作,如果换一种方法我就还得找新的读写方法。已看完各位朋友的方法,但是暂时还未成功打开,我不确定是不是我AutoWrap写得有问题,所以如果有能打开的朋友麻烦提供一些更多的代码。以及我加密的方式如下图,用的WPS,采用左边或者右边任意一种都可以。