如何在VS2022上的MFC项目中操作Excel(VS2010、VS2012、VS2015、VS2017、VS2019使用方法一样)

news/2024/7/21 5:39:36 标签: mfc, excel, VC++, excel读写, excel操作, vs2022, vs2015

先决条件

  • 本机安装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

excelexcel_sheetrang_18">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

excel_134">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单元格的格式


http://www.niftyadmin.cn/n/5220611.html

相关文章

模板上新|2023年10月DataEase模板市场上新动态

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场&#xff08;https://dataease.io/templates/&#xff09;。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板&#xff0c;方便用户根据自身的业务需求和使用场景选择对应的仪表板模板&#xff0c;并…

提升APP软件的用户体验方法

提升APP软件的用户体验是确保用户满意度和应用成功的关键。以下是一些方法&#xff0c;可以帮助提升APP的用户体验&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.简洁的用户界面设计&#xff1a; …

蓝桥杯day01——根据给定数字划分数组

题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 pivot 。请你将 nums 重新排列&#xff0c;使得以下条件均成立&#xff1a; 所有小于 pivot 的元素都出现在所有大于 pivot 的元素 之前 。所有等于 pivot 的元素都出现在小于和大于 pivot 的元素 中间 。小于 piv…

线性表的逻辑结构

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 只有靠自己的毅力忍耐&#xff0…

Kotlin中常见的List使用

文章目录 1.filter2.map3.count4.first,last5.any,all,none6.find&#xff0c;findLast7.indexOf()和lastIndexOf()查找元素下标8.Slice切片9.Take()和drop()获取指定长度 1.filter filter 就像其本意一样&#xff0c;可以通过 filter 对 Kotlin list 进行过滤。 fun main() …

MFC、VC++操作excel后,excel程序进程无法正常退出的非暴力处理方法

先说处理方式 1、最low的方式&#xff1a;强制结束进程 //打开进程得到进程句柄 HANDLE hProcessOpenProcess(PROCESS_ALL_ACCESS,FALSE,Pid); if(hProcess!NULL) { //结束进程 if (TerminateProcess(hProcess,0)){printf("结束进程成功\n");return 0;} }这种方式…

将用户的session改为分布式共享session

将用户的session改为分布式session 分布式session理解 使用分布式session的原因&#xff1a; 后台服务器是分布式的&#xff08;比如要负载均衡&#xff09;&#xff0c;在A服务器请求的的信息&#xff08;如用户登录信息&#xff09;存在A的session中&#xff0c;B服务器并不…

docker基础快速入门:基础命令、网络、docker compose工具

docker基础命令快速入门 目录 docker基本命令docker 网络docker compose Docker介绍 Docker是一个虚拟环境容器&#xff0c;可以将你的开发环境、代码、配置文件等一并打包到这个容器中&#xff0c;并发布和应用到任意平台中。 Docker的三个概念 镜像 Docker镜像是一个特…