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、 在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
成功
在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();
}
示例---将所有单元格设置为文本格式:
[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,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。
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 | 一定数量的单元格,可对单元格进行单个或多个单元格进行操作。 |
二、操作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();
}
相关文章推荐
- POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写
- POI 设置Excel单元格为文本格式
- POI中设置Excel单元格格式
- POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写
- C#中设置Excel单元格格式
- POI导出EXCEL带水印,以及单元格格式设置
- 用代码设置Excel单元格的格式
- 使用C#和Excel进行报表开发(七)-设置单元格的显示格式
- 支持将数据导出到Excel文档的时候设置单元格格式的.NET控件Spire.DataExport
- POI中设置Excel单元格格式样式(居中,字体,边框等)
- Excel单元格格式设置
- 使用C#和Excel进行报表开发(七)-设置单元格的显示格式 【转】
- 在vc++中调用Excel,怎样设置单元格的格式可以得到科学计数法显示,且保留两位小数
- C# 操作 Excel 单元格格式设置
- C# 操作 Excel 单元格格式设置
- 使用C#和Excel进行报表开发(七)-设置单元格的显示格式
- Java 中使用POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写、单元格边框等
- 使用C#和Excel进行报表开发(七)-设置单元格的显示格式
- 导出excel时设置单元格格式(避免类似0100的数字丢失前面的0)
- POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写