注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

从C开始

 
 
 

日志

 
 

C++ 创建excel  

2010-10-28 14:24:40|  分类: SDK编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
// excel.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <ole2.h>  // 这个头文件一定要包含,否则就不能自动化了

// 接着修改我们添加一个函数,这个函数是整个程序的基础
// 若以后写别的程序而想用纯 C++ 来实现自动化,这个函数是可以复用的
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...);

// 主函数
int main(int argc, char* argv[])
{
 // 初始化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);

 // 获取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;
 }
 
 // 创建一个15x15的数组,用于填充表格
 VARIANT arr;
 WCHAR szTmp[32];
 arr.vt = VT_ARRAY | VT_VARIANT;
 SAFEARRAYBOUND sab[2];
 sab[0].lLbound = 1; sab[0].cElements = 15;
 sab[1].lLbound = 1; sab[1].cElements = 15;
 arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);

 // 初始化数组内容
 for(int i=1; i<=15; i++) {
  for(int j=1; j<=15; j++) {
   VARIANT tmp;
   tmp.vt = VT_BSTR;
   wsprintfW(szTmp,L"%i,%i",i,j);
   tmp.bstrVal = SysAllocString(szTmp);
   // 添加数据到数组中
   long indices[] = {i,j};
   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;
 }

 // 选择一个15x15大小的Range
 IDispatch *pXlRange;
 {
 VARIANT parm;
 parm.vt = VT_BSTR;
 parm.bstrVal = ::SysAllocString(L"A1:O15");

 VARIANT result;
 VariantInit(&result);
 AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
 VariantClear(&parm);

 pXlRange = result.pdispVal;
 }

 ::MessageBox(NULL, "我要填充数据了哈!", "通知", 0x10000);

 // 用我们的数组填充这个Range
 AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);
 pXlRange->Release();

 // 另外再选择一个Range
 {
 VARIANT parm;
 parm.vt = VT_BSTR;
 parm.bstrVal = ::SysAllocString(L"A11:O25");
  
 VARIANT result;
 VariantInit(&result);
 AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, L"Range", 1, parm);
 VariantClear(&parm);
  
 pXlRange = result.pdispVal;
 }
 
 ::MessageBox(NULL, "我还要填充一次哈!", "通知", 0x10000);

 // 用我们的数组再次填充这个Range
 AutoWrap(DISPATCH_PROPERTYPUT, NULL, pXlRange, L"Value", 1, arr);

 ::MessageBox(NULL, "好了,我们该保存文件了!", "通知", 0x10000);

 // 接下来我们该保存文件了,利用Worksheet.SaveAs()方法(我这里忽略了其他所有参数,除了文件名)
 {
 VARIANT filename;
 filename.vt = VT_BSTR;
 filename.bstrVal = SysAllocString(L"d:\\test.xls");
 AutoWrap(DISPATCH_METHOD, NULL, pXlSheet, L"SaveAs", 1, filename);
 }

 ::MessageBox(NULL, "哈哈,收工了!", "通知", 0x10000);

 // 退出,调用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;
}

// AutoWrap 函数的正体(真身,哈哈)
// 先声明:这个函数不是偶写的哈(别问是谁写的,偶也不知道)
// AutoWrap() - Automation helper function...
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
    // Begin variable-argument list...
    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;
}
  评论这张
 
阅读(1630)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018