C++读写Excel的实现方法详解
更新时间:2020年4月25日 17:47 点击:2115
1.导入Excel类型库
使用Visual C++的扩展指令#import导入Excel类型库:
#import "C:\\Program Files\\Common Files\\microsoft shared\\OFFICE14\\MSO.DLL" \
rename("RGB","MsoRGB") \
rename("SearchPath","MsoSearchPath")
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
#import "C:\\Program Files\\Microsoft Office\\Office14\\EXCEL.EXE" \
rename( "DialogBox", "ExcelDialogBox" ) \
rename( "RGB", "ExcelRGB" ) \
rename( "CopyFile", "ExcelCopyFile" ) \
rename( "ReplaceText", "ExcelReplaceText" ) \
exclude( "IFont", "IPicture" ) no_dual_interfaces
#import指令会从指定的可执行文件,动态链接库等COM组件中导出类型库(type lib),在Debug和Release临时目录中生成对应的类型库头文件(type lib header file),以供C++程序使用。如以上三条指令在编译后会生成excel.tlh, mso.lh和vbetext.olb三个头文件,可以在Debug和Release目录中找到。
2.访问Excel暴露的COM对象
下面是一段比较完整的访问Excel的实例代码。首先用生成的数据填充单元格,然后用这些单元格的数据生成了一个图表(Chart):
try
{
Excel::_ApplicationPtr pExcelApp;
HRESULT hr = pExcelApp.CreateInstance(L"Excel.Application");
ATLASSERT(SUCCEEDED(hr));
pExcelApp->Visible = true; // make Excel's main window visible
Excel::_WorkbookPtr pWorkbook = pExcelApp->Workbooks->Open(lpszPathName); // open excel file
Excel::_WorksheetPtr pWorksheet = pWorkbook->ActiveSheet;
pWorksheet->Name = L"Chart Data";
Excel::RangePtr pRange = pWorksheet->Cells;
const int nplot = 100;
const double xlow = 0.0, xhigh = 20.0;
double h = (xhigh-xlow)/(double)nplot;
pRange->Item[1][1] = L"x"; // read/write cell's data
pRange->Item[1][2] = L"f(x)";
for (int i=0;i<nplot;++i)
{
double x = xlow+i*h;
pRange->Item[i+2][1] = x;
pRange->Item[i+2][2] = sin(x)*exp(-x);
}
Excel::RangePtr pBeginRange = pRange->Item[1][1];
Excel::RangePtr pEndRange = pRange->Item[nplot+1][2];
Excel::RangePtr pTotalRange =
pWorksheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange];
Excel::_ChartPtr pChart = pExcelApp->ActiveWorkbook->Charts->Add();
// refer to :
// http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.chart.chartwizard(v=vs.80).aspx
pChart->ChartWizard(
(Excel::Range*)pTotalRange,
(long)Excel::xlXYScatter,
6L,
(long)Excel::xlColumns,
1L,1L,
true,
L"My Graph",
L"x",L"f(x)");
pChart->Name = L"My Data Plot";
pWorkbook->Close(VARIANT_TRUE); // save changes
pExcelApp->Quit();
}
catch (_com_error& error)
{
ATLASSERT(FALSE);
ATLTRACE2(error.ErrorMessage());
}
在这段代码中,Excel::_ApplicationPtr , Excel::_WorkbookPtr 和 Excel::_WorksheetPtr 等均是Visual C++ 编译器根据#import指令自动生成的智能指针,实际上就是C++模板类_com_ptr_t<T>的typedef,其定义可在excel.tlh等类型库头文件中找到。
另外,由于#import指令中没有指定raw_interface_only修饰符,Visual C++对Excel的COM接口进行了适当的封装,以简化COM接口属性和方法的调用,并且将HRESULT返回值都转换成了C++异常,因此,上面的这段代码不需要每一步都坚持HRESULT,而是改为捕获C++异常。
使用Visual C++的扩展指令#import导入Excel类型库:
复制代码 代码如下:
#import "C:\\Program Files\\Common Files\\microsoft shared\\OFFICE14\\MSO.DLL" \
rename("RGB","MsoRGB") \
rename("SearchPath","MsoSearchPath")
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
#import "C:\\Program Files\\Microsoft Office\\Office14\\EXCEL.EXE" \
rename( "DialogBox", "ExcelDialogBox" ) \
rename( "RGB", "ExcelRGB" ) \
rename( "CopyFile", "ExcelCopyFile" ) \
rename( "ReplaceText", "ExcelReplaceText" ) \
exclude( "IFont", "IPicture" ) no_dual_interfaces
#import指令会从指定的可执行文件,动态链接库等COM组件中导出类型库(type lib),在Debug和Release临时目录中生成对应的类型库头文件(type lib header file),以供C++程序使用。如以上三条指令在编译后会生成excel.tlh, mso.lh和vbetext.olb三个头文件,可以在Debug和Release目录中找到。
2.访问Excel暴露的COM对象
下面是一段比较完整的访问Excel的实例代码。首先用生成的数据填充单元格,然后用这些单元格的数据生成了一个图表(Chart):
复制代码 代码如下:
try
{
Excel::_ApplicationPtr pExcelApp;
HRESULT hr = pExcelApp.CreateInstance(L"Excel.Application");
ATLASSERT(SUCCEEDED(hr));
pExcelApp->Visible = true; // make Excel's main window visible
Excel::_WorkbookPtr pWorkbook = pExcelApp->Workbooks->Open(lpszPathName); // open excel file
Excel::_WorksheetPtr pWorksheet = pWorkbook->ActiveSheet;
pWorksheet->Name = L"Chart Data";
Excel::RangePtr pRange = pWorksheet->Cells;
const int nplot = 100;
const double xlow = 0.0, xhigh = 20.0;
double h = (xhigh-xlow)/(double)nplot;
pRange->Item[1][1] = L"x"; // read/write cell's data
pRange->Item[1][2] = L"f(x)";
for (int i=0;i<nplot;++i)
{
double x = xlow+i*h;
pRange->Item[i+2][1] = x;
pRange->Item[i+2][2] = sin(x)*exp(-x);
}
Excel::RangePtr pBeginRange = pRange->Item[1][1];
Excel::RangePtr pEndRange = pRange->Item[nplot+1][2];
Excel::RangePtr pTotalRange =
pWorksheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange];
Excel::_ChartPtr pChart = pExcelApp->ActiveWorkbook->Charts->Add();
// refer to :
// http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.chart.chartwizard(v=vs.80).aspx
pChart->ChartWizard(
(Excel::Range*)pTotalRange,
(long)Excel::xlXYScatter,
6L,
(long)Excel::xlColumns,
1L,1L,
true,
L"My Graph",
L"x",L"f(x)");
pChart->Name = L"My Data Plot";
pWorkbook->Close(VARIANT_TRUE); // save changes
pExcelApp->Quit();
}
catch (_com_error& error)
{
ATLASSERT(FALSE);
ATLTRACE2(error.ErrorMessage());
}
在这段代码中,Excel::_ApplicationPtr , Excel::_WorkbookPtr 和 Excel::_WorksheetPtr 等均是Visual C++ 编译器根据#import指令自动生成的智能指针,实际上就是C++模板类_com_ptr_t<T>的typedef,其定义可在excel.tlh等类型库头文件中找到。
另外,由于#import指令中没有指定raw_interface_only修饰符,Visual C++对Excel的COM接口进行了适当的封装,以简化COM接口属性和方法的调用,并且将HRESULT返回值都转换成了C++异常,因此,上面的这段代码不需要每一步都坚持HRESULT,而是改为捕获C++异常。
相关文章
- vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
- 这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- 整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
- 这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
- 这篇文章主要介绍了c#读取excel方法,实例分析了C#读取excel文件的原理与相关技巧,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 这篇文章主要介绍了Python导入数值型Excel数据并生成矩阵操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-09
- 该例子使用 BinaryStream 和 BinaryWriter 对二进制文件进行读写操作先上代码再根据我理解的所分享给各位朋友...2020-06-25
- 这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
- 本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
- 下面小编就为大家带来一篇C# winform打开Excel文档的方法总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
- C# 导出 Excel 的6种简单方法:数据表导出到 Excel,对象集合导出到 Excel,数据库导出到 Excel,微软网格控件导出到 Excel,数组导出到 Excel,CSV 导出到 Excel,你都会了吗?需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要介绍了C++ pair的用法实例详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了VSCode C++多文件编译的简单使用方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
- 虽然C++11引入了智能指针的,但是开发人员在与内存的斗争问题上并没有解放,如果我门实用不当仍然有内存泄漏问题,其中智能指针的循环引用缺陷是最大的问题。下面通过实例代码给大家介绍c++中的循环引用,一起看看吧...2020-04-25