转自:http://blog.chinaunix.net/uid-23089249-id-3605764.html
参考文章:
1、VC操作Excel文件编程相关内容总结
2、VC++导出数据到Excel
3、VSTO学习笔记(二)Excel对象模型
利用VC操作Excel的方法至少有两种:
1、利用ODBC把Excel文件当成数据库文件,来进行读、写、修改等操作。网上有人编写了CSpreadSheet类,提供支持。
2、利用OLE Automation方法,将Excel当成组件服务器,利用VBA。
本文选择了第2中方式。要利用OLE Automation实现对Excel进行操作,必须与Excel对象模型提供的对象进行交互。Excel提供了数百个可能需要与之交互的对象,下面先了解一下编程中常用到的几个对象。
1) Application 对象:代表整个 Microsoft Excel 应用程序。
2) Workbook 对象:代表一个 Microsoft Excel 工作簿,即Excel文件。
3) Workbooks 对象:包含 Microsoft Excel 中当前打开的所有 Workbook 对象。
4) Worksheet 对象:代表一个工作表。一个工作簿中可以包括多个工作表。
5) Worksheets 对象:代表指定或活动工作簿中所有 Worksheet 对象的集合。
6) Range 对象:代表某一单元格、某一行、某一列、某一选定区域(该区域可包含一个或若干连续单元格区域)。Range对象是Excel操作的重点,对于数据插入、修改、删除都要通过它来实现,Range所表示等同于我们在实际编辑Excel文件时,用鼠标在表单中选择中的区域,选中之后再对其进行单元格修改、删除、合并、设置宽、高、颜色等操作。
7) Chart对象:代表工作簿中的图表。此图表既可以是嵌入的图表(包含在ChartObject对象中),也可以是单独的图表工作表。
8) Charts对象:代表指定或活动工作簿中所有图表工作表的集合。
9) Sheets 对象:代表指定或活动工作簿中所有工作表(可以是Chart对象或者WorkSheet对象)的集合。
10) Font对象:用于设置Range选中的单元格字体格式和颜色。
11) Interior对象:用于设置Range选中的单元格背景格式和颜色。
12) Borders对象:用于设置Range选中的单元格的边框。
其他对象可到msdn去了解:http://msdn.microsoft.com/zh-cn/library/office/ff194068.aspx
调用excel对象方法时,常常会用到一些枚举变量,可以到msdn中查找相关值:http://msdn.microsoft.com/zh-cn/library/office/ff838815.aspx
在操作Excel之前,必须向工程中添加Excel对象,其步骤是: 选择Menu --> View --> ClassWizard,打开ClassWizard 窗口, 选择Add Class -->From a type library,若系统中安装的是Office2000,则在Office 安装目录选择Excel.OLB,如果安装的是Office2003或2007,则选择Excel.exe;然后根据需要选择添加的类(如果要使用下面的CExcelServer封装类,必须加入_Application,Workbooks,_Workbook ,Worksheets,_Work2sheet,Range,Font,Interior,Borders等),向导会在工程中自动生成加入了这些类的Excel.h和Excel.cpp两个文件。在要使用这些导入的类时加入#include "Excel.h"即可。
CExcelServer类头文件
#if !defined(AFX_EXCELSERVER_H__7495C273_745B_4F87_A729_D057CAA8D2A9__INCLUDED_)
#define AFX_EXCELSERVER_H__7495C273_745B_4F87_A729_D057CAA8D2A9__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ExcelServer.h : header file
//
#include <afxcoll.h>
#include "excel.h"
#define InfoMessageBox(strMsg) \
AfxMessageBox(strMsg, MB_OK | MB_ICONINFORMATION)
#define DebugMessageBox(strMsg) \
AfxMessageBox(strMsg, MB_OK | MB_ICONINFORMATION)
#define WarningMessageBox(strMsg) \
AfxMessageBox(strMsg, MB_OK | MB_ICONWARNING)
#define ErrorMessageBox(strMsg) \
AfxMessageBox(strMsg, MB_OK | MB_ICONERROR)
//Excel文件格式
//http://msdn.microsoft.com/zh-cn/library/office/ff198017.aspx
typedef enum
{
xlCSV = 6, //csv
xlTextWindows = 20, //Windows 文本
xlTextMSDOS = 21, //MSDOS 文本
xlUnicodeText = 42, //Unicode 文本
xlExcel9795 = 43, //Excel9795
xlWorkbookNormal = -4143, //常规工作簿
xlExcel12 = 50, //Excel 12
xlWorkbookDefault = 51, //默认工作簿
} XlFileFormat;
//水平对齐方式
//http://msdn.microsoft.com/zh-cn/library/office/ff840772.aspx
typedef enum
{
xlHAlignCenter = -4108, //居中对齐
xlHAlignCenterAcrossSelection = 7, //跨列居中
xlHAlignDistributed = -4117, //分散对齐
xlHAlignFill = 5, //填充
xlHAlignGeneral = 1, //按数据类型对齐
xlHAlignJustify = -4130, //两端对齐
xlHAlignLeft = -4131, //左对齐
xlHAlignRight = -4152, //右对齐
} XlHAlign;
//垂直对齐方式
//http://msdn.microsoft.com/zh-cn/library/office/ff835305.aspx
typedef enum
{
xlVAlignBottom = -4107, //靠下
xlVAlignCenter = -4108, //居中对齐
xlVAlignDistributed = -4117, //分散对齐
xlVAlignJustify = -4130, //两端对齐
xlVAlignTop = -4160, //靠上
} XlVAlign;
//插入时单元格的移动方向
//http://msdn.microsoft.com/zh-cn/library/office/ff837618.aspx
typedef enum
{
xlShiftDown = -4121, //向下移动单元格
xlShiftToRight = -4161, //向右移动单元格
} XlInsertShiftDirection;
//边框的线条样式
//http://msdn.microsoft.com/zh-cn/library/office/ff821622.aspx
typedef enum
{
xlContinuous = 1, //实线
xlDash = -4115, //虚线
xlDashDot = 4, //点划相间线
xlDashDotDot = 5, //划线后跟两个点
xlDot = -4118, //点式线
xlDouble = -4119, //双线
xlLineStyleNone = -4142, //无线条
xlSlantDashDot = 13, //倾斜的划线
} XlLineStyle;
//边框的粗细
//http://msdn.microsoft.com/zh-cn/library/office/ff197515.aspx
typedef enum
{
xlHairline = 1, //细线(最细的边框)
xlMedium = -4138, //中等
xlThick = 4, //粗(最宽的边框)
xlThin = 2, //细
} XlBorderWeight;
/
// CExcelServer window create by lingdxuyan
class CExcelServer : public CWnd
{
// Construction
public:
CExcelServer();
// Attributes
private:
CString m_strExcelFile;
CString m_strWorkSheet;
_Application m_oExcelApp; // Excel程序
_Worksheet m_oWorkSheet; // 工作表
_Workbook m_oWorkBook; // 工作簿
Workbooks m_oWorkBooks; // 工作簿集合
Worksheets m_oWorkSheets; // 工作表集合
Range m_oCurrRange; // 使用区域
// Operations
private:
//创建Excel服务
BOOL CreateExcelServer();
//销毁Excel服务
void DestroyExcelServer();
public:
//打开指定工作薄
BOOL OpenWorkBook(CString strExcelFile);
//在已打开的工作薄中,打开指定工作薄
BOOL OpenWorkSheet(CString strWorkSheet);
//打开指定工作薄和工作表
BOOL OpenWorkSheet(CString strExcelFile, CString strWorkSheet);
//关闭当前打开的工作薄
void CloseWorkBook();
//关闭工作表
void CloseWorkSheet();
//保存工作薄
void WorkBookSave();
//将工作薄另存为指定格式
BOOL WorkBookSaveAs(CString strSaveAsFile, XlFileFormat fileFormat);
//将工作表另存为指定格式
void WorkSheetSaveAs(CString strSaveAsFile, XlFileFormat fileFormat);
//获取当前工作表已使用的行数
long GetUsedRowsCount();
//获取当前工作表已使用的列数
long GetUsedColumnsCount();
//获取当前工作表中一行数据
BOOL GetRowString(UINT nRow, CStringArray &array);
//在指定行插入数据
void InsertRow(UINT nRow, CStringArray &array);
//设置指定单元格颜色
void SetRangeBackgroundColor(CString strStart, CString strEnd, long nColorIndex);
//设置单元格边框
void SetRangeBorders(CString strStart, CString strEnd, XlLineStyle lineStyle,
XlBorderWeight borderWeight);
//设置单元格外边框
void SetRangeBorderAround(CString strStart, CString strEnd, XlLineStyle lineStyle,
XlBorderWeight borderWeight);
//设置所有单元格的水平对齐和垂直对齐
void SetAlignment(CString strStart, CString strEnd, XlHAlign hAlign, XlVAlign vAlign);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CExcelServer)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CExcelServer();
// Generated message map functions
protected:
//{{AFX_MSG(CExcelServer)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EXCELSERVER_H__7495C273_745B_4F87_A729_D057CAA8D2A9__INCLUDED_)
CExcelServer类cpp文件
// ExcelServer.cpp : implementation file
//
#include "stdafx.h"
#include "ExcelServer.h"
#include <afxtempl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CExcelServer
CExcelServer::CExcelServer()
{
m_strExcelFile = _T("");
m_strWorkSheet = _T("");
CreateExcelServer();
}
CExcelServer::~CExcelServer()
{
CloseWorkBook();
DestroyExcelServer();
}
BEGIN_MESSAGE_MAP(CExcelServer, CWnd)
//{{AFX_MSG_MAP(CExcelServer)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CExcelServer message handlers
BOOL CExcelServer::CreateExcelServer()
{
if (0 != CoInitialize(NULL))
{
ErrorMessageBox(_T("初始化COM支持库失败!"));
exit(1);
}
//创建Excel服务
if (!m_oExcelApp.CreateDispatch(_T("Excel.Application"), NULL))
{
ErrorMessageBox(_T("创建Excel服务失败!"));
return FALSE;
}
//设置为显示
m_oExcelApp.SetVisible(FALSE);
return TRUE;
}
void CExcelServer::DestroyExcelServer()
{
m_oExcelApp.ReleaseDispatch();
m_oExcelApp.Quit(); // 这条语句是推出Excel程序,任务管理器中的EXCEL进程会自动结束。
}
BOOL CExcelServer::OpenWorkBook(CString strExcelFile)
{
LPDISPATCH lpDisp = NULL;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CloseWorkBook();
m_oWorkBooks.AttachDispatch(m_oExcelApp.GetWorkbooks(), TRUE); //没有这条语句,下面打开文件返回失败。
// 打开文件
lpDisp = m_oWorkBooks.Open(strExcelFile,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional,
covOptional );
// 获得活动的WorkBook( 工作簿 )
m_oWorkBook.AttachDispatch(lpDisp, TRUE);
// 获得活动的WorkSheet( 工作表 )
// m_oWorkSheet.AttachDispatch(m_oWorkBook.GetActiveSheet(), TRUE);
m_strExcelFile = strExcelFile;
return TRUE;
}
void CExcelServer::CloseWorkBook()
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
if (!m_strExcelFile.IsEmpty())
{
// 关闭
m_oWorkBook.SetSaved(TRUE); // 将Workbook的保存状态设置为已保存,即不让系统提示是否人工保存
m_oWorkBook.Close(covOptional, COleVariant(m_strExcelFile), covOptional);
m_oWorkBooks.Close();
// 释放
m_oWorkBook.ReleaseDispatch();
m_oWorkBooks.ReleaseDispatch();
}
m_strExcelFile = _T("");
CloseWorkSheet();
}
BOOL CExcelServer::OpenWorkSheet(CString strWorkSheet)
{
CString strMsg;
long i;
CloseWorkSheet();
// 打开工作表集,查找工作表strSheet
m_oWorkSheets.AttachDispatch( m_oWorkBook.GetWorksheets(), TRUE );
long lSheetNUM = m_oWorkSheets.GetCount();
for (i=1; i<=lSheetNUM; i++)
{
m_oWorkSheet.AttachDispatch( m_oWorkSheets.GetItem(COleVariant((short)i)), TRUE );
if (strWorkSheet == m_oWorkSheet.GetName())
break;
}
if (i > lSheetNUM)
{
strMsg.Format(_T("在%s中找不到名为%s的表"), m_strExcelFile, strWorkSheet);
WarningMessageBox(strMsg);
return FALSE;
}
#ifdef _DEBUG
else
{
strMsg.Format(_T("%s是%s第%d个表"), strWorkSheet, m_strExcelFile, i);
DebugMessageBox(strMsg);
}
#endif
m_strWorkSheet = strWorkSheet;
return TRUE;
}
BOOL CExcelServer::OpenWorkSheet(CString strExcelFile, CString strWorkSheet)
{
if (!OpenWorkBook(strExcelFile))
return FALSE;
return OpenWorkSheet(strWorkSheet);
}
void CExcelServer::CloseWorkSheet()
{
if (!m_strWorkSheet.IsEmpty())
{
m_oCurrRange.ReleaseDispatch();
m_oWorkSheet.ReleaseDispatch();
m_oWorkSheets.ReleaseDispatch();
}
m_strWorkSheet = _T("");
}
long CExcelServer::GetUsedRowsCount()
{
// 获得使用的区域Range( 区域 )
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetUsedRange(), TRUE);
// 获得使用的行数
m_oCurrRange.AttachDispatch(m_oCurrRange.GetRows(), TRUE);
return m_oCurrRange.GetCount();
}
BOOL CExcelServer::GetRowString(UINT nRow, CStringArray &array)
{
Range oCurCell;
CString strMsg;
// 获得使用的列数
long lUsedColumnNum = GetUsedColumnsCount();
COleVariant covRow((long)nRow);
CString strHeader;
// 遍历列头
#ifdef _DEBUG
strMsg.Format(_T("row %d:"), nRow);
#endif
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetUsedRange(), TRUE);
for (long i=1; i<=lUsedColumnNum; i++)
{
if (0 != nRow)
{
//获取单元格数据
oCurCell.AttachDispatch(m_oCurrRange.GetItem(covRow, COleVariant(i)).pdispVal, TRUE);
strHeader = (oCurCell.GetText()).bstrVal;
}
//保存单元格数据
array.Add(strHeader);
#ifdef _DEBUG
strMsg += _T(" ") + strHeader;
#endif
}
#ifdef _DEBUG
strHeader.Format(_T("size%d"), array.GetSize());
strMsg += _T(" ") + strHeader;
DebugMessageBox(strMsg);
#endif
return TRUE;
}
long CExcelServer::GetUsedColumnsCount()
{
// 获得使用的区域Range( 区域 )
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetUsedRange(), TRUE);
// 获得使用的列数
m_oCurrRange.AttachDispatch( m_oCurrRange.GetColumns(), TRUE );
return m_oCurrRange.GetCount();
}
void CExcelServer::InsertRow(UINT nRow, CStringArray &array)
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
long size = array.GetSize();
CString strCell, strData;
char cColumn = 'A';
Font oFont;
if (nRow < 1)
{
WarningMessageBox(_T("%s: 行号必须大于0"));
return;
}
#ifdef _DEBUG
CString strMsg;
strMsg.Format(_T("row %d:"), nRow);
#endif
for (long i=1; i<=size; i++)
{
//获取每1列第1个单元格
strCell.Format("%c%d", cColumn++, nRow);
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strCell),
covOptional), TRUE);
//当前位置插入单元格
m_oCurrRange.Insert(COleVariant((short)xlShiftDown), covOptional);
//设置单元格内容
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strCell),
covOptional), TRUE);
strData = array.GetAt(i - 1);
m_oCurrRange.SetValue2(COleVariant(strData));
#ifdef _DEBUG
strMsg += _T(" ") + strData;
#endif
//设置单元格字体加粗
oFont.AttachDispatch(m_oCurrRange.GetFont(), TRUE);
oFont.SetBold(COleVariant((short)TRUE));
//自动列宽
m_oCurrRange.AttachDispatch(m_oCurrRange.GetEntireColumn(), TRUE);
m_oCurrRange.AutoFit();
}
#ifdef _DEBUG
DebugMessageBox(strMsg);
#endif
oFont.ReleaseDispatch();
}
void CExcelServer::SetRangeBackgroundColor(CString strStart, CString strEnd, long nColorIndex)
{
Interior oInterior;
//获取单元格区域
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strStart),
COleVariant(strEnd)), TRUE);
//设置单元格背景色
oInterior.AttachDispatch(m_oCurrRange.GetInterior(), TRUE);
oInterior.SetColorIndex(COleVariant(nColorIndex));
oInterior.ReleaseDispatch();
}
void CExcelServer::SetRangeBorders(CString strStart, CString strEnd,
XlLineStyle lineStyle, XlBorderWeight borderWeight)
{
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strStart),
COleVariant(strEnd)), TRUE);
// 设置区域内所有单元格的边框
Borders oBorders;
oBorders.AttachDispatch(m_oCurrRange.GetBorders(), TRUE);
oBorders.SetColorIndex(COleVariant((long)1)); // 线的颜色(-4105为自动, 1为黑色)
oBorders.SetLineStyle(COleVariant((long)lineStyle));
oBorders.SetWeight(COleVariant((long)borderWeight));
oBorders.ReleaseDispatch();
}
void CExcelServer::SetRangeBorderAround(CString strStart, CString strEnd,
XlLineStyle lineStyle, XlBorderWeight borderWeight)
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strStart),
COleVariant(strEnd)), TRUE);
//设置外边框
//线的颜色(-4105为自动, 1为黑色)
m_oCurrRange.BorderAround(COleVariant((long)lineStyle), borderWeight, 1, covOptional);
}
void CExcelServer::SetAlignment(CString strStart, CString strEnd, XlHAlign hAlign, XlVAlign vAlign)
{
// 获得使用的区域Range( 区域 )
m_oCurrRange.AttachDispatch(m_oWorkSheet.GetRange(COleVariant(strStart),
COleVariant(strEnd)), TRUE);
// 设置水平对齐
m_oCurrRange.SetHorizontalAlignment(COleVariant((short)hAlign));
// 设置垂直对齐
m_oCurrRange.SetVerticalAlignment(COleVariant((short)vAlign));
}
BOOL CExcelServer::WorkBookSaveAs(CString strSaveAsFile, XlFileFormat fileFormat)
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CString strMsg;
#ifdef _DEBUG
strMsg.Format(_T("excel %s save as %s"),
m_strExcelFile, strSaveAsFile);
DebugMessageBox(strMsg);
#endif
// 删除strSaveAsFile文件,以免excel另存为strSaveAsFile,磁盘中已存在同名文件
::DeleteFile(strSaveAsFile);
// excel另存为strSaveAsFile
m_oWorkBook.SaveAs(COleVariant(strSaveAsFile),COleVariant((short)fileFormat),covOptional,
covOptional,covOptional,covOptional,0,
covOptional,covOptional,covOptional,covOptional,covOptional);
return TRUE;
}
void CExcelServer::WorkSheetSaveAs(CString strSaveAsFile, XlFileFormat fileFormat)
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CString strMsg;
#ifdef _DEBUG
strMsg.Format(_T("excel %s sheet %s save as %s"),
m_strExcelFile, m_oWorkSheet.GetName(), strSaveAsFile);
DebugMessageBox(strMsg);
#endif
// 删除strSaveAsFile文件,以免excel另存为strSaveAsFile文件,磁盘中已存在同名文件
::DeleteFile(strSaveAsFile);
// excel另存为strSaveAsFile
m_oWorkSheet.SaveAs(strSaveAsFile,COleVariant((short)fileFormat),covOptional,
covOptional,covOptional,covOptional,
covOptional,covOptional,covOptional,covOptional);
}
void CExcelServer::WorkBookSave()
{
m_oWorkBook.Save();
m_oWorkBook.SetSaved(TRUE); // 将Workbook的保存状态设置为已保存
}
一个例子
先定义一个CExcelServer对象
2.CExcelServer m_oExcelServer; // Excel服务
//打开xls文件
m_oExcelServer.OpenWorkSheet(strExcelFile, m_strWorkSheet);
//插入列头
m_oExcelServer.InsertRow(1, m_arrayHeaders);
//设置单元格边框和背景颜色
CString strStartCell, strEndCell;
long lUsedRowsNum = m_oExcelServer.GetUsedRowsCount();
long lUsedColumnsNum = m_oExcelServer.GetUsedColumnsCount();
strStartCell = "A1";
strEndCell.Format("%c%d", 'A' + lUsedColumnsNum - 1, lUsedRowsNum);
m_oExcelServer.SetRangeBorders(strStartCell, strEndCell, xlContinuous, xlThin);
m_oExcelServer.SetRangeBorderAround(strStartCell, strEndCell, xlDouble, xlThin);
m_oExcelServer.SetRangeBackgroundColor(strStartCell, strEndCell, 34);
//设置单元格均为水平居中,垂直居中
strStartCell.Format("A1");
strEndCell.Format("%c%d", 'A' + lUsedColumnsNum - 1, lUsedRowsNum);
m_oExcelServer.SetAlignment(strStartCell, strEndCell, xlHAlignCenter, xlVAlignCenter);
//保存并关闭Excel文件
m_oExcelServer.WorkBookSave();
m_oExcelServer.CloseWorkBook();
CExcelServer类,只在VC++6.0、excel2007测试过!
原文地址:VC++6.0操作excel2007文件封装类CExcelServer 出自http://blog.chinaunix.net/uid/23089249.html