vs2010 使用 excel9.h_VS2010 对Excel读写操作
说到操作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?
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;i
(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
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
因为现在上传好像是自己改不了下载所需积分,因此如果没有积分的朋友可以直接下面评论给我说,我再私发也可以的
?
相关文章
- 10-06 Python Joblib库使用方法总结
- 10-06 Python标准类库
- 10-06 Java Maven 设置配置参考
- 10-05 戈多的场景树
- 10-05 戈多动画
- 10-05 在 Godot 中设计标题画面
- 10-05 信息搜索和可视化
- 10-05 设计流程与任务分析
- 10-05 颤动警报对话框
- 10-05 PostgreSQL远程连接配置管理/账号密码分配
- 10-05 Windows server 创建FTP 包括ft
- 10-05 Mongodb副本集加分片集群安全认证使用账号密码
- 10-05 浅谈ubuntu中执行.sh文件的几种方式的区别
- 10-05 Linux性能优化的实用思路和技巧(linux性能
- 10-05 如何轻松安装Linux系统显卡驱动(Linux安装
- 10-05 win10动态锁设置教程
- 10-05 win10关闭Win10右下角提示的教程
- 10-05 win10设置定时提醒闹钟方法
- 10-05 win10音频服务未运行 错误1068怎么办
- 10-05 win10哪里下载
- 最近发表