先决条件
- 本机安装office2003、2007、2010、2016及以后版本,总之必须安装office
- 导入Excel库文件,导入方式可参考:
- 如何在vs2017及以前版本(vs2010、vs2015)上添加 添加类型库中的MFC类
- 如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控件中的MFC类
- 如何使用vs2022通过excel.exe生成VC、C++能够使用的头文件
一、导入头文件
#include "CApplication.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CRange.h"
#include "CFont0.h"
二、使用示例1
1、打开excel驱动及操作excel (读、写、新建sheet,选择rang,行、列等)
//默认使用第一个sheet
int nSheetNumber=1;
//创建对象
CApplication app;
if( !app.CreateDispatch(_T("Excel.Application")))
{
AfxMessageBox("没有安装office2007以上版本,无法操作excel文件");
return ;
}
//定义其他内部对象
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CFont0 font;
CRange range;
CString FieldName,FieldValue;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
books=app.get_Workbooks();
//需要在c盘建立一个excel文件,也可以改成系统自带的excel文件
// book=books.Add(COleVariant("c:\\aa.xlsx"));
book = books.Add(covOptional);
book.put_Title("Mybooks");
sheets=book.get_Sheets();
sheet=sheets.get_Item(COleVariant((short)nSheetNumber));
sheet.put_Name("wxpSheet");
//---------------------
app.put_Visible(TRUE);//可见性
app.put_UserControl(TRUE);//只读
//设置标题
FieldName="a1";
FieldValue="数据A";
range=sheet.get_Range(COleVariant(FieldName),COleVariant(FieldName));
range.put_Value2(COleVariant(FieldValue));
FieldName="B1";
FieldValue="数据B";
range=sheet.get_Range(COleVariant(FieldName),COleVariant(FieldName));
range.put_Value2(COleVariant(FieldValue));
//填充数据-------------------------------------------------------
for(int row=1;row<10;++row)
{
//每一行的数据
for(int col=0;col<10;++col)
{
//放置自己的指定数据------------------------------
FieldName.Format("%c%d",'a'+col,(row+1));
FieldValue.Format("(%d,%d)",row+1,col+1);
range=sheet.get_Range(COleVariant(FieldName),COleVariant(FieldName));
// range.put_Value2(COleVariant(FieldValue));
range.put_Formula(_variant_t("=RAND()*100"));
range.put_NumberFormat(_variant_t("00.00"));
//设置隔行颜色
if(row %2==0)
{
font=range.get_Font();
font.put_Bold(COleVariant((short)TRUE));
font.put_Color(COleVariant((long)RGB(255, 0, 0)));
// font.put_Name(COleVariant(_T("黑体")));
}
}//end of col
}//end of row
//设计计算公式,所有excel中的公式都可以使用-------------------------
FieldName="a11";
range=sheet.get_Range(COleVariant(FieldName),COleVariant(FieldName));
range.put_Formula(COleVariant(_T("=sum(a2:a10")));
//自适应列宽度--------------------------------
CRange cols;
cols=range.get_EntireColumn();
cols.AutoFit();
//::Sleep(5000);
//读取内容-----------------------------------------------------
FieldName="a11";
range = sheet.get_Range(COleVariant(FieldName),COleVariant(FieldName));
COleVariant cov = range.get_Value2();
CString str="success";
cov.ChangeType(VT_BSTR);
str=cov.bstrVal;
AfxMessageBox(str);
//------------------------------------------------------------------
//关闭excel文件,根据需要自行决定
books.Close();
app.Quit();
books.ReleaseDispatch();
app.ReleaseDispatch();
2、结果
三、使用示例2
1、打开指定excel,设置对齐方式,设置字体颜色,合并单元格
//变量定义
CApplication app; //Excel应用程序接口
CWorkbooks books; //工作薄集合
CWorkbook book; //工作薄
CWorksheets sheets; //工作表集合
CWorksheet sheet; //工作表
CRange range; //Excel中针对单元格的操作都应先获取其对应的Range对象
CFont0 font;
CRange cols;
CRange iCell;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covTrue((short)TRUE);
COleVariant covFalse((short)FALSE);
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//初始化
if (!app.CreateDispatch("Excel.Application"))
{
this->MessageBox("无法创建Excel应用!");
return;
}
app.put_Visible(FALSE); //可见
app.put_UserControl(TRUE); //用户可控制
//打开XLS文件
books.AttachDispatch(app.get_Workbooks());
lpDisp = books.Open("C:\\test\\excel\\test.xlsx",
covOptional, covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional);
//得到Workbook
book.AttachDispatch(lpDisp);
//得到Worksheets
sheets.AttachDispatch(book.get_Worksheets());
//得到当前活跃sheet
//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
lpDisp = book.get_ActiveSheet();
sheet.AttachDispatch(lpDisp);
//*****
//读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列
CRange usedRange;
usedRange.AttachDispatch(sheet.get_UsedRange());
range.AttachDispatch(usedRange.get_Rows());
//已经使用的行数
long iRowNum = range.get_Count();
range.AttachDispatch(usedRange.get_Columns());
//已经使用的列数
long iColNum = range.get_Count();
//已使用区域的起始行,从开始
long iStartRow = usedRange.get_Row();
//已使用区域的起始列,从开始
long iStartCol = usedRange.get_Column();
//读取第一个单元格的值
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(COleVariant((long)1), COleVariant((long)1)).pdispVal);
vResult = range.get_Value2();
CString str;
if (vResult.vt == VT_BSTR) //字符串
{
str = vResult.bstrVal;
}
else if (vResult.vt == VT_R8) //8字节的数字
{
str.Format("%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.get_Cells());
iCell.AttachDispatch((range.get_Item(COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
vResult.lVal = 0;
vResult = iCell.get_HorizontalAlignment();
if (vResult.lVal != 0)
{
switch (vResult.lVal)
{
case 1: //默认
break;
case -4108: //居中
break;
case -4131: //*左
break;
case -4152: //*右
break;
}
}
//垂直对齐方式
iCell.AttachDispatch((range.get_Item(COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
vResult.lVal = 0;
vResult = iCell.get_VerticalAlignment();
if (vResult.lVal != 0)
{
switch (vResult.lVal)
{
case -4160: //*上
break;
case -4108: //居中
break;
case -4107: //*下
break;
}
}
//设置第一个单元格字体颜色:红色
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch((range.get_Item(COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
font.AttachDispatch(range.get_Font());
font.put_Color(COleVariant((long)0xFF0000));
//合并单元格的处理
//包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并
CRange unionRange;
range.AttachDispatch(sheet.get_Cells());
unionRange.AttachDispatch(range.get_Item(COleVariant((long)1), COleVariant((long)1)).pdispVal);
vResult = unionRange.get_MergeCells();
if (vResult.boolVal == -1) //是合并的单元格
{
//合并单元格的行数
range.AttachDispatch(unionRange.get_Rows());
long iUnionRowNum = range.get_Count();
//合并单元格的列数
range.AttachDispatch(unionRange.get_Columns());
long iUnionColumnNum = range.get_Count();
//合并区域的起始行,列
long iUnionStartRow = unionRange.get_Row(); //起始行,从开始
long iUnionStartCol = unionRange.get_Column(); //起始列,从开始
}
else if (vResult.boolVal == 0)
{
//不是合并的单元格
}
//将第一个单元格合并成行,列
range.AttachDispatch(sheet.get_Cells());
unionRange.AttachDispatch(range.get_Item(COleVariant((long)1), COleVariant((long)1)).pdispVal); //第一个单元格
unionRange.AttachDispatch(unionRange.get_Resize(COleVariant((long)3), COleVariant((long)2))); //GetResize(3,2) 从第一个单元格开始合并行列的所有单元格
unionRange.Merge(COleVariant((long)0)); //合并单元格
//将文件保存为.xls
app.put_DisplayAlerts(FALSE);
book.SaveAs(COleVariant("C:\\test\\excel\\test1.xlsx"), covOptional, covOptional,
covOptional, covOptional, covOptional, 0,
covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);
//book.Save();
book.Close(covOptional, COleVariant("C:\\test\\excel\\test.xlsx"), covOptional);
books.Close();
//释放对象(相当重要!)
range.ReleaseDispatch();
cols.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//App一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
app.Quit();
app.ReleaseDispatch();
2、结果
更多使用方式,可以参考VC 设置EXCEL单元格的格式