欢迎来到Introzo百科
Introzo百科
当前位置:网站首页 > 技术 > vs2010 使用 excel9.h_VS2010 对Excel读写操作

vs2010 使用 excel9.h_VS2010 对Excel读写操作

日期:2023-09-19 09:11

说到操作excel,可能用java来写更方便一些。mfc确实不太适合这种操作,个人感觉要比java复杂一点,尤其是在数据类型的转换和操作上,java简单有效。下面进入正题,环境为vs2010。

1. 这个小的mfc程序实现的是读取excel中的数据,然后经过数据处理,生成一个新的excel来存放处理结果。

2.我们用到的技术是通过OLE/COM对excel进行操作。

步骤:

1.新建MFC对话框。注意勾选自动化,否则后面加入不了需要的库,导致启动服务失败等错误。有的博客说需要加入

1 if (!AfxOleInit())

2 {

3 AfxMessageBox(IDP_OLE_INIT_FAILED);

4 return FALSE;

5 }

笔者实验发现自己的环境自动添加了这部分代码。

? ? ? ? 2.?向项目工程中添加基本的7个类(?Excel?作为?OLE/COM?库插件,定义好了各类交互的接口,这些接口是跨语言的接口。?VC?可以通过导入这些接口,并通过 ? 接口来对?Excel?的操作),?由于本文只关心对?Excel?表格中的数据的读取,主要关注7个接_?Application、?Workbooks?、?_Workbook?、Worksheets?、?_Worksheet?、Range、Font?。

VS2012?导入?OLE/COM?组件的接口的步骤为:?项目->类向导->添加类->类型库中的MFC类?,先选择要导入的组件所在的路径,即?Excel.exe?所在的路 ? ? ?径,然后再选择?要导入的?Excel?类型库中的接口。组件路径一般为C:\Program Files\Microsoft Office\Office15\EXCEL.exe;格式类似。

? ? ? ? 3. 导入之后需要“#import?"C:\\Program?Files\\Microsoft?Office\\Office12\\EXCEL.EXE"?no_namespace”注释掉,然后添加头文 ? ? ? ? ? ? ? ? 件:#include?到上面7个文件中去。

4.如果有错误error?C2059双击error?C2059,将VARIANT?DialogBox()改成VARIANT?_DialogBox()再次编译,通过!!

5.读写excel。

在对话框头文件中*Dlg.h定义变量

1 //定义接口类变量

2 CApplication app;

3 CWorkbook book;

4 CWorkbooks books;

5 CWorksheet sheet;

6 CWorksheets sheets;

7 CRange range;

8 CMyFont font;

9 CRange cols;

10 LPDISPATCH lpDisp;

以上部分来自网络,经试验,正确无误。

6.功能可以分为三个模块,第一个模块是一个文件选择器,第二个模块是读取excel,第三个模块为创建excel.

(1)文件选择部分

void CTXDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 CFileDialog OpenDlg(true); if(OpenDlg.DoModal() == IDOK){ CEdit* ECtr = (CEdit *)GetDlgItem(IDC_EDIT1); fileNameTrans = OpenDlg.GetPathName(); ECtr->SetWindowText(fileNameTrans); } }

(2)导入excel并读取数据,放到list里面暂存待处理

void CTXDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 int mCount=0; CString str,str1; double num1,num2; double d_skewing =0.004; COleVariant vResult; COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR); if(!app.CreateDispatch(_T("Excel.Application"))){ this->MessageBox(_T("无法创建Excel应用!")); return; } books.AttachDispatch(app.get_Workbooks()); lpDisp = www.introzo.com(fileNameTrans,covOptional, covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional); book.AttachDispatch(lpDisp); sheets.AttachDispatch(book.get_Worksheets()); //得到当前活跃sheet lpDisp = book.get_ActiveSheet(); sheet.AttachDispatch(lpDisp); //获得行数 CRange usedRange; CRange mRange; usedRange.AttachDispatch(sheet.get_UsedRange()); mRange.AttachDispatch(usedRange.get_Rows(),true); int count = mRange.get_Count(); usedRange.ReleaseDispatch(); mRange.ReleaseDispatch(); //读取一个值 range.AttachDispatch(sheet.get_Cells()); range.AttachDispatch(range.get_Item(COleVariant((long)1),COleVariant((long)2)).pdispVal); vResult = range.get_Value2(); if(vResult.vt == VT_BSTR){ str1 = vResult.bstrVal; }else if(vResult.vt == VT_R8){ str1.Format(L"%f",vResult.dblVal); }else{ str1 = "数据类型错误!"; this->MessageBox(str1); return; } num1 = _wtof(str1.GetBuffer(0)); mList1.AddTail(1); mList2.AddTail(str1);//添加第一个值 ++mCount; //读取单元格值 for(int i=2;iMessageBox(str); break; } num2 = _wtof(str.GetBuffer(0)); if(num2-num1>=0.004){ mList1.AddTail(i); mList2.AddTail(str); num1 = num2; ++mCount; } range.ReleaseDispatch(); } books.Close(); sheet.ReleaseDispatch(); book.ReleaseDispatch(); books.ReleaseDispatch(); app.ReleaseDispatch(); app.Quit(); this->MessageBox(_T("数据已导入,请点击导入按键!")); }

(3)对读取的数据进行处理,结果保存,生成新的excel

void CTXDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码 if(!app.CreateDispatch(_T("Excel.Application"),NULL)){ AfxMessageBox(_T("启动Excel服务器失败!")); return ; } //判断当前的Excel的版本 CString strExcelVersion = app.get_Version(); int iStart =0; strExcelVersion = strExcelVersion.Tokenize(_T("."),iStart); if(_T("11")==strExcelVersion){ AfxMessageBox(_T("当前的Excel的版本是2003")); }else if(_T("12")==strExcelVersion){ AfxMessageBox(_T("当前的Excel的版本是2007")); }else{ AfxMessageBox(_T("当前的Excel的版本是其他版本")); } app.put_Visible(true); app.put_UserControl(false); //得到工作薄容器 books.AttachDispatch(app.get_Workbooks()); //打开一个工作薄,如不存在,则创建 CString strBookPath = _T("D:\\tmp.xls"); try{ lpDisp = www.introzo.com(strBookPath,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing); book.AttachDispatch(lpDisp); }catch(...){ lpDisp = books.Add(vtMissing); book.AttachDispatch(lpDisp); } //得到工作薄中的sheet的容器 sheets.AttachDispatch(book.get_Sheets()); //打开一个sheet,如不存在,就新增一个sheet CString strSheetName = _T("NewSheet"); try{ //尝试打开一个已有的sheet lpDisp = sheets.get_Item(_variant_t(strSheetName)); sheet.AttachDispatch(lpDisp); }catch(...){ //创建一个新的sheet lpDisp = sheets.Add(vtMissing,vtMissing,_variant_t((long)1),vtMissing); sheet.AttachDispatch(lpDisp); sheet.put_Name(strSheetName); } range.AttachDispatch(sheet.get_Cells()); //插入数据 POSITION ps1 = mList1.GetHeadPosition(); POSITION ps2 = mList2.GetHeadPosition(); int aa; CString mStr1,mStr2,strr; for(int i=1;ps1!=NULL&&ps2!=NULL;mList1.GetNext(ps1),mList2.GetNext(ps2),i++){ iCells.AttachDispatch(range.get_Item(COleVariant((long)i),COleVariant((long)1)).pdispVal,true); aa = mList1.GetAt(ps1); strr.Format(L"%d",aa); iCells.put_Value2(COleVariant(strr)); iCells.AttachDispatch(range.get_Item(COleVariant((long)i),COleVariant((long)2)).pdispVal,true); strr = mList2.GetAt(ps2); iCells.put_Value2(COleVariant(strr)); } //www.introzo.com(); range.ReleaseDispatch(); sheet.ReleaseDispatch(); sheets.ReleaseDispatch(); book.ReleaseDispatch(); books.ReleaseDispatch(); app.Quit(); app.ReleaseDispatch(); }

https://www.introzo.com/ywx123_/article/details/77074038

VS2010对Excel读写操作 一、开发环境 编程环境 VS2010 office版本 office 2010 注意 :这里office版本号不一定非得和vs版本号一致。 二、基本实现功能 基本实现对Excel的读写 创建一个表格,并向里面写入内容 三、基本操作步骤 1. 新建一个基于MFC的对话框工程。 如下图。注意:勾选基本对话框。默认编码方式使用的是Unicode库,在对字符操作时需要将char转化为TCHAR,一般用_T(“xxx”)即可。(vc6 默认不是uicode这点需要区别)

图1 其余选择,默认直接点击完成即可。生成一个基本对话框如图2。

图2 将上面的默认控件删除。

2. 导入Excel类库 从office安装目录下找到EXCEL.exe(D:\Program Files(x86)\Microsoft Office\Office14),在VS2010中添加类库(从类库中添加)类向导->添加类->从类库中添加。如图3、图4

图3

图4 依次从接口:_Application、_Workbook、_Worksheet、Workbooks、Worksheets、Font、Range(暂时只用到这些)生成对应的类(CApplication 、CWorkbook、CWorksheet、CWorkbook、Cworksheets、CFont0、CRange)如图5所示。点击确定,总生成对应.h、.cpp文件并添加到工程。?

图5 在所建对话框添加一个按钮,名字修改为导出EXCEL,ID修改为IDC_BTN_EXCEL,添加一个消息消息函数(这里为OnBtnExcel())。

3. 解决导入工程后的编译错误。 在stdafx.h中包含,以上头文件,编译。 #include "CApplication.h" #include "CFont0.h" #include "CRange.h" #include "CWorkbook.h" #include "CWorkbooks.h" #include "CWorksheet.h" #include "CWorksheets.h" 1 2 3 4 5 6 7 屏蔽掉导入每个头文件下的//#import “D:\Program Files (x86)\Microsoft Office\Office14\EXCEL.EXE” no_namespace 编译出现1>c:\users\desktop\exceltest\crange.h(335): warning C4003: “DialogBoxW”宏的实参不足。将DialogBox修改为_DialogBox。 4. 实例代码。 在CExcelTestApp的InitInstance初始化com组件,添加COM/OLE支持 ? ? if(CoInitialize(NULL)!=0) ? ? { ? ? ? ? AfxMessageBox(_T("初始化失败")); ? ? } 1 2 3 4 同时在ExitInstance里释放资源

? ? CoUninitialize(); ?//释放com资源 1 在对话框的按钮事件实现导出EXCEL。 /********************************************************************** *作者:ywx2904 *函数名:OnBtnExcel *功 ?能:创建Excel,向里面添加内容,并导出 *参 ?数: 无 *返回值:无 ***********************************************************************/ void CExcelTestDlg::OnBtnExcel() { ? ? //1.创建基本对象 ? ? CApplication App; ?//创建应用程序实例 ? ? CWorkbooks Books; ?//工作簿,多个Excel文件 ? ? CWorkbook Book; ? ?//单个工作簿 ? ? CWorksheets sheets;//多个sheet页面 ? ? CWorksheet sheet; ?//单个sheet页面 ? ? CRange range; ? ? ?//操作单元格 ? ? //2.打开指定Excel文件,如果不存在就创建 ? ? char path[MAX_PATH]; ? ? GetCurrentDirectory(MAX_PATH,(TCHAR*)path);//获取当前路径 ? ? CString strExcelFile =(TCHAR*) path; ? ? CString strdevName = _T("\\Test.xlsx"); ? ?//xls也行 ? ? strExcelFile += strdevName; ? ? COleVariant ? ? ? ? covTrue((short)TRUE), ? ? ? ? covFalse((short)FALSE), ? ? ? ? covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);

? ? LPDISPATCH lpdisp = NULL; ? ? //1.创建Excel实例 ? ? if(!App.CreateDispatch(_T("Excel.Application"),NULL)) ? ? { ? ? ? ? AfxMessageBox(_T("创建Excel实例失败")); ? ? ? ? exit(-1); ? ? } ? ? else ? ? { ? ? ? ? AfxMessageBox(_T("创建成功")); ? ? } ? ? App.put_Visible(TRUE); ?//打开Excel ? ? App.put_UserControl(FALSE);? ? ? //2. 得到workbooks容器 ? ? Books.AttachDispatch(App.get_Workbooks()); ? ? Book.AttachDispatch(Books.Add(covOptional)); ? ? sheets.AttachDispatch(Book.get_Worksheets()); ? ? sheet.AttachDispatch(sheets.get_Item(COleVariant((short)1))); ? //获取sheet1 ? ? sheet.put_Name(_T("TestName")); ? ? //设置sheet1名字

? ? //3. 加载要合并的单元格 ? ? range.AttachDispatch(sheet.get_Range(COleVariant(_T("B2")),COleVariant(_T("E2"))),TRUE); ? ? range.Merge(COleVariant((long)0)); ?//合并单元格

? ? //4. 设置表格内容 ? ? range.AttachDispatch(sheet.get_Cells(),TRUE); ? ? ? ? ? ? ? //加载所有单元格 ? ? range.put_Item(COleVariant((long)2),COleVariant((long)2),COleVariant(_T("电气工程及其自动化课程统计"))); ? ? range.put_Item(COleVariant((long)3),COleVariant((long)2),COleVariant(_T("课程名称"))); ? ? range.put_Item(COleVariant((long)3),COleVariant((long)3),COleVariant(_T("课时"))); ? ? range.put_Item(COleVariant((long)3),COleVariant((long)4),COleVariant(_T("难度"))); ? ? range.put_Item(COleVariant((long)3),COleVariant((long)5),COleVariant(_T("教学方式")));

? ? range.put_Item(COleVariant((long)4),COleVariant((long)2),COleVariant(_T("电磁场"))); ? ? range.put_Item(COleVariant((long)4),COleVariant((long)3),COleVariant(_T("30"))); ? ? range.put_Item(COleVariant((long)4),COleVariant((long)4),COleVariant(_T("变态难"))); ? ? range.put_Item(COleVariant((long)4),COleVariant((long)5),COleVariant(_T("老师讲课")));

? ? range.put_Item(COleVariant((long)5),COleVariant((long)2),COleVariant(_T("电机学"))); ? ? range.put_Item(COleVariant((long)5),COleVariant((long)3),COleVariant(_T("40"))); ? ? range.put_Item(COleVariant((long)5),COleVariant((long)4),COleVariant(_T("难"))); ? ? range.put_Item(COleVariant((long)5),COleVariant((long)5),COleVariant(_T("老师讲课加实验")));

? ? range.put_Item(COleVariant((long)6),COleVariant((long)2),COleVariant(_T("PLC"))); ? ? range.put_Item(COleVariant((long)6),COleVariant((long)3),COleVariant(_T("20"))); ? ? range.put_Item(COleVariant((long)6),COleVariant((long)4),COleVariant(_T("普通"))); ? ? range.put_Item(COleVariant((long)6),COleVariant((long)5),COleVariant(_T("老师讲课加实验")));

? ? //range.put_Item(COleVariant((long)7),COleVariant((long)2),COleVariant(_T("电力系统"))); ? ? //range.put_Item(COleVariant((long)7),COleVariant((long)3),COleVariant(_T("50"))); ? ? //range.put_Item(COleVariant((long)7),COleVariant((long)4),COleVariant(_T("难"))); ? ? //range.put_Item(COleVariant((long)7),COleVariant((long)5),COleVariant(_T("老师讲课加实验")));

? ? range.AttachDispatch(sheet.get_UsedRange());//加载已使用的单元格 ? ? range.put_WrapText(COleVariant((long)1)); ? //设置文本自动换行

? ? //5.设置对齐方式 ? ? //水平对齐:默认 1 居中 -4108, 左= -4131,右=-4152 ? ? //垂直对齐:默认 2 居中 -4108, 左= -4160,右=-4107 ? ? range.put_VerticalAlignment(COleVariant((long)-4108)); ? ? range.put_HorizontalAlignment(COleVariant((long)-4108)); ? ? //6.设置字体颜色 ? ? CFont0 ft; ? ? ft.AttachDispatch(range.get_Font()); ? ? ft.put_Name(COleVariant(_T("楷体"))); //字体 ? ? ft.put_ColorIndex(COleVariant((long)1));//颜色 ? ?//黑色 ? ? ft.put_Size(COleVariant((long)12)); ? ? //大小

? ? range.AttachDispatch(sheet.get_Range(COleVariant(_T("B2")),COleVariant(_T("E2"))),TRUE); ? ? ft.AttachDispatch(range.get_Font()); ? ? ft.put_Name(COleVariant(_T("华文行楷"))); ? ? ft.put_Bold(COleVariant((long)1)); ? ? ft.put_ColorIndex(COleVariant((long)5)); ? ?//颜色 ? ? ? ? ft.put_Size(COleVariant((long)18)); ? ? ? ? //大小 ? ? Book.SaveCopyAs(COleVariant(strExcelFile)); //保存

? ? Book.put_Saved(TRUE); ? ? //8.释放资源 ? ? range.ReleaseDispatch(); ? ? sheet.ReleaseDispatch(); ? ? sheets.ReleaseDispatch(); ? ? Book.ReleaseDispatch(); ? ? Books.ReleaseDispatch(); ? ? App.ReleaseDispatch(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 5. 最终效果

图6 四、基本原理介绍 一般操作Excel步骤 创建一个Excel应用程序 app 得到Workbooks容器 打开一个workbook或者创建一个workbook 得到workbook的worksheets容器 打开一个worksheet或者创建一个worksheet 通过Range对worksheet里的单元格进行读写操作。 保存Excel释放资源 五、参考文献 http://www.introzo.com/xiaoxiangyuan123456/article/details/70941588? http://www.introzo.com/Augusdi/article/details/5782575 ---------------------? 作者:ywx123_? 来源:CSDN? 原文:https://www.introzo.com/ywx123_/article/details/77074038? 版权声明:本文为博主原创文章,转载请附上博文链接!

最近一个同学说是要做一个报账的软件,总体上要实现的功能就是读写Excel文件,于是自己就开始在网上找读写Excel的方法,首先看到了C/C++读写Excel的几种方法,说是读写的方法有很多,但是反正就是各有利弊,我就选择了以OLE的方式进行Excel的操作(这种方式必须要在电脑上安装Excel程序,否则连最开始的配置就无法完成)。

在网上也看到了很多教程,其中VS2010通过OLE操作Excel2010这篇博客的正文加上下面有个博主的评论就差不多可以实现了,但是都是以文字、方法的方式进行讲解,很难操作,并且自己在弄得时候也遇到了各种各样的问题,所以,我以我自己的实例进行讲解:

1.新建一个MFC工程文件,如下

2.为工程文件导入Excel.exe程序并添加一些必须的类,首先点“文件”,然后找到自己的Excel的安装位置添加过来,最后添加下面 的那几个类(如果前面不小心已经添加了这几个类上面却没有添加Excel.exe程序,这个时候直接把添加的文件直接“删除”即可,如果不删直接添加的话仍然会添加成功,但是添加的就是“CApplication0.h”、“CRange0.h”,这样的话就会跟下面添加的头文件和源文件的类不一致,就会报错)

3.添加完成以后,在“解决方案资源管理器”里面就多了下面6个文件,依次打开每个文件,把右边这个路径给注释掉或者直接删掉

4.这个时候编译时没有问题的

5.为这个工程添加对Excel表格进行操作的头文件“IllusionExcelFile.h”和源文件“IllusionExcelFile.cpp”

头文件(IllusionExcelFile.h):

#pragma once

//OLE的头文件

#include "CRange.h"

#include "CWorkbook.h"

#include "CWorkbooks.h"

#include "CWorksheet.h"

#include "CWorksheets.h"

#include "CApplication.h"

///

///用于OLE的方式的EXCEL读写,

class IllusionExcelFile

{

public:

//构造函数和析构函数

IllusionExcelFile();

virtual ~IllusionExcelFile();

protected:

///打开的EXCEL文件名称

CString open_excel_file_;

///EXCEL BOOK集合,(多个文件时)

CWorkbooks excel_books_;

///当前使用的BOOK,当前处理的文件

CWorkbook excel_work_book_;

///EXCEL的sheets集合

CWorksheets excel_sheets_;

///当前使用sheet

CWorksheet excel_work_sheet_;

///当前的操作区域

CRange excel_current_range_;

///是否已经预加载了某个sheet的数据

BOOL already_preload_;

///Create the SAFEARRAY from the VARIANT ret.

COleSafeArray ole_safe_array_;

protected:

///EXCEL的进程实例

static CApplication excel_application_;

public:

///

void ShowInExcel(BOOL bShow);

///检查一个CELL是否是字符串

BOOL IsCellString(long iRow, long iColumn);

///检查一个CELL是否是数值

BOOL IsCellInt(long iRow, long iColumn);

///得到一个CELL的String

CString GetCellString(long iRow, long iColumn);

///得到整数

int GetCellInt(long iRow, long iColumn);

///得到double的数据

double GetCellDouble(long iRow, long iColumn);

///取得行的总数

int GetRowCount();

///取得列的总数

int GetColumnCount();

///使用某个shet,shit,shit

BOOL LoadSheet(long table_index,BOOL pre_load = FALSE);

///通过名称使用某个sheet,

BOOL LoadSheet(LPCTSTR sheet,BOOL pre_load = FALSE);

///通过序号取得某个Sheet的名称

CString GetSheetName(long table_index);

///得到Sheet的总数

int GetSheetCount();

///打开文件

BOOL OpenExcelFile(LPCTSTR file_name);

///关闭打开的Excel 文件,有时候打开EXCEL文件就要

void CloseExcelFile(BOOL if_save = FALSE);

//另存为一个EXCEL文件

void SaveasXSLFile(const CString &xls_file);

///取得打开文件的名称

CString GetOpenFileName();

///取得打开sheet的名称

CString GetLoadSheetName();

///写入一个CELL一个int

void SetCellInt(long irow, long icolumn,int new_int);

///写入一个CELL一个string

void SetCellString(long irow, long icolumn,CString new_string);

public:

///初始化EXCEL OLE

static BOOL InitExcel();

///释放EXCEL的 OLE

static void ReleaseExcel();

///取得列的名称,比如27->AA

static char *GetColumnName(long iColumn);

protected:

//预先加载

void PreLoadSheet();

};

源文件(IllusionExcelFile.cpp):

#include "StdAfx.h"

#include "IllusionExcelFile.h"

COleVariant

covTrue((short)TRUE),

covFalse((short)FALSE),

covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

//

CApplication IllusionExcelFile::excel_application_;

IllusionExcelFile::IllusionExcelFile():

already_preload_(FALSE)

{

}

IllusionExcelFile::~IllusionExcelFile()

{

//

CloseExcelFile();

}

//初始化EXCEL文件,

BOOL IllusionExcelFile::InitExcel()

{

CoUninitialize();

if(CoInitialize(NULL)==S_FALSE)

{

AfxMessageBox(_T("初始化COM支持库失败!"));

return FALSE;

}

//创建Excel 2000服务器(启动Excel)

if (!excel_application_.CreateDispatch(_T("Excel.Application"),NULL))

{

AfxMessageBox(_T("创建Excel服务失败,你可能没有安装EXCEL,请检查!"));

return FALSE;

}

excel_application_.put_DisplayAlerts(FALSE);

return TRUE;

}

//

void IllusionExcelFile::ReleaseExcel()

{

excel_application_.Quit();

excel_application_.ReleaseDispatch();

excel_application_=NULL;

}

//打开excel文件

BOOL IllusionExcelFile::OpenExcelFile(LPCTSTR file_name)

{

//先关闭

CloseExcelFile();

//利用模板文件建立新文档

excel_books_.AttachDispatch(excel_application_.get_Workbooks(),true);

LPDISPATCH lpDis = NULL;

lpDis = excel_books_.Add(COleVariant(file_name));

if (lpDis)

{

excel_work_book_.AttachDispatch(lpDis);

//得到Worksheets

excel_sheets_.AttachDispatch(excel_work_book_.get_Worksheets(),true);

//记录打开的文件名称

open_excel_file_ = file_name;

return TRUE;

}

return FALSE;

}

//关闭打开的Excel 文件,默认情况不保存文件

void IllusionExcelFile::CloseExcelFile(BOOL if_save)

{

//如果已经打开,关闭文件

if (open_excel_file_.IsEmpty() == FALSE)

{

//如果保存,交给用户控制,让用户自己存,如果自己SAVE,会出现莫名的等待

if (if_save)

{

ShowInExcel(TRUE);

}

else

{

//

excel_work_book_.Close(COleVariant(short(FALSE)),COleVariant(open_excel_file_),covOptional);

excel_books_.Close();

}

//打开文件的名称清空

open_excel_file_.Empty();

}

excel_sheets_.ReleaseDispatch();

excel_work_sheet_.ReleaseDispatch();

excel_current_range_.ReleaseDispatch();

excel_work_book_.ReleaseDispatch();

excel_books_.ReleaseDispatch();

}

void IllusionExcelFile::SaveasXSLFile(const CString &xls_file)

{

excel_work_book_.SaveAs(COleVariant(xls_file),

covOptional,

covOptional,

covOptional,

covOptional,

covOptional,

0,

covOptional,

covOptional,

covOptional,

covOptional,

covOptional);

return;

}

int IllusionExcelFile::GetSheetCount()

{

return excel_sheets_.get_Count();

}

CString IllusionExcelFile::GetSheetName(long table_index)

{

CWorksheet sheet;

sheet.AttachDispatch(excel_sheets_.get_Item(COleVariant((long)table_index)),true);

CString name = sheet.get_Name();

sheet.ReleaseDispatch();

return name;

}

//按照序号加载Sheet表格,可以提前加载所有的表格内部数据

BOOL IllusionExcelFile::LoadSheet(long table_index,BOOL pre_load)

{

LPDISPATCH lpDis = NULL;

excel_current_range_.ReleaseDispatch();

excel_work_sheet_.ReleaseDispatch();

lpDis = excel_sheets_.get_Item(COleVariant((long)table_index));

if (lpDis)

{

excel_work_sheet_.AttachDispatch(lpDis,true);

excel_current_range_.AttachDispatch(excel_work_sheet_.get_Cells(), true);

}

else

{

return FALSE;

}

already_preload_ = FALSE;

//如果进行预先加载

if (pre_load)

{

PreLoadSheet();

already_preload_ = TRUE;

}

return TRUE;

}

//按照名称加载Sheet表格,可以提前加载所有的表格内部数据

BOOL IllusionExcelFile::LoadSheet(LPCTSTR sheet,BOOL pre_load)

{

LPDISPATCH lpDis = NULL;

excel_current_range_.ReleaseDispatch();

excel_work_sheet_.ReleaseDispatch();

lpDis = excel_sheets_.get_Item(COleVariant(sheet));

if (lpDis)

{

excel_work_sheet_.AttachDispatch(lpDis,true);

excel_current_range_.AttachDispatch(excel_work_sheet_.get_Cells(), true);

}

else

{

return FALSE;

}

//

already_preload_ = FALSE;

//如果进行预先加载

if (pre_load)

{

already_preload_ = TRUE;

PreLoadSheet();

}

return TRUE;

}

//得到列的总数

int IllusionExcelFile::GetColumnCount()

{

CRange range;

CRange usedRange;

usedRange.AttachDispatch(excel_work_sheet_.get_UsedRange(), true);

range.AttachDispatch(usedRange.get_Columns(), true);

int count = range.get_Count();

usedRange.ReleaseDispatch();

range.ReleaseDispatch();

return count;

}

//得到行的总数

int IllusionExcelFile::GetRowCount()

{

CRange range;

CRange usedRange;

usedRange.AttachDispatch(excel_work_sheet_.get_UsedRange(), true);

range.AttachDispatch(usedRange.get_Rows(), true);

int count = range.get_Count();

usedRange.ReleaseDispatch();

range.ReleaseDispatch();

return count;

}

//检查一个CELL是否是字符串

BOOL IllusionExcelFile::IsCellString(long irow, long icolumn)

{

CRange range;

range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);

COleVariant vResult =range.get_Value2();

//VT_BSTR标示字符串

if(vResult.vt == VT_BSTR)

{

return TRUE;

}

return FALSE;

}

//检查一个CELL是否是数值

BOOL IllusionExcelFile::IsCellInt(long irow, long icolumn)

{

CRange range;

range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);

COleVariant vResult =range.get_Value2();

//好像一般都是VT_R8

if(vResult.vt == VT_INT || vResult.vt == VT_R8)

{

return TRUE;

}

return FALSE;

}

//

CString IllusionExcelFile::GetCellString(long irow, long icolumn)

{

COleVariant vResult ;

CString str;

//字符串

if (already_preload_ == FALSE)

{

CRange range;

range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);

vResult =range.get_Value2();

range.ReleaseDispatch();

}

//如果数据依据预先加载了

else

{

long read_address[2];

VARIANT val;

read_address[0] = irow;

read_address[1] = icolumn;

ole_safe_array_.GetElement(read_address, &val);

vResult = val;

}

if(vResult.vt == VT_BSTR)

{

str=vResult.bstrVal;

}

//整数

else if (vResult.vt==VT_INT)

{

str.Format(_T("%d"),vResult.pintVal);

}

//8字节的数字

else if (vResult.vt==VT_R8)

{

str.Format(_T("%0.0f"),vResult.dblVal);

}

//时间格式

else if(vResult.vt==VT_DATE)

{

SYSTEMTIME st;

VariantTimeToSystemTime(www.introzo.com, &st);

CTime tm(st);

str=tm.Format("%Y-%m-%d");

}

//单元格空的

else if(vResult.vt==VT_EMPTY)

{

str="";

}

return str;

}

double IllusionExcelFile::GetCellDouble(long irow, long icolumn)

{

double rtn_value = 0;

COleVariant vresult;

//字符串

if (already_preload_ == FALSE)

{

CRange range;

range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);

vresult =range.get_Value2();

range.ReleaseDispatch();

}

//如果数据依据预先加载了

else

{

long read_address[2];

VARIANT val;

read_address[0] = irow;

read_address[1] = icolumn;

ole_safe_array_.GetElement(read_address, &val);

vresult = val;

}

if (vresult.vt==VT_R8)

{

rtn_value = vresult.dblVal;

}

return rtn_value;

}

//VT_R8

int IllusionExcelFile::GetCellInt(long irow, long icolumn)

{

int num;

COleVariant vresult;

if (already_preload_ == FALSE)

{

CRange range;

range.AttachDispatch(excel_current_range_.get_Item (COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);

vresult = range.get_Value2();

range.ReleaseDispatch();

}

else

{

long read_address[2];

VARIANT val;

read_address[0] = irow;

read_address[1] = icolumn;

ole_safe_array_.GetElement(read_address, &val);

vresult = val;

}

//

num = static_cast(vresult.dblVal);

return num;

}

void IllusionExcelFile::SetCellString(long irow, long icolumn,CString new_string)

{

COleVariant new_value(new_string);

CRange start_range = excel_work_sheet_.get_Range(COleVariant(_T("A1")),covOptional);

CRange write_range = start_range.get_Offset(COleVariant((long)irow -1),COleVariant((long)icolumn -1) );

write_range.put_Value2(new_value);

start_range.ReleaseDispatch();

write_range.ReleaseDispatch();

}

void IllusionExcelFile::SetCellInt(long irow, long icolumn,int new_int)

{

COleVariant new_value((long)new_int);

CRange start_range = excel_work_sheet_.get_Range(COleVariant(_T("A1")),covOptional);

CRange write_range = start_range.get_Offset(COleVariant((long)irow -1),COleVariant((long)icolumn -1) );

write_range.put_Value2(new_value);

start_range.ReleaseDispatch();

write_range.ReleaseDispatch();

}

//

void IllusionExcelFile::ShowInExcel(BOOL bShow)

{

excel_application_.put_Visible(bShow);

excel_application_.put_UserControl(bShow);

}

//返回打开的EXCEL文件名称

CString IllusionExcelFile::GetOpenFileName()

{

return open_excel_file_;

}

//取得打开sheet的名称

CString IllusionExcelFile::GetLoadSheetName()

{

return excel_work_sheet_.get_Name();

}

//取得列的名称,比如27->AA

char *IllusionExcelFile::GetColumnName(long icolumn)

{

static char column_name[64];

size_t str_len = 0;

while(icolumn > 0)

{

int num_data = icolumn % 26;

icolumn /= 26;

if (num_data == 0)

{

num_data = 26;

icolumn--;

}

column_name[str_len] = (char)((num_data-1) + 'A' );

str_len ++;

}

column_name[str_len] = '\0';

//反转

_strrev(column_name);

return column_name;

}

//预先加载

void IllusionExcelFile::PreLoadSheet()

{

CRange used_range;

used_range = excel_work_sheet_.get_UsedRange();

VARIANT ret_ary = used_range.get_Value2();

if (!(ret_ary.vt & VT_ARRAY))

{

return;

}

//

ole_safe_array_.Clear();

ole_safe_array_.Attach(ret_ary);

}

6.这个时候再次编译会出现如下问题,双击出现的错误定位到错误的行,只需在“DialogBox()”前面加一个横杠改为“_DialogBox()”即可

7.这个时候已经对工程文件配置好了,下面就开始进行测试,对Excel进行读写:

8.在工程文件的头文件“COperateExcelByOLEDlg.h”中包含我们刚才添加的头文件,并定义一个“IllusionExcelFile”类的对象“excl”如下:

? ?

9.在源文件“COperateExcelByOLEDlg.cpp”中的“OnInitDialog()”初始化函数中添加如下代码:

AfxOleInit();

excl.InitExcel();

10.在界面上添加一个按钮控件并为这个按钮添加如下代码(代码里面为了测试,我在电脑的F盘新建了一个“Exce”的文件夹并新建了一个“工作簿1.xlsx”文件,自己也可以根据自己的需求改变路径):

bool bRet = excl.OpenExcelFile("F:\\Excel\\工作簿1.xlsx");

CString strSheetName = excl.GetSheetName(1);

bool bLoad = excl.LoadSheet(strSheetName);

int nRow = excl.GetRowCount();

int nCol = excl.GetColumnCount();

if (bRet == 1)

{

AfxMessageBox("文件打开成功!");

for (int i=1; i<10; ++i)

{

for (int j=1; j<20; ++j)

{

CString strValue = excl.GetCellString(i,j);

excl.SetCellInt(i,j,9);

}

}

}

else

{

AfxMessageBox("文件打开失败!");

return ;

}

excl.SaveasXSLFile("F:\\Excel\\工作簿2.xlsx");

AfxMessageBox("文件写入成功!");

11.此时按道理讲,应该就可以运行了

??

12.如果运行的时候报错:“服务器出现意外情况”,看到一篇C#操作Excel报错:服务器出现意外情况,就是自己的电脑安装了福熙阅读器这个软件

解决方案:

打开你电脑中的Office-Excel。在“文件”->"选项"->"加载项"->"管理",选择“COM加载项”,点击“转到”按钮。将“复习阅读器”这个选项不勾选即可

最后,我上传了这个实例教程的工程文件,需要的可以自行下载:https://www.introzo.com/my

因为现在上传好像是自己改不了下载所需积分,因此如果没有积分的朋友可以直接下面评论给我说,我再私发也可以的

?

关灯