写了不少blog,也码了一点点文字,不知道为啥,被大家看的比较多几篇文章却总有那篇《C++读写EXCEL文件方式比较》。

小小伤心一下,我blog里面写的很认真的文字还有几篇,这篇大概是最随意的文章。个人估计这是SEO的作用导致的。

另外,由于文中提到了可以加快OLE读取的EXCEL的速度,总有一些哥们找我要代码。

好吧,好吧,把代码放出来,因为我原来也是找人家的代码逐步改的。来而不往非礼也。

我的代码参考的地方是这儿,再次感谢原作者

http://blog.csdn.net/gyssoft/archive/2007/04/29/1592104.aspx

我根据自己的需要做了整理,干净了一点,而后根据发现的速度问题做了一些优化。

预加载的思路来自这个帖子

http://topic.csdn.net/t/20030626/21/1962211.html

其实思路很简单,不再一个CELL一个CELL的伛数据,而是一次把表格里面所有的数据读取出来处理。

.h文件的源码代码如下:

其中的头文件都是OLE的头文件。如何导出可以参考

http://blog.csdn.net/wyz365889/article/details/7599924

我自己这儿一直保存了一套别人生成的这几个文件,也可以用。大家可以找找有没有下载的,不过我不太确认跨版本是否可行。

还有既然是OLE,你一定要安装EXCEL的。

#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_; ///当前使用sheetCWorksheet    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的StringCString GetCellString(long iRow, long iColumn);///得到整数int     GetCellInt(long iRow, long iColumn);///得到double的数据double  GetCellDouble(long iRow, long iColumn);///取得行的总数int GetRowCount();///取得列的总数int GetColumnCount();///使用某个shet,shit,shitBOOL LoadSheet(long table_index,BOOL pre_load = FALSE);///通过名称使用某个sheet,BOOL LoadSheet(const char* sheet,BOOL pre_load = FALSE);///通过序号取得某个Sheet的名称CString GetSheetName(long table_index);///得到Sheet的总数int GetSheetCount();///打开文件BOOL OpenExcelFile(const char * file_name);///关闭打开的Excel 文件,有时候打开EXCEL文件就要void CloseExcelFile(BOOL if_save = FALSE);//另存为一个EXCEL文件void SaveasXSLFile(const CString &xls_file);///取得打开文件的名称CString GetOpenFileName();///取得打开sheet的名称CString GetLoadSheetName();///写入一个CELL一个intvoid SetCellInt(long irow, long icolumn,int new_int);///写入一个CELL一个stringvoid SetCellString(long irow, long icolumn,CString new_string);public:///初始化EXCEL OLEstatic BOOL InitExcel();///释放EXCEL的 OLEstatic void ReleaseExcel();///取得列的名称,比如27->AAstatic char *GetColumnName(long iColumn);protected://预先加载void PreLoadSheet();
};

CPP文件的与代码如下:

/******************************************************************************************
Copyright           : 2000-2004, Appache  2.0
FileName            : illusion_excel_file.cpp
Author              : Sail
Version             :
Date Of Creation    : 2009年4月3日
Description         : Others              :
Function List       : 1.  ......Modification History:1.Date  :
Author  :
Modification  :这个类是从网上下载的,我坐享其成,感谢原来的作者,我只试试是稍稍做了一下修正。修正包括一些参数的使用不谨慎,bool 改为BOOL等,对于对象关系,我改了一部分,感觉原来的作者对于OO的思路部分不是很清楚。对于这类东西OLE,我完全不了解,用别人封装的东西感觉还是放心了很多,C++,伟大的C++http://blog.csdn.net/gyssoft/archive/2007/04/29/1592104.aspxOLE读写EXCEL都比较慢,所以应该尽量减少OLE的次数对于读取,还有解决方法,请试用一下预加载的方式,这个方法一次加载所有的读取数据,如此速度就飞快了。据说写数据是没有什么方法加快的http://topic.csdn.net/t/20030626/21/1962211.html增加了一些写入方式的代码,保证可以写入EXCEL数据区,但是对于保存,我发现如果调用CLOSE并且保存的方式,速度非常慢,我不理解为什么。所以我吧EXCEL打开了,让你进行后续管理,******************************************************************************************///-----------------------excelfile.cpp----------------#include "StdAfx.h"
#include "illusion_excel_file.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()
{//创建Excel 2000服务器(启动Excel) if (!excel_application_.CreateDispatch("Excel.Application",NULL)) { AfxMessageBox("创建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(const char *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(const char* 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_R8if(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("%d",vResult.pintVal);}//8字节的数字 else if (vResult.vt==VT_R8)     {str.Format("%0.0f",vResult.dblVal);}//时间格式else if(vResult.vt==VT_DATE)    {SYSTEMTIME st;VariantTimeToSystemTime(vResult.date, &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<int>(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("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("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);
}
【本文作者是雁渡寒潭,本着自由的精神,你可以在无盈利的情况完整转载此文档,转载时请附上BLOG链接:http://www.cnblogs.com/fullsail/ 或者http://blog.csdn.net/fullsail,否则每字一元,每图一百不讲价。对Baidu文库。360doc加价一倍】

C++使用OLE高速读写EXCEL的源码相关推荐

  1. C++使用OLE/COM高速读写EXCEL的源码

    通过VC实现对Excel表格的操作的方法有多种,如:通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现.本文主要研究通过OLE/COM实现对Excel表格的操作.另外,本文主 ...

  2. 以OLE方式读写EXCEL的C++类【转载】

    ◆C++中的[L"https://msdn.microsoft.com/library"]. 这个是C++标准规定的写法.详见以下链接: http://bbs.csdn.net/t ...

  3. VS2010 MFC通过OLE方式读写Excel文件(实例+工程文件)

    最近一个同学说是要做一个报账的软件,总体上要实现的功能就是读写Excel文件,于是自己就开始在网上找读写Excel的方法,首先看到了C/C++读写Excel的几种方法,说是读写的方法有很多,但是反正就 ...

  4. 使用NPOI导入导出标准Excel(源码)

    http://www.cnblogs.com/lwme/archive/2011/11/18/npoi_excel_import_export.html 尝试过很多Excel导入导出方法,都不太理想, ...

  5. java如何实现导出Excel(附源码)--文末送书

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 作者:你在我家门口 juejin.im/post/5c6b6b126fb9a04a0c2f024f 前言 公司项目最近有一个需要:报表导出 ...

  6. Ceph 学习——OSD读写流程与源码分析(一)

    消息从客户端发送而来,之前几节介绍了 客户端下 对象存储.块存储库的实现以及他们在客户端下API请求的发送过程(Ceph学习--Librados与Osdc实现源码解析 . Ceph学习--客户端读写操 ...

  7. Python 实现txt、excel、csv文件读写【附源码】

    目录 前言 一.txt文件读写 二.excel文件读写 总结 前言 本文介绍使用Python进行文件读写操作,包括txt文件.excel文件(xlsx.xls.csv) 编译器使用的是PyCharm ...

  8. Pandas处理Excel文件源码学习

    pandas.read_excel pandas.read_excel API pandas.read_excel(io, sheet_name=0, header=0, names=None, in ...

  9. golang RWMutex读写互斥锁源码分析

    针对Golang 1.9的sync.RWMutex进行分析,与Golang 1.10基本一样除了将panic改为了throw之外其他的都一样. RWMutex是读写互斥锁.锁可以由任意数量的读取器或单 ...

  10. 若依框架Excel导出源码解析

    入口 /*** 导出接收人列表*/@PostMapping("/export")@ResponseBodypublic AjaxResult export(Wxpusher wxp ...

最新文章

  1. 4个可以写进简历的京东 NLP 项目实战
  2. 跟无闻学习GO Web 编程(四) -- bee 工具使用
  3. 模拟usb设备_高速USB数据采集卡
  4. 抽了几天用Flex写了个上传小工具,支持批量上传,支持配置
  5. orcle10忘记密码
  6. 这么奇葩搞笑的代码注释你见过吗
  7. Cisco ACS AAA服务器导入华为私有属性
  8. [转载] numpy.base_repr 方法解释
  9. SQL Server中删除重复数据
  10. jquery中的trigger和triggerHandler区别
  11. c语言void调用不可作为,C语言的选择题.pdf
  12. Oracle openv目录,nub备份安装目录/openv由来
  13. 一些可以参考的文档集合5
  14. Ps(Adobephoto shop)当中的色彩范围应该使用在什么地方和使用方法和快速的将一张图片变成素描
  15. 修改Hosts文件解决文件访问问题
  16. ORACLE 10064诊断工具,TRCA安装与测试
  17. 液压比例阀放大器比例控制器比例阀放大板
  18. html盒模型中border的写法,【前端】盒子模型的边框样式属性和应用技巧讲解
  19. 【Win10】资源管理器无法正常启动
  20. 【bzoj3252】攻略

热门文章

  1. 记录一次获取车载摄像头数量为0同时打开摄像头黑屏的问题分析(基于Android M)
  2. [Photography] 测光
  3. centos7 “v篇n“工具
  4. 用MFC实现WebGUI--(CDHtmlDialog)
  5. 支付宝 android sdk 调用h,支付宝 iOS SDK 的简单使用
  6. 中南OJ 2012年8月月赛 I题 Imagination
  7. dpkg制作deb包详解
  8. 流媒体后视镜方案关键技术--调节后视图像显示范围
  9. 1024 程序员节|用代码,改变世界
  10. Word 重复引用同一个脚注