您的位置:首页 > 其它

excel之单元格格式/设置/

2013-03-23 11:40 901 查看
http://blog.csdn.net/shuilan0066/article/details/7925023

示例---将所有单元格设置为文本格式:

 

[cpp]
view plaincopyprint?

_Application app;       //Excel应用程序接口  
Workbooks books;        //工作薄集合  
_Workbook book;     //工作薄  
Worksheets sheets;      //工作表集合  
_Worksheet sheet;       //工作表  
Range range;            //Excel中针对单元格的操作都应先获取其对应的Range对象  
Font font;  
Range cols;  
/* 
COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用 
VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant 
类来转换了的。 
*/  
//covOptional 可选参数的VARIANT类型  
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
  
if( !app.CreateDispatch(L"Excel.Application") ){  
    this->MessageBox(L"无法创建Excel应用!");  
    return;  
}  
  
//获取工作薄集合  
books=app.GetWorkbooks();  
//添加一个工作薄  
book=books.Add(covOptional);  
//获取工作表集合  
sheets=book.GetSheets();  
//获取第一个工作表  
sheet=sheets.GetItem(COleVariant((short)1));  
  
  
range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格   
range.SetNumberFormat(COleVariant(L"@")); //将单元格设置为文本类型  
  
//合并单元格  
//加载要合并的单元格   
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))),TRUE);   
range.Merge(COleVariant((long)0));   
  
  
  
range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格   
range.SetItem(COleVariant((long)1),COleVariant((long)1),COleVariant(_T("数学系研究生课程统计")));  //A1  
range.SetItem(COleVariant((long)2),COleVariant((long)1),COleVariant(_T("课程名")));              //A2  
range.SetItem(COleVariant((long)2),COleVariant((long)2),COleVariant(_T("课时")));                //B2  

 

   函数 SetNumberFormat() 用于设置单元格的格式,但是首先我们必须知道所有格式的标记。

 

文本类:

1、@ 指定内容按文本显示,主要用于编码、手机号等用数字表示的文本。设定该格式后,可以保证导出excel时,此类文本不会被转成数字显示。
数值类:

1、 0.00 表示两位小数,例如3.10367显示为3.10

2、 0.## 表示两位小数,当小数末位为0时,0将不显示。例如3.10显示为3.1

3、 "#,##0.00 "表示两位小数,且显示千份位

4、 #,##0.00;[Red]#,##0.00
表示负数红字

5、0.00;[Red]0.00;" " 表示负数红字,且数据为0时不显示

6、0.00;[Red](0.00);" "表示正数时两位小数,负数时两位小数并显示红色,0时不显示。0.00;[Red](0.00)只是一个示例,可以为任意的数字格式串,后边再加上;"
"(空格)即表示数据为0时不显示。
日期类:

1、 yyyy-m-d

2、 yyyy-MM-dd

3、 yyyy-MM-dd hh:mm:ss

4、 yyyy年MM月dd日
百分比:

1、0%

2、0.00%
详细请打开Excel2003,单元格右键,设置单元格格式,选一种格式,点自定义即可看到该格式的格式串;有的Excel格式串后有带”_”,在使用时,必须去掉。
设置篇
1 设置单元格的值
 
1)
选中指定单元格,使用SetValue设置值
CellName.Format(_T("A%d"),i);//单元格的名称
range.AttachDispatch(sheet.GetRange(COleVariant(CellName),COleVariant(CellName)));//加载单元格range.SetValue(COleVariant(subFileName));
 
 
CellName.Format(_T("C%d"),i);//单元格的名称
range.AttachDispatch(sheet.GetRange(COleVariant(CellName),COleVariant(CellName)));//加载单元格
range.SetValue(COleVariant((long)i));
 
2)
选中所有的单元格, 使用SetItem 设置指定单元格的值
 
range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格
//设置第I行 第1、2、3列的值
range.SetItem(COleVariant((long)(i)),COleVariant((long)1),COleVariant(subFileName)); //第一列
range.SetItem(COleVariant((long)(i)),COleVariant((long)2),COleVariant(unicodeStr));  //第二列
range.SetItem(COleVariant((long)(i)),COleVariant((long)3),COleVariant((long)i));      //第三列
 
2 设置行高列宽
 
选中某列 设置列宽
//获得所有列
range.AttachDispatch(sheet.GetColumns(),true);
//设置第一列的列宽  Range cols
cols.AttachDispatch(range.GetItem(COleVariant((long)1),vtMissing).pdispVal,TRUE);
cols.SetColumnWidth(COleVariant((long)10)); //设置列宽
 
//设置第4列的列宽
cols.AttachDispatch(range.GetItem(COleVariant((long)4),vtMissing).pdispVal,TRUE);
cols.SetColumnWidth(COleVariant((long)10)); //设置列宽
 
 
 
//设置列宽为自动适应
cols.AutoFit();
 
设置行高
 
 
    Range rows;
 
       range.AttachDispatch(sheet.GetRows(),TRUE);
       //选择第一行
       rows.AttachDispatch(range.GetItem(COleVariant((long)1),vtMissing).pdispVal);
//设置行高
       rows.SetRowHeight(COleVariant((long)60));
 
注意: 行高列宽使用的单位不一样 
 
3 设置单元格类型
 
       range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格
       range.SetNumberFormat(COleVariant(L"@")); //将单元格设置为文本类型
 
4 设置单元格字体
 
       Font ft;
 
       //设置第一列的字体
       range.AttachDispatch(sheet.GetColumns(),true);
       range.AttachDispatch(range.GetItem(COleVariant((long)1),vtMissing).pdispVal,TRUE);
      
       //字体作用范围
       ft.AttachDispatch(range.GetFont());
       ft.SetName(COleVariant(_T("宋体")));
       ft.SetSize(COleVariant((long)48));
ft.SetBold(COleVariant((long)1));//粗体
ft.SetColorIndex(COleVariant((long)2));//设置字体颜色
 
 
5 设置单元格背景色
 
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))));
       //////////////设置底色/////////////////
       Interior it;
       it.AttachDispatch(range.GetInterior());
       it.SetColorIndex(COleVariant((long)11));//标题底色
 
       ////表格内容的底色////
       range.AttachDispatch(sheet.GetRange(COleVariant(_T("A2")),COleVariant(_T("D5"))));
       it.AttachDispatch(range.GetInterior());
       it.SetColorIndex(COleVariant((long)15));
 
6 设置表格边框
 
1)
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A2")),COleVariant(_T("D5"))));
//LineStyle=线型Weight=线宽ColorIndex=线的颜色(-4105为自动)
range.BorderAround(COleVariant((long)1),(long)2,((long)-4105),vtMissing);//设置边框
 
2)
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A2")),COleVariant(_T("D5"))));
                     _variant_t v1;  //线型
                     _variant_t v2;  //宽度
                     _variant_t v3;  //颜色
 
                     v1.vt=VT_I2;
                     v1.lVal=2; // 线的样式:- no line; 1-solid; 2-big dot;3-small dot;4-dash dot; 5-dash dot dot; 
 
                     v2.vt=v1.vt;
                     v2.lVal=3; // 线的粗细程度
 
                     v3.vt=v1.vt;
                     v3.lVal=1; // 1-black;2-white;3-red;4-green;5-blue; 6-yellow; 7-pink;8-dark blue; 
 
                     UnitRge.BorderAround(v1,v2,v3,vtMissing);//设置边框
7 合并单元格
 
1)
       //合并单元格
       //加载要合并的单元格
       range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))),TRUE);
       range.Merge(COleVariant((long)0));
 
2)
        //将第一个单元格合并成行,列
        range.AttachDispatch(sheet.GetCells());
        unionRange.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal ); //第一个单元格
        unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)3),COleVariant((long)2)));     //GetResize(3,2) 从第一个单元格开始合并行列的所有单元格
        unionRange.Merge(COleVariant((long)0));   //合并单元格
8 设置单元格文本为自动换行 及排列方式
 
       range.AttachDispatch(sheet.GetUsedRange());//加载已使用的单元格
       range.SetWrapText(COleVariant((long)1));//设置单元格内的文本为自动换行
 
       //设置齐方式为水平垂直居中
       //水平对齐:默认=1,居中=-4108,左=-4131,右=-4152
       //垂直对齐:默认=2,居中=-4108,左=-4160,右=-4107
       range.SetHorizontalAlignment(COleVariant((long)-4108));
       range.SetVerticalAlignment(COleVariant((long)-4108));
9 在单元格中插入公式
      
//选择A2单元格,插入一个公式"=RAND()*100000",并设置A2数字格式为货币形式
range=sheet.GetRange(COleVariant(L"A2"),COleVariant(L"A2"));
range.SetFormula(COleVariant(L"=RAND()*100000"));
range.SetNumberFormat(COleVariant(L"$0.00"));
 
10 在单元格中插入图片
 
       Shapes   shapes   =   sheet.GetShapes();// 从Sheet对象上获得一个Shapes   
       range.AttachDispatch(sheet.GetRange(COleVariant(L"E5"),COleVariant(L"E5"))); // 获得Range对象,用来插入图片
       shapes.AddPicture( L"d:\\pic.bmp "   ,   false   ,   true   ,   (float)range.GetLeft().dblVal
              ,(float)range.GetTop().dblVal,(float)range.GetWidth().dblVal,(float)range.GetHeight().dblVal);
   ShapeRange   sRange   =   shapes.GetRange(_variant_t(long(1)));
   sRange.SetHeight(float(30));  //在RANGE范围内 设置图片宽高

   sRange.SetWidth(float(30)); 
11 对选取的区域进行排序
 
       #define xlAscending (long) 1
       #define xlDescending (long) 2
       #define vOpt COleVariant((long) DISP_E_PARAMNOTFOUND, VT_ERROR)
       #define xlHeader (long) 1                            // 选取的区域有标题
       #define xlNoHeader (long) 2                          // 选取的区域无标题    一定要正确确定是否有标题,否则排序可能不成功
       #define xlMatchCase COleVariant((long) 1)
       #define xlIgnoreCase COleVariant((long) 0)
       #define xlTopToBottom (long) 1                       // 垂直方向进行排序
       #define xlLeftToRight (long) 2                       // 水平方向进行排序
       #define xlPinYin (long) 1 // this is the default     // 按字符的中文拼音进行排序
       #define xlStroke (long) 2                            // 按每个字符中的笔画数进行排序
 
       VARIANT key1; // these lines set up first arg (key1) to sort
       V_VT(&key1) = VT_DISPATCH;                           // 排序时,关键字的vt设置为VT_DISPATCH
       V_DISPATCH(&key1) = sheet.GetRange(COleVariant(L"A1"),COleVariant(L"A1"));   // 设置按哪个关键字进行排序 选择单元意为:按此列(或行)为主关键字进行排序
       range=sheet.GetRange(COleVariant(L"A1"),COleVariant(CellName));              // 选择对哪些区域内的单元格进行排序
       range.Sort(key1, xlAscending, vOpt, vOpt, xlAscending, vOpt,xlAscending,xlNoHeader,vOpt,xlIgnoreCase,xlTopToBottom,xlPinYin); //设置排序 无标题时一定要设置为xlNoHeader  否则不起作用
选择篇
1 选择单元格
 
//选择一个单元格
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("A1"))),TRUE);
 
//选择多个单元格
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))),TRUE);
 
//使用变量表示单元格
CString CellName;
Int i=1;j=1;
CellName.Format(_T(“%c%d”),j+64,i);   //A–Z  65-90
 
 
//加载单元格
rnge.AttachDispatch(range.GetRange(COleVariant(CellName),COleVariant(CellName)));
2 选择某行
 
1)
//选择第一行
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("IV1"))),TRUE);
 
//选择前5行
range.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("IV5"))),TRUE);
 
2)先选择某行中的某个单元格,然后再选择整行
       Range rows;
 
       rows.AttachDispatch(sheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("A1"))),TRUE);
       rows=rows.GetEntireRow();
 
3)获得所有的行,然后再选择指定行
    Range rows;
 
       range.AttachDispatch(sheet.GetRows(),TRUE);
       //选择第一行
       rows.AttachDispatch(range.GetItem(COleVariant((long)1),vtMissing).pdispVal);
       rows.SetRowHeight(COleVariant((long)60));
 
3 选择某一列
 
1)
range.AttachDispatch(sheet.GetRange(COleVariant(L"A1"),COleVariant(L"A65536")));  //第一列
 
2)先选择某列中的某个单元格,然后再选择整列
 
range.AttachDispatch(sheet.GetRange(COleVariant(L"A1"),COleVariant(L"A1")));  //第一列
range=range.GetEntireColumn();
 
3)先获得所有列,然后再选择某一列
//获得所有列
range.AttachDispatch(sheet.GetColumns(),true);
//选择第一列
range.AttachDispatch(range.GetItem(COleVariant((long)1),vtMissing).pdispVal,TRUE);
 
4 选择全部CELLS
 
range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格
 
5 选择已使用的单元格
range.AttachDispatch(sheet.GetUsedRange());//加载已使用的单元格
 
6 获取单元格的值
1)
range=sheet.GetRange(COleVariant("A1"),COleVariant("A1"));
COleVariant rValue;

rValue=COleVariant(range.GetValue());

rValue.ChangeType(VT_BSTR);

this->MessageBox(CString(rValue.bstrVal));
 
2)
 
//读取第一个单元格的值
 range.AttachDispatch(sheet.GetCells());
 range.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
 
 vResult =range.GetValue();
 
 CString str;
 if(vResult.vt == VT_BSTR)       //字符串
 {
        str=vResult.bstrVal;
 }
 else if (vResult.vt==VT_R8)     //8字节的数字
 {
        str.Format(L"%f",vResult.dblVal);
 }
 else if(vResult.vt==VT_DATE)    //时间格式
 {
        SYSTEMTIME st;
        VariantTimeToSystemTime((long)&vResult.date, &st);
 }
 else if(vResult.vt==VT_EMPTY)   //单元格空的
 {
        str="";
 } 
读取xls文件示例 :
 
       //变量定义
       _Application app;          //Excel应用程序接口
       Workbooks books;         //工作薄集合
       _Workbook book;          //工作薄
       Worksheets sheets;         //工作表集合
       _Worksheet sheet;          //工作表
       Range range;                 //Excel中针对单元格的操作都应先获取其对应的Range对象
       Font font;
       Range cols;
       Range iCell;
       LPDISPATCH lpDisp;   
       COleVariant vResult;
       COleVariant
              covTrue((short)TRUE),
              covFalse((short)FALSE),
              covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); 
 
 
    //初始化
       if( !app.CreateDispatch(L"Excel.Application") ){
              this->MessageBox(L"无法创建Excel应用!");
              return;
       }
       app.SetVisible(TRUE);     //可见
       app.SetUserControl(TRUE); //用户可控制
 
 
 
       //打开XLS文件
       books.AttachDispatch(app.GetWorkbooks());
       lpDisp = books.Open(L"d:\\3.xls",     
              covOptional, covOptional, covOptional, covOptional, covOptional,
              covOptional, covOptional, covOptional, covOptional, covOptional,
              covOptional, covOptional );  
 
 
       //得到Workbook
    book.AttachDispatch(lpDisp);
 
       //得到Worksheets
       sheets.AttachDispatch(book.GetWorksheets());
 
       //得到当前活跃sheet
       //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
       lpDisp=book.GetActiveSheet();
       sheet.AttachDispatch(lpDisp);
 
 
 //*****
 //读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列
 Range usedRange;
 usedRange.AttachDispatch(sheet.GetUsedRange());
 range.AttachDispatch(usedRange.GetRows());
 long iRowNum=range.GetCount();                   //已经使用的行数
 
 range.AttachDispatch(usedRange.GetColumns());
 long iColNum=range.GetCount();                   //已经使用的列数
 
 long iStartRow=usedRange.GetRow();               //已使用区域的起始行,从开始
 long iStartCol=usedRange.GetColumn();            //已使用区域的起始列,从开始
 
//读取第一个单元格的值
 range.AttachDispatch(sheet.GetCells());
 range.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
 
 vResult =range.GetValue();
 
 CString str;
 if(vResult.vt == VT_BSTR)       //字符串
 {
        str=vResult.bstrVal;
 }
 else if (vResult.vt==VT_R8)     //8字节的数字
 {
        str.Format(L"%f",vResult.dblVal);
 }
 else if(vResult.vt==VT_DATE)    //时间格式
 {
        SYSTEMTIME st;
        VariantTimeToSystemTime((long)&vResult.date, &st);
 }
 else if(vResult.vt==VT_EMPTY)   //单元格空的
 {
        str="";
 } 
 
 
 //读取第一个单元格的对齐方式,数据类型:VT_I4
 //读取水平对齐方式
 range.AttachDispatch(sheet.GetCells());
 iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 vResult.lVal=0;
 vResult=iCell.GetHorizontalAlignment();
 
if(vResult.lVal!=0)
 {
  switch (vResult.lVal)
  {
  case 1:      //默认
   break;
  case -4108:  //居中
   break;
  case -4131 : //*左
   break;
  case -4152 : //*右
   break;
  }
 
 }
 
 
 
 //垂直对齐方式
 iCell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 vResult.lVal=0;
 vResult=iCell.GetVerticalAlignment();
 if(vResult.lVal!=0)
 {
  switch (vResult.lVal)
  {
  case -4160 :  //*上
   break;
  case -4108 :  //居中
   break;
  case -4107 :  //*下
   break;
  }
 
 }
 
//设置第一个单元格字体颜色:红色
 
 range.AttachDispatch(sheet.GetCells());
 range.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
 
 font.AttachDispatch(range.GetFont());
 font.SetColor(COleVariant((long)0xFF0000)); 
 
 
//合并单元格的处理
 //包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并
 Range unionRange;
 range.AttachDispatch(sheet.GetCells());
 unionRange.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal );
 
 vResult=unionRange.GetMergeCells();   
 if(vResult.boolVal==-1)             //是合并的单元格  
 {
        //合并单元格的行数
        range.AttachDispatch (unionRange.GetRows ());
        long iUnionRowNum=range.GetCount ();
 
        //合并单元格的列数
        range.AttachDispatch (unionRange.GetColumns ());
        long iUnionColumnNum=range.GetCount ();  
 
        //合并区域的起始行,列
        long iUnionStartRow=unionRange.GetRow();       //起始行,从开始
        long iUnionStartCol=unionRange.GetColumn();    //起始列,从开始
 
 }
 else if(vResult.boolVal==0)  
 {
        
        //不是合并的单元格
 }
 
        //将第一个单元格合并成行,列
        range.AttachDispatch(sheet.GetCells());
        unionRange.AttachDispatch(range.GetItem (COleVariant((long)1),COleVariant((long)1)).pdispVal ); //第一个单元格
        unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)3),COleVariant((long)2)));     //GetResize(3,2) 从第一个单元格开始合并行列的所有单元格
        unionRange.Merge(COleVariant((long)0));   //合并单元格
 
 
//将文件保存为.xls
 book.SaveAs(COleVariant(L"C:\\2.xls"),covOptional,covOptional,
        covOptional,covOptional,covOptional,0,
        covOptional,covOptional,covOptional,covOptional); 
 
book.Close (covOptional,COleVariant(L"d:\\3.xls"),covOptional);
 books.Close();
       //释放对象(相当重要!)
       range.ReleaseDispatch();
       cols.ReleaseDispatch();
       sheet.ReleaseDispatch();
       sheets.ReleaseDispatch();
       book.ReleaseDispatch();
       books.ReleaseDispatch();
       //App一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
       app.ReleaseDispatch();
       app.Quit();
一、加载
1、 在VC6.0里创建一个MFC工程
2、打开MFCClassWizard窗口(查看—>建立类向导),选择Automation,单击AddClass按钮,选择Froma
type library...,弹出文件选择对话框,之后定位到C:\Program Files\MicrosoftOffice\OFFICE11\EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。



 
 
3、返回编辑器,查看工程文件,可发现多了EXCEL.9H及EXCEL9.CPP两个文件,拷贝出来,放在VS2005需要使用excel的工程文件中。
4. 打开stdafx.h头文件确保包含如下头文件:
#include <afxdisp.h>(这个一般有了)
#include "excel.h" (手动添加这个即可)
5. 打开TestExcel.cpp文件,修改CTestExcelApp::InitInstance(),加入如下代码:
if(!AfxOleInit() ){

AfxMessageBox("初始化Ole出错!");

return FALSE;

}

为保证编译时不产生重复定义错误(可以验证一下是否成功加载,没有也能正常执行),我编译时出现了很多“类重复定义”异常,打开excel.h文件,在文件开始位置加入如下代码:
#if !defined _HEAD_FILE_EXCEL9_
#define _HEAD_FILE_EXCEL9_
相应的,在文件末尾加入:
#endif
成功
Excel接口
导入类
头文件
说明
_Application
CApplicaton
Application.h
Excel应用程序。
Workbooks
CWorkbooks
Workbooks.h
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
_Workbook
CWorkbook
Workbook.h
单个工作簿。
Worksheets
CWorksheets
Worksheets.h
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
_Worksheet
CWorksheet
Worksheet.h
单个Sheet表格。
Range
CRange
Range.h
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
在MSDN中,很少有excel方面的资料,但是在http://msdn.microsoft.com/zh-cn/ms348103.aspx中可以找到C#控制EXCEL方面的说明
 
二、操作EXCEL文件
1. 新建一个excel表,并填充两个单元格的实例

[cpp]
view plaincopyprint?

void CTestExcelDlg::OnButton1()  
{  
//Workbooks—>Workbook —>Worksheets—>Worksheet —>Range  
_Application app;       //Excel应用程序接口  
Workbooks books;        //工作薄集合  
_Workbook book;     //工作薄  
Worksheets sheets;      //工作表集合  
_Worksheet sheet;       //工作表  
Range range;            //Excel中针对单元格的操作都应先获取其对应的Range对象  
Font font;  
Range cols;  
/* 
COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用 
VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant 
类来转换了的。 
*/  
//covOptional 可选参数的VARIANT类型  
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
if( !app.CreateDispatch("Excel.Application") ){  
this->MessageBox("无法创建Excel应用!");  
return;  
}  
//获取工作薄集合  
books=app.GetWorkbooks();  
//添加一个工作薄  
book=books.Add(covOptional);  
//获取工作表集合  
sheets=book.GetSheets();  
//获取第一个工作表  
sheet=sheets.GetItem(COleVariant((short)1));  
//选择工作表中A1:A1单元格区域  
range=sheet.GetRange(COleVariant("A1"),COleVariant("A1"));  
//设置A1=HELLO EXCEL!"  
range.SetValue(COleVariant("HELLO EXCEL!"));  
//调整格式,设置粗体  
font=range.GetFont();  
font.SetBold(COleVariant((short)TRUE));  
//选择A2单元格,插入一个公式"=RAND()*100000",并设置A2数字格式为货币形  
式  
range=sheet.GetRange(COleVariant("A2"),COleVariant("A2"));  
range.SetFormula(COleVariant("=RAND()*100000"));  
range.SetNumberFormat(COleVariant("$0.00"));  
//选择A:A列,设置宽度为自动适应  
cols=range.GetEntireColumn();  
cols.AutoFit();  
//显示Excel表格,并设置状态为用户可控制  
app.SetVisible(TRUE);  
app.SetUserControl(TRUE);  

2. 打开一个已有的excel表格实例

[cpp]
view plaincopyprint?

CString strPath;   
strPath += "C:\\template.xlt"; // 模板的路径   
CFileFind filefind;   
if( !filefind.FindFile( strPath ) )   
{   
AfxMessageBox( "没有找到模版文档,请其查找" );   
    return;  
}   
LPDISPATCH lpDisp;  //接口指针  
books=app.GetWorkbooks();  
lpDisp = books.Open(m_filepath,  
    covOptional, covOptional, covOptional, covOptional,  
    covOptional, covOptional, covOptional, covOptional,  
    covOptional, covOptional, covOptional, covOptional,  
    covOptional, covOptional  
    );                  //与的不同,是个参数的,直接在后面加了两个covOptional成功了  
book.AttachDispatch(lpDisp);  

3. 保存一个excel文件实例

[cpp]
view plaincopyprint?

book.SetSaved(TRUE);  

4. 另存一个excel文件实例

[cpp]
view plaincopyprint?

book.SaveAs(COleVariant(m_filename),covOptional,  
    covOptional,covOptional,  
    covOptional,covOptional,(long)0,  
covOptional,covOptional,covOptional,  
covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了  

5. 释放一个excel文件实例
经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)

[cpp]
view plaincopyprint?

//释放对象(相当重要!)   
Rang.ReleaseDispatch();   
sheet.ReleaseDispatch();   
sheets.ReleaseDispatch();   
book.ReleaseDispatch();   
books.ReleaseDispatch();   
//退出程序   
app.Quit();  
//m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错   
app.ReleaseDispatch();   

6. 修改一个excel单元格

[cpp]
view plaincopyprint?

range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
range.SetValue2(COleVariant(value));  

7. 取出一个excel单元格

实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。

[cpp]
view plaincopyprint?

range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
COleVariant rValue;  
rValue=COleVariant(range.GetValue2());  
rValue.ChangeType(VT_BSTR);  
return CString(rValue.bstrVal);  

8. 还有释放问题是最重要的问题:
   首先变量必须全释放,无论当初是否绑定过;
   其次,程序释放和程序关闭的顺序必须是

[cpp]
view plaincopyprint?

app.Quit();  
app.ReleaseDispatch();  
如果顺如颠倒如下:  
app.ReleaseDispatch();  
app.Quit();  
出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。  

附录(操作类源码):

[cpp]
view plaincopyprint?

#include "../Stdafx.h"  
#include "OptExcel.h"  
#include "excel.h"  
#include "comdef.h"  
         
  
_Application app;  
Workbooks books;  
_Workbook book;  
Worksheets sheets;  
_Worksheet sheet;  
Range range;  
Range cell;  
Font font;  
  
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
  
  
////////////////////////////////////////////////////////////////////////  
///Function:    COptExcel  
///Description: 初始化函数,初始化中附加excel应用程序  
///Call:        app.CreateDispatch(_T("Excel.Application")  
////////////////////////////////////////////////////////////////////////  
COptExcel::COptExcel(void)  
{  
    if (::CoInitialize( NULL ) == E_INVALIDARG)   
    {   
        AfxMessageBox(_T("初始化Com失败!"));   
        return;  
    }  
  
    //验证office文件是否可以正确运行  
  
    if( !app.CreateDispatch(_T("Excel.Application")) )  
    {  
        AfxMessageBox(_T("无法创建Excel应用!"));  
        return;  
    }  
    //在程序执行文件路径名中,剪掉执行文件名,得到程序路径,追加模板文件名,得到模板完整路径  
      
  
}  
  
  
////////////////////////////////////////////////////////////////////////  
///Function:    ~COptExcel  
///Description: 析构函数,释放对象,非常重要,不全部释放,占用内存,下  
///             一次使用此类时会中断  
///Call:        ReleaseDispatch()  
////////////////////////////////////////////////////////////////////////  
COptExcel::~COptExcel(void)  
{  
      
  
      
    books.ReleaseDispatch();  
    book.ReleaseDispatch();  
    sheets.ReleaseDispatch();  
    sheet.ReleaseDispatch();  
    range.ReleaseDispatch();  
    font.ReleaseDispatch();  
    cell.ReleaseDispatch();  
  
    app.Quit();  
  
    app.ReleaseDispatch();  
    ::CoUninitialize();  
}  
  
  
////////////////////////////////////////////////////////////////////////  
///Function:    OpenExcelBook  
///Description: 打开表名为filename的文件,注意,文件路径非自动生成,以后  
///             考虑从下处理方法  
///Call:        GetAppPath()  
///Input:       CString filename 文件名  
////////////////////////////////////////////////////////////////////////  
bool COptExcel::OpenExcelBook(CString filename)  
{  
    CFileFind filefind;   
    if( !filefind.FindFile(filename) )   
    {   
        AfxMessageBox(_T("文件不存在"));  
        return false;  
    }  
    LPDISPATCH lpDisp; //接口指针  
    books=app.GetWorkbooks();  
    lpDisp = books.Open(filename,  
        covOptional, covOptional, covOptional, covOptional,  
        covOptional, covOptional, covOptional, covOptional,  
        covOptional, covOptional, covOptional, covOptional,  
        covOptional, covOptional  
        );                                      //与office 2000的不同,是个参数的,直接在后面加了两个covOptional成功了  
    book.AttachDispatch(lpDisp);  
    sheets=book.GetSheets();  
    sheet=sheets.GetItem(COleVariant((short)1));        //与的不同,是个参数的,直接在后面加了两个covOptional成功了  
    return true;  
}  
void COptExcel::NewExcelBook()  
{  
    books=app.GetWorkbooks();  
    book=books.Add(covOptional);  
    sheets=book.GetSheets();  
    sheet=sheets.GetItem(COleVariant((short)1));        //与的不同,是个参数的,直接在后面加了两个covOptional成功了  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    OpenExcelApp  
///Description: 打开应用程序(要注意以后如何识别用户要打开的是哪个文件)  
////////////////////////////////////////////////////////////////////////  
void COptExcel::OpenExcelApp(void)  
{  
    app.SetVisible(TRUE);  
    app.SetUserControl(TRUE);  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    SaveExcel  
///Description: 用于打开数据文件,续存数据后直接保存  
////////////////////////////////////////////////////////////////////////  
void COptExcel::SaveExcel(void)  
{  
    book.SetSaved(TRUE);  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    SaveAsExcel  
///Description: 保存excel文件  
////////////////////////////////////////////////////////////////////////  
void COptExcel::SaveAsExcel(CString filename)  
{  
    book.SaveAs(COleVariant(filename),covOptional,  
    covOptional,covOptional,  
    covOptional,covOptional,(long)0,covOptional,covOptional,covOptional,  
    covOptional,covOptional);                     
}  
  
  
////////////////////////////////////////////////////////////////////////  
///Function:    SetCellValue  
///Description: 修改单元格内的值  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int row 单元格所在行  
///             int col 单元格所在列  
///             int Align       对齐方式默认为居中  
////////////////////////////////////////////////////////////////////////  
void COptExcel::SetCellValue(int row, int col,int Align)  
{  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    range.SetValue2(COleVariant(value));  
    cell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);  
    cell.SetHorizontalAlignment(COleVariant((short)Align));  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    GetCellValue  
///Description: 得到的单元格中的值  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int row 单元格所在行  
///             int col 单元格所在列  
///Return:      CString 单元格中的值  
////////////////////////////////////////////////////////////////////////  
CString COptExcel::GetCellValue(int row, int col)  
{  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    COleVariant rValue;  
    rValue=COleVariant(range.GetValue2());  
    rValue.ChangeType(VT_BSTR);  
    return CString(rValue.bstrVal);  
}  
////////////////////////////////////////////////////////////////////////  
///Function:    SetRowHeight  
///Description: 设置行高  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int row 单元格所在行  
////////////////////////////////////////////////////////////////////////  
void COptExcel::SetRowHeight(int row, CString height)  
{  
    int col = 1;  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    range.SetRowHeight(COleVariant(height));  
}  
////////////////////////////////////////////////////////////////////////  
///Function:    SetColumnWidth  
///Description: 设置列宽  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int col 要设置列宽的列  
///             CString 宽值  
////////////////////////////////////////////////////////////////////////  
void COptExcel::SetColumnWidth(int col,CString width)  
{  
    int row = 1;  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    range.SetColumnWidth(COleVariant(width));  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    SetRowHeight  
///Description: 设置行高  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int row 单元格所在行  
////////////////////////////////////////////////////////////////////////  
CString COptExcel::GetColumnWidth(int col)  
{  
    int row = 1;  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    VARIANT width = range.GetColumnWidth();  
    CString strwidth;  
    strwidth.Format(CString((LPCSTR)(_bstr_t)(_variant_t)width));  
    return strwidth;  
}  
  
////////////////////////////////////////////////////////////////////////  
///Function:    GetRowHeight  
///Description: 设置行高  
///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  
///Input:       int row 要设置行高的行  
///             CString 宽值  
////////////////////////////////////////////////////////////////////////  
CString COptExcel::GetRowHeight(int row)  
{  
    int col = 1;  
    range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
    VARIANT height = range.GetRowHeight();  
    CString strheight;  
    strheight.Format(CString((LPCSTR)(_bstr_t)(_variant_t)height));  
    return strheight;  
}  
  
  
////////////////////////////////////////////////////////////////////////  
///Function:    IndexToString  
///Description: 得到的单元格在EXCEL中的定位名称字符串  
///Input:       int row 单元格所在行  
///             int col 单元格所在列  
///Return:      CString 单元格在EXCEL中的定位名称字符串  
////////////////////////////////////////////////////////////////////////  
CString COptExcel::IndexToString( int row, int col )   
{   
    CString strResult;  
    if( col > 26 )   
    {   
        strResult.Format(_T("%c%c%d"),'A' + (col-1)/26-1,'A' + (col-1)%26,row);  
    }   
    else   
    {   
        strResult.Format(_T("%c%d"), 'A' + (col-1)%26,row);  
    }   
    return strResult;  
}   
  
////////////////////////////////////////////////////////////////////////  
///Function:    LastLineIndex  
///Description: 得到表格总第一个空行的索引  
///Return:      int 空行的索引号  
////////////////////////////////////////////////////////////////////////  
int COptExcel::LastLineIndex()   
{   
    int i,j,flag=0;  
    CString str;  
    for(i=1;;i++)  
    {  
        flag = 0;  
        //粗略统计,认为前列都没有数据即为空行  
        for(j=1;j<=5;j++)  
        {  
            str.Format(_T("%s"),this->GetCellValue(i,j).Trim());  
            if(str.Compare(_T(""))!=0)  
            {  
                flag = 1;  
                break;  
            }  
              
        }  
        if(flag==0)  
            return i;  
          
    }  


1.     VS2005添加COM

Project-> addclass -> MFC -> MFC CLASS FROM TypeLib

选择:_Application/_Workbook/_Worksheet/Workbooks/Worksheet/Range



点击finish 后生成
CApplication.h
CWorkbook.h
CWorkbooks.h
CWorksheet.h
CWorksheets.h
CRange.h
删掉这些文件,导入excel9.h,excel9.cpp

[cpp]
view plaincopyprint?

<strong>2.  在对应的程序文件中添加头文件#include "excel9.h"  
在程序中启用COM服务库</strong>  
  
 // 初始化 OLE 库  
    if (!AfxOleInit())  
    {  
        AfxMessageBox(L"Could not initialize COM dll");  
        return FALSE;  
    }  
   if (CoInitialize(NULL) != S_OK)          
return -1;  
  
  
<strong>下面是一个处理EXCEL的程序例子,可直接调用:</strong>  
void OnBnClickedButtonCaln()  
{  
    // TODO: 在此添加控件通知处理程序代码  
    // TODO: Add your control notification handler code here   
  
    Range m_ExlRge;  
    _Worksheet m_ExlSheet;  
    Worksheets m_ExlSheets;   
    _Workbook m_ExlBook;   
    Workbooks m_ExlBooks;   
    _Application m_ExlApp;   
  
  
    //用m_ExlApp对象创建Excel2003进程   
  
    if(!m_ExlApp.CreateDispatch(_T("Excel.Application"),NULL))   
    {   
        AfxMessageBox(_T("创建Excel服务失败!"));   
        return;   
    }   
  
    //设置为可见   
    m_ExlApp.SetVisible(TRUE);   
  
    ///////////////////下面得到应用程序所在的路径///////////////////   
    CString theAppPath,theAppName;   
//  char Path[MAX_PATH];   
  
//  GetModuleFileName(NULL,Path,MAX_PATH);//得到应用程序的全路径   
    GetModuleFileName(NULL,_T("D:\\1.xlt"),MAX_PATH);//得到应用程序的全路径   
    //theAppPath=(CString)Path;   
    theAppPath=_T("D:\\1.xlt");  
  
    theAppName=AfxGetApp()->m_pszAppName;   
    theAppName+=_T(".exe");   
  
    //把最后的文件名去掉   
    int length1,length2;   
  
    length1=theAppPath.GetLength();   
    length2=theAppName.GetLength();   
  
    theAppPath.Delete(length1-length2,length2);   
    ////////////////////////////////////////////////////////////////   
  
  
    CString TempPath=_T("");   
  
    //TempPath=theAppPath+_T("Template.xls");//EXCEL模板的路径   
    TempPath=theAppPath;  
  
    m_ExlBooks.AttachDispatch(m_ExlApp.GetWorkbooks(),TRUE);   
  
    m_ExlBook.AttachDispatch(m_ExlBooks.Add((COleVariant)TempPath),TRUE);//加载EXCEL模板   
  
    m_ExlSheets.AttachDispatch(m_ExlBook.GetSheets(),TRUE);//加载Sheet页面   
  
    //添加新的Sheet页面   
    m_ExlSheets.Add(vtMissing,vtMissing,COleVariant((long)1),vtMissing);   
  
    //删除第二个Sheet页面   
    m_ExlSheet.AttachDispatch(m_ExlSheets.GetItem(COleVariant((long)2)),TRUE);   
    m_ExlSheet.Delete();   
  
    //把第一个Sheet页面的名字改变为TestSheet   
    m_ExlSheet.AttachDispatch(m_ExlSheets.GetItem(COleVariant((long)1)),TRUE);   
    m_ExlSheet.SetName(_T("TestSheet"));   
  
  
    ///////合并第一行单元格A1至D1//////   
  
    //加载要合并的单元格   
    m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))),TRUE);   
  
    m_ExlRge.Merge(COleVariant((long)0));   
  
    ////////设置表格内容////////   
  
    m_ExlRge.AttachDispatch(m_ExlSheet.GetCells(),TRUE);//加载所有单元格   
  
    m_ExlRge.SetItem(COleVariant((long)1),COleVariant((long)1),COleVariant(_T("数学系研究生课程统计")));   
  
    m_ExlRge.SetItem(COleVariant((long)2),COleVariant((long)1),COleVariant(_T("课程名")));   
    m_ExlRge.SetItem(COleVariant((long)2),COleVariant((long)2),COleVariant(_T("课时")));   
    m_ExlRge.SetItem(COleVariant((long)2),COleVariant((long)3),COleVariant(_T("难度")));   
    m_ExlRge.SetItem(COleVariant((long)2),COleVariant((long)4),COleVariant(_T("教学方式")));   
  
    m_ExlRge.SetItem(COleVariant((long)3),COleVariant((long)1),COleVariant(_T("泛函分析")));   
    m_ExlRge.SetItem(COleVariant((long)3),COleVariant((long)2),COleVariant(_T("60")));   
    m_ExlRge.SetItem(COleVariant((long)3),COleVariant((long)3),COleVariant(_T("普通")));   
    m_ExlRge.SetItem(COleVariant((long)3),COleVariant((long)4),COleVariant(_T("老师讲课")));   
  
    m_ExlRge.SetItem(COleVariant((long)4),COleVariant((long)1),COleVariant(_T("微分流形")));   
    m_ExlRge.SetItem(COleVariant((long)4),COleVariant((long)2),COleVariant(_T("40")));   
    m_ExlRge.SetItem(COleVariant((long)4),COleVariant((long)3),COleVariant(_T("变态难")));   
    m_ExlRge.SetItem(COleVariant((long)4),COleVariant((long)4),COleVariant(_T("自学")));   
  
    m_ExlRge.SetItem(COleVariant((long)5),COleVariant((long)1),COleVariant(_T("二阶椭圆型方程与方程组")));   
    m_ExlRge.SetItem(COleVariant((long)5),COleVariant((long)2),COleVariant(_T("60")));   
    m_ExlRge.SetItem(COleVariant((long)5),COleVariant((long)3),COleVariant(_T("很难")));   
    m_ExlRge.SetItem(COleVariant((long)5),COleVariant((long)4),COleVariant(_T("讨论")));   
  
  
    m_ExlRge.AttachDispatch(m_ExlSheet.GetUsedRange());//加载已使用的单元格   
  
    m_ExlRge.SetWrapText(COleVariant((long)1));//设置单元格内的文本为自动换行   
  
    //设置齐方式为水平垂直居中   
    //水平对齐:默认=1,居中=-4108,左=-4131,右=-4152   
    //垂直对齐:默认=2,居中=-4108,左=-4160,右=-4107   
    m_ExlRge.SetHorizontalAlignment(COleVariant((long)-4108));   
    m_ExlRge.SetVerticalAlignment(COleVariant((long)-4108));   
  
    ///////设置整体的字体、字号及颜色//////   
  
    Font ft;   
  
    ft.AttachDispatch(m_ExlRge.GetFont());   
  
    ft.SetName(COleVariant(_T("宋体")));//字体   
    ft.SetColorIndex(COleVariant((long)11));//字的颜色   
    ft.SetSize(COleVariant((long)12));//字号   
  
    ///////////设置标题字体及颜色//////////   
  
    m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(COleVariant(_T("A1")),COleVariant(_T("D1"))));   
  
    ft.AttachDispatch(m_ExlRge.GetFont());   
  
    ft.SetBold(COleVariant((long)1));//粗体   
    ft.SetSize(COleVariant((long)13));   
    ft.SetColorIndex(COleVariant((long)2));   
  
//  CellFormat cf;   
//  cf.AttachDispatch(m_ExlRge.GetCells());   
  
    //////////////设置底色/////////////////   
  
    Interior it;   
  
    it.AttachDispatch(m_ExlRge.GetInterior());   
  
    it.SetColorIndex(COleVariant((long)11));//标题底色   
  
    ////表格内容的底色////   
  
    m_ExlRge.AttachDispatch(m_ExlSheet.GetRange(COleVariant(_T("A2")),COleVariant(_T("D5"))));   
  
    it.AttachDispatch(m_ExlRge.GetInterior());   
  
    it.SetColorIndex(COleVariant((long)15));   
  
  
    //////////////为表格设置边框/////////////   
  
    Range UnitRge;   
    CString CellName;   
  
    for(int i=1;i<=4;i++)   
    {   
        for(int j=1;j<=4;j++)   
        {       
            CellName.Format(_T("%c%d"),j+64,i);//单元格的名称   
  
            UnitRge.AttachDispatch(m_ExlRge.GetRange(COleVariant(CellName),COleVariant(CellName)));//加载单元格   
  
            //LineStyle=线型 Weight=线宽 ColorIndex=线的颜色(-4105为自动)   
            UnitRge.BorderAround(COleVariant((long)1),(long)2,((long)-4105),vtMissing);//设置边框   
        }   
    }   
  
  
  
    //释放对象(相当重要!)   
    m_ExlRge.ReleaseDispatch();   
    m_ExlSheet.ReleaseDispatch();   
    m_ExlSheets.ReleaseDispatch();   
    m_ExlBook.ReleaseDispatch();   
    m_ExlBooks.ReleaseDispatch();   
    //m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错   
    m_ExlApp.ReleaseDispatch();   
  
    //退出程序 m_ExlApp.Quit();   
  
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: