c++操作excel文件
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...)
{
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010);
_exit(0);
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
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)) {
sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err 0x%08lx", szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1];
// 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)) {
sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// End variable-argument section...
va_end(marker);
delete [] pArgs;
return hr;
}
//=====================
int DoExcleFile(RETURNSET * pReturn,PROVALUE * pFldNames)
{
// 初始化COM库
CoInitialize(NULL);
// 获得EXCEL的CLSID
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
if(FAILED(hr)) {
::MessageBox(NULL, "CLSIDFromProgID() 函数调用失败!", "错误", 0x10010);
return -1;
}
// 创建实例
IDispatch *pXlApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pXlApp);
if(FAILED(hr)) {
::MessageBox(NULL, "请检查是否已经安装EXCEL!", "错误", 0x10010);
return -2;
}
/*-------------------------------------
// 显示,将Application.Visible属性置1
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible",1, x);
-------------------------------------*/
//不显示打开?
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlApp, L"Visible",1,0);
// 获取Workbooks集合
IDispatch *pXlBooks;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"Workbooks", 0);
pXlBooks = result.pdispVal;
}
// 调用Workbooks.Add()方法,创建一个新的Workbook
IDispatch *pXlBook;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, L"Add", 0);
pXlBook = result.pdispVal;
}
//创建数据数组
VARIANT arr;
WCHAR szTmp[256];
arr.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[2];
int columnNum = pFldNames->size();
int lineNum = pReturn->size();
sab[0].lLbound = 1; sab[0].cElements = lineNum+1;
sab[1].lLbound = 1; sab[1].cElements = columnNum;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
for (int i=0;i<lineNum+1;i++)
{
RECORDSET *pRecord = NULL;
if (i != 0)
pRecord = pReturn->at(i-1);
for (int j=0;j<columnNum;j++)
{
string strtemp;
if (i == 0)
strtemp = _com_util::ConvertBSTRToString(_bstr_t(pFldNames->at(j)));
else if (pReturn != NULL)
{
_variant_t var = pRecord->at(j);
if (var.vt == VT_NULL)
strtemp = "";
else
strtemp = (LPCTSTR)(_bstr_t)var;
}
VARIANT tmp;
tmp.vt = VT_BSTR;
int nLen = strlen(strtemp.c_str())+1;
MultiByteToWideChar(CP_ACP,0,strtemp.c_str(),nLen,szTmp,256);
tmp.bstrVal = SysAllocString(szTmp);
// 添加数据到数组中
long indices[] = {i+1,j+1};
SafeArrayPutElement(arr.parray, indices, (void *)&tmp);
}
}
// 从Application.ActiveSheet属性获得Worksheet对象
IDispatch *pXlSheet;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, L"ActiveSheet", 0);
pXlSheet = result.pdispVal;
}
// 选择一个columnNum*(lineNum+1)大小的Range
IDispatch *pXlRange;
{
VARIANT parm;
parm.vt = VT_BSTR;
CString strset;
if(columnNum>=26) // 因为前26列用A~Z表示,大于26列都是用两个字母表示的,如从27列开始是AA、AB...
strset.Format(_T("A1:%c%c%d"), columnNum/26+64, columnNum%26+64, lineNum+1);
else
strset.Format(_T("A1:%c%d"), columnNum+64, lineNum+1);
WCHAR wBuf[100];
::MultiByteToWideChar(CP_ACP,0,strset.GetBuffer(),strset.GetLength()+1,wBuf,100);
parm.bstrVal = ::SysAllocString(wBuf);
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
VariantClear(&parm);
pXlRange = result.pdispVal;
}
// 用我们的数组填充这个Range
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);
// 接下来我们该保存文件了,利用Worksheet.SaveAs()方法(我这里忽略了其他所有参数,除了文件名)
{
VARIANT filename;
filename.vt = VT_BSTR;
int index = GetFileIndex();
if (index == 0)
return -1;
char pathBuf[MAX_PATH];
DWORD dw = GetCurrentDirectory(MAX_PATH,pathBuf);
if (dw == 0)return -1;
strcat(pathBuf,"http://www.cnblogs.com/justinpanrobot/admin/file://temp/");
char fileBuf[30]="";
sprintf_s(fileBuf,"http://www.cnblogs.com/justinpanrobot/admin/file://dtmp%25d.xls%22,index/);
strcat(pathBuf,fileBuf);
WCHAR szTmp[256];
int nlen = strlen(pathBuf)+1;
MultiByteToWideChar(CP_ACP,0,pathBuf,nlen,szTmp,256);
filename.bstrVal = SysAllocString(szTmp);
AutoWrap(DISPATCH_METHOD, NULL, pXlSheet, L"SaveAs", 1, filename);
}
// 退出,调用Application.Quit()方法
AutoWrap(DISPATCH_METHOD, NULL, pXlApp, L"Quit", 0);
// 释放所有的接口以及变量
pXlRange->Release();
pXlSheet->Release();
pXlBook->Release();
pXlBooks->Release();
pXlApp->Release();
VariantClear(&arr);
// 注销COM库
CoUninitialize();
return 0;
}