• VC2008操作Excel2007总结


    概要

    网上VCExcel的操作资料虽然很多,但是很乱,这里做下总结,以后要用了可以参考,免得放在硬盘里时间一长找不到了。本文最后列出了主要的参考源,进一步信息可以从这些网站中获得。

    代码段均在WinXP+SP3 Excel2007 VS2008+SP1环境下调试通过。

    这里对Excel OLE对象的调用方式采用了MFCtype Lib

    正文

    准备工作

    通过type Lib方式引入Excel OLE封装源码文件后,对要用到的头文件做修改。注释import语句,添加Excel对象引用代码(参考资源[2]),注释掉冲突的代码。

    要引用哪对象就添加哪些对象的头文件,一般下面这些头文件是会被用到的。

    #include "CApplication.h"

    #include "CWorkbooks.h"

    #include "CWorkbook.h"

    #include "CWorksheets.h"

    #include "CWorksheet.h"

    打开Excel App对象

    CApplicationapp;

    if( !app.CreateDispatch(_T("Excel.Application")))

    {

    return false;

    }

    新建Excel文件和Sheet

      CWorkbooks books;

    CWorkbook book;

    CWorksheets sheets;

    CWorksheet sheet;

    books=app.get_Workbooks();

    book=books.Add(covOptional);

    sheets=book.get_Sheets();

    sheet=sheets.get_Item(COleVariant((short)nSheetNumber));

    一般nSheetNumber取值为1,即下面的代码将对第一张Sheet进行操作。

    显示Excel报表(控件)

    app.put_Visible(TRUE);

    app.put_UserControl(TRUE);

    打开已存在的Excel文件和Sheet

    books= app.get_Workbooks();

    book = books.Open(filename.GetBuffer(MAX_PATH),covOptional,covOptional,

    covOptional,covOptional,covOptional,covOptional,

    covOptional,covOptional,covOptional,covOptional,

    covOptional,covOptional,covOptional,covOptional);

    sheets =book.get_Worksheets();

    sheet=sheets.get_Item(COleVariant((short)nSheetNumber));

    读取Excel文件中单元格的内容

    CRange range;

    range = sheet.get_Range(COleVariant(startRange.GetBuffer(MAX_PATH)),

    COleVariant(endRange.GetBuffer(MAX_PATH)));

    COleVariantcov = range.get_Value2();

    CString str = (LPCWSTR)cov.bstrVal;

    其中startRangeendRangeCString实例,是单元格的位置,例如“A1”、“A2”、“B1”等。

    Excel文件中单元格的内容

    CRange range;

    range=sheet.get_Range(COleVariant(startRange.GetBuffer(MAX_PATH)),COleVariant(endRange.GetBuffer(MAX_PATH)));

    range.put_Value2(COleVariant(strValue.GetBuffer(MAX_PATH)));

    //font=range.get_Font();

    //font.put_Bold(COleVariant((short)TRUE));

    //range.put_Formula(COleVariant(_T("=RAND()")));

    //range.put_NumberFormat(COleVariant(_T("$0.00")));

    //CRange cols;

    //cols=range.get_EntireColumn();

    //cols.AutoFit();

    这里设置了字符串类型,应该还能设置其它类型参数,比如说整型。解开上面代码中的注释,可以尝试下其它功能。参考资源[1]

    释放资源

    books.Close();

    app.Quit();

    books.ReleaseDispatch();

    app.ReleaseDispatch();

    上面这段代码建议有,因为读取Excel文件时,如果没有上面这段代码文件可能会被锁定。

    参考资源

    [1]VS80开启Excel问题》

    http://www.programmer-club.com.tw/ShowSameTitleN/vc/32776.html

    [2]vc 如何操作excel2003(注意一定是2003编程》

    http://zhidao.baidu.com/question/40379986.html?si=1

    [3]excel,合并了单元格后该如何定位?》

    http://zhidao.baidu.com/question/112923672.html?si=3

    -----------------------------------------------------------------------------附------------------

     
    Excel在公司用的很多,而这个东西我用的不是很好,就想用程序来处理,遇到很多错误。这几天研究了下OLE操作Excel。
    环境:VS2008
    SP1+Excel 2007

    加入OLE Type
    Library
    随便建立一个MFC程序,选添加类,Typelib中的MFC类,出来一个对话,可用类型库选“Microsoft Excel 12.0
    Object Library”
    一般来说,添加下边这些类就够了,当然也可以全部添加
    CApplication

    CWorkbook
    CWorkbooks
    CWorksheet
    CRange
    CWorksheets
    CPicture
    CPictures
    CBorder

    CBorders
    CFont0
    Cnterior

    包含头文件的时候,把CApplication.h放到最前面

    一个操作的例子

    #define VT(x)
    _variant_t(x)


    void
    CExcelTest2Dlg::OnBnClickedButton1()
    {
        CApplication m_appExcel;      
    // Excel应用程序
        CWorkbooks m_books;
        CWorkbook m_book;
        CWorksheets sheets;
        CWorksheet sheet;
        CRange range;         
    //选择范围
        Cnterior interior;
        CFont0 font;              
    // 字体
        CBorders borders;         // 边框
        CBorder border;
        CRange column;
        CRange row;
       
    // 初始化Com
        if (::CoInitialize( NULL ) == E_INVALIDARG)
       
    {
            MessageBox(
    "初始化Com失败!");
        }


       
    // 启动Excel
        if ( !m_appExcel.CreateDispatch(_T("Excel.Application"), NULL))
       
    {
            MessageBox(_T(
    "创建Excel失败!"));
            ::CoUninitialize();
        }

        COleVariant covOptional((
    long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        m_appExcel.put_Visible(TRUE);
        m_books.AttachDispatch(m_appExcel.get_Workbooks());
        m_book.AttachDispatch(m_books.Add(covOptional));
        sheets.AttachDispatch(m_book.get_Worksheets());
    //得到Worksheets
        sheet.AttachDispatch(sheets.get_Item(_variant_t("sheet1"))); //得到sheet1
        sheet.put_Name("1234"); //sheet1改名
       

       
    //所有单元格颜色设为白色
        range.AttachDispatch(sheet.get_Cells());
        interior.AttachDispatch(range.get_Interior());
        interior.put_Color(VT(RGB(
    255, 255, 255)));
        interior.ReleaseDispatch();

        range.ClearContents();
        range.ReleaseDispatch();

        range.AttachDispatch(sheet.get_Range(VT(
    "A1"), VT("C1001")));
        range.ClearFormats();
       
    //插入数据
        range.put_Item(VT(1), VT(1), VT("函数"));
        range.put_Item(VT(
    1), VT(2), VT("大项目"));
        range.put_Item(VT(
    1), VT(3), VT("小项目"));
       
    for (int i = 2; i < 1000; i++)
       
    {
            range.put_Item(VT(i), VT(
    2), VT(i - 1));
            range.put_Item(VT(i), VT(
    3), VT("37122368~37097735~"));
        }

       
       
    // 为四周和内部加上边框
        borders.AttachDispatch(range.get_Borders());
       
    for (long i = xlEdgeLeft; i <= xlInsideHorizontal; i++)
       
    {
            border
    = borders.get_Item(i);
            border.put_LineStyle(VT(xlContinuous));
            border.ReleaseDispatch();
        }

        borders.ReleaseDispatch();

       
    //调整列宽
        column = range.get_EntireColumn();
        column.put_ColumnWidth(VT(
    18.63));
        column.ReleaseDispatch();
        range.ReleaseDispatch();

        range.AttachDispatch(sheet.get_Range(VT(
    "A10"), VT("A20"))); //选中
        range.Merge(VT(0)); //合并单元格
        range.ReleaseDispatch();

        range.AttachDispatch(sheet.get_Range(VT(
    "A1"), VT("C1")));
        interior.AttachDispatch(range.get_Interior());
        interior.put_ColorIndex(VT(
    7));
        interior.put_Pattern(VT(xlPatternSolid));
        interior.ReleaseDispatch();

        font.AttachDispatch(range.get_Font());
        font.put_ColorIndex(VT(
    6));
        font.get_Bold();
        font.ReleaseDispatch();
        range.ReleaseDispatch();

        range.AttachDispatch(sheet.get_Range(VT(
    "A2"), VT("C1001")));  //设置range对象的范围
        interior.AttachDispatch(range.get_Interior());  //选择表格内部
        interior.put_ColorIndex(VT(13));   //颜色
        interior.put_Pattern(VT(xlPatternSolid));  //加粗
        interior.ReleaseDispatch();

        font.AttachDispatch(range.get_Font()); 
    //选择字
        font.put_ColorIndex(VT(3));  //设置字颜色
        font.ReleaseDispatch();
       
        row.AttachDispatch(range.get_EntireRow());
    //选择range里的全部行
        row.put_RowHeight(VT(24));  //行高
        row.ReleaseDispatch();
        range.ReleaseDispatch();

        sheet.ReleaseDispatch();
        sheets.ReleaseDispatch();
        m_book.ReleaseDispatch();
        m_books.ReleaseDispatch();
        m_appExcel.ReleaseDispatch();

       
    }

    接下来开始编译,哇,一大堆错误...

    e:\myprograms3\exceltest2\exceltest2\debug\excel.tlh(1461)
    : error C2371: “FontPtr”: 重定义;不同的基类型   等等
    把CApplication.h里的#import
    "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE"
    no_namespace
    改为#import "C:\Program Files\Microsoft Office\OFFICE12\excel.exe"
    exclude("IFont", "IPicture") rename("RGB", "ignorethis"), rename("DialogBox",
    "ignorethis"), rename("VBE", "GREATWSVBE")

    rebuild
    all
    e:\myprograms3\exceltest2\exceltest2\debug\excel.tlh(2036) : error C2504:
    “_IMsoDispObj”: 未定义基类
    应该是接口没定义,mso.dll这个接口,在CApplication.h最上面加入#import
    "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\mso.dll"

    rebuild
    all  错误少多了
    还有VBE之类的错误,改法:
    加入
    #import "C:\Program Files\Common
    Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
    raw_interfaces_only, rename("Reference", "ignorethis"), rename("VBE",
    "GREATWSVBE")

    注意自己机器的路径!
    剩下还有一些rename
    的警告,可以在相关import后面几上rename("XXX","XXXXX")

  • 相关阅读:
    [openshift]openshfit OKD的安装
    [Docker]记一次使用jenkins将镜像文件推送到Harbor遇到的问题
    [k8s]创建Kubernetes的ssl/tls用户
    [k8s]ubuntu18 + Heketi + Glsuterfs的独立部署
    [k8s]kubernetes dashboard的安装
    [K8S]kubeadm国内镜像安装方式
    [K8S]污点调度
    [GO]解决golang.org/x/ 下包下载不下来的问题
    [GO]删除切片的某个值
    layui静态初始化渲染表单样式
  • 原文地址:https://www.cnblogs.com/areliang/p/2261269.html
Copyright © 2020-2023  润新知