先列一个特别的.
VC++ 中操作Excel文档的方法,读取,查询,写入,修改,删除
https://blog.csdn.net/CreatedSign/article/details/18811481
VC操作Execl生成execl表格进行打印
有的说:Office的自动化接口是语言独立的。你可以自己把c#示例的代码翻译到C++。
微软的帮助文档:
https://support.microsoft.com/zh-cn/help/196776/office-automation-using-visual-c
根据里面的文档连接比如:
How to use MFC to automate Excel and create and format a new workbook
https://support.microsoft.com/EN-US/help/179706
就可以找到一些微软的例子代码.
186120如何: 使用 MFC 使 Excel 自动运行并填充数组的范围
186122如何: 使用 MFC 使 Excel 自动运行,并获得一系列的数组
179706如何: 使用 MFC 使 Excel 自动运行并创建/格式化一个新工作簿
179494如何: 使用自动化来检索内置文档属性
186898如何: 读取直接与 VC + + 的复合文档属性
184663如何: 嵌入和自动化使用 MFC 的 Microsoft Excel 工作表中
VC编程操作word2010生成表格
https://blog.csdn.net/clever101/article/details/52185032
金山WPS、微软Office EXCEL表格通用C++接口
https://blog.csdn.net/QQ282881515/article/details/40561927
该博文有源码提供下载.看起来是非常健全的例子的.
MFC通过com接口操作Excel
https://blog.csdn.net/HolaMirai/article/details/46365411
该文列出了代码并附有文库具体创建工程来编码实现.值得注意的是这里添加lib的方式是通过注册表.这个实践应会消除我之前看到有不同的App类操作sheet的疑惑了.
https://wenku.baidu.com/view/d7383548767f5acfa1c7cd30
对该文库对应的文件在博客中找到如下:
http://www.cnblogs.com/yaowen/archive/2013/01/22/2870762.html
通过该资料的学习就能打消vc如何编程execl的疑虑,还是很不错的.
在看该资料的时候还看到如下几个文库也值得验看一下.
https://wenku.baidu.com/view/d8ffa2c4d5bbfd0a79567345.html?sxts=1550282546901
https://wenku.baidu.com/view/cbd0b4ea172ded630b1cb61d.html?sxts=1550282543580
https://wenku.baidu.com/view/563e90c7aa00b52acfc7caf4.html?sxts=1550282538733
https://wenku.baidu.com/view/afee201810a6f524ccbf8500.html?rec_flag=default&sxts=1550282670071
https://wenku.baidu.com/view/8dd5e310a2161479171128eb.html?rec_flag=default&sxts=1550282669044
https://wenku.baidu.com/view/1587001dff00bed5b9f31d66.html?rec_flag=default&sxts=1550282667884
https://wenku.baidu.com/view/ed039e3c5727a5e9856a6156.html?rec_flag=default&sxts=1550282666132
有利用模板的可以借鉴,可以用先前的文档进行填充数据就可以了.这样就不用建立了.
本人遇到需要解决数字截断的问题,这个跟格式相关,有以下几篇文章:
【MFC/C++ 操作Excel】将数字格式单元格转为文本格式
https://blog.csdn.net/xxxxxx91116/article/details/8532001
【MFC/C++ 操作Excel】将数字格式单元格转为文本格式
https://blog.csdn.net/xxxxxx91116/article/details/8543424
C++操作EXCEL中的单个CELL,支持读写、设置字体大小、颜色和单元格属性
https://blog.csdn.net/yuer_xiao/article/details/79917367
VC 设置EXCEL单元格的格式 这个文章不错.
https://blog.csdn.net/zhanglidn013/article/details/38900191
VC2010对Excel的操作
https://blog.csdn.net/rexuefengye/article/details/11482713
VS2005 MFC C/C++ 操作excel【网上找了好多列子,都不合适,自己总结一下】
https://blog.csdn.net/wangmeng0804/article/details/65627826
VS2010 C++ 操作Excel表格的编程实现
https://blog.csdn.net/u011135902/article/details/50603133
C++ 控制台读写excel
https://blog.csdn.net/android_lover2014/article/details/52755936
VC中导出Office的类库, 用于操作Office
https://blog.csdn.net/bagboy_taobao_com/article/details/46521555
VC之Office自动化开发(一)
https://blog.csdn.net/sgdgoodboy/article/details/2102628
VC操作word和excel文件,查询与读写[依赖office环境]
https://blog.csdn.net/sudoRoger/article/details/52516897
其他备用内容:
使用c++开发excel插件(第1章 准备知识)
https://blog.csdn.net/cjsycyl/article/details/41518655
VC通过Excel接口 操作Excel的方法
https://blog.csdn.net/wangjieest/article/details/7445414
一、CRange类的Copy函数实现方法
具体步骤:
1.实例化一个CRange类对象range1,关联你要拷贝的区域;
2.实例化一个CRange类对象range2,关联你要将要粘贴到的区域;
3.调用前一个range1对象的Copy函数,就可以把拷贝的内容复制到将要粘贴到的区域了。
典例:(将单元格A1到单元格G16之间区域拷贝到单元格A17到单元格G32之间区域。)
二、CRange类的Delete函数实现方法
具体步骤:
1.实例化一个CRange类对象DelRange,关联你要删除的区域;
2.调用DelRange对象的Delete函数,就可以把将要删除的区域删除了。
典例:(删除单元格A1到单元格G16之间区域。)
---------------------
作者:皓月盈江
来源:CSDN
原文:https://blog.csdn.net/u013541325/article/details/42584667
版权声明:本文为博主原创文章,转载请附上博文链接!
出处:https://blog.csdn.net/ouyangyanlan/article/details/48597951
说到操作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 <afxdisp.h>到上面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 = books.Open(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<count;i++){
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(COleVariant((long)i),COleVariant((long)2)).pdispVal);
vResult = range.get_Value2();
if(vResult.vt == VT_BSTR){
str = vResult.bstrVal;
}else if(vResult.vt == VT_R8){
str.Format(L"%f",vResult.dblVal);
}else{
str = "数据类型错误!";
this->MessageBox(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 = books.Open(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));
}
//book.Save();
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
app.Quit();
app.ReleaseDispatch();
}
1.使用场景:
在不安装Office组件包的情况下,操作Excel文件(.xlsx)。以前做过的好几个项目中,都需要对Excel文件处理,特别是将统计成果按照一定的格式和样式输出到Excel中,或将固定格式的Excel数据导入到系统,这种需求非常常见,以前的做法主要是基于Office组件进行二次开发。但这种做法存在一定的缺陷,(1) 部署比较麻烦,所有的部署机上都必须安装Office。(2)好多新手在使用Office开发时,对自动生成的office组件包装类理解不深,导致在项目移植的过程中引起了很多的问题。
2.EPPlus库的使用:
EPPlus是一个能不依赖于Office而独立读写操作Excel2007/2010的.net类库,主要是操作Excel的xlsx文件。
官方下载地址:http://epplus.codeplex.com/
EPPlus提供的功能包括:
Cell Ranges 单元格范围
Cell Styling 单元格样式,包括:边框、颜色、填充、字体、显示格式(Number)、靠边。
Charts 统计图表
Picture 图片
Shapes
Comments
Tables 表格
Protection 协议
Encryption 加密
Pivot Tables透视表
Conditional Formatting、VBA、Enumeration Of Cell 支持Linq。等。
2.应用实例
注意:在使用之前必须添加两个引用,这两个命名空间都在EPPlus.dll库中。
using OfficeOpenXml;
using OfficeOpenXml.Style;
(1)【写】这是项目中用到的创建一个.xlsx文件,并将统计结果到处到此.xlsx文件中。
/// <summary>
/// 统计信息输出到excel文件中,创建本地缓存。
/// </summary>
/// <param name="singleDataTable">单程</param>
/// <param name="doubleTable">往返</param>
/// <returns>ture,false</returns>
private bool ExportToExcel(DataTable singleDataTable, DataTable doubleTable)
{
ExcelPackage excelPackage = new ExcelPackage();
#region 单程
ExcelWorksheet single_Sheet = excelPackage.Workbook.Worksheets.Add("single_Sheet");
single_Sheet.Name = "单程航班";
single_Sheet.Cells.Style.Font.Size = 9;
single_Sheet.Cells.Style.Font.Name = "微软雅黑";
single_Sheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
int columsCount = singleDataTable.Columns.Count;
int rowIndex = 0;
++rowIndex; //在worksheet中添加新行
for (int i = 0; i < columsCount; i++)
{
single_Sheet.Cells[rowIndex, i + 1].Value = singleDataTable.Columns[i].ColumnName;
single_Sheet.Cells[rowIndex, i + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
single_Sheet.Cells[rowIndex, i + 1].Style.Font.Bold = true;
}
++rowIndex;//excel第一行用来存储表格头,从第二行开始存储数据。
for (int i = 0; i < singleDataTable.Rows.Count; i++)
{
for (int j = 0; j < columsCount; j++)
{
single_Sheet.Cells[rowIndex + i, j + 1].Value = singleDataTable.Rows[i][j].ToString();
}
}
#endregion
#region 往返
ExcelWorksheet double_Sheet = excelPackage.Workbook.Worksheets.Add("double_Sheet");
double_Sheet.Name = "往返航班";
double_Sheet.Cells.Style.Font.Size = 9;
double_Sheet.Cells.Style.Font.Name = "微软雅黑";
double_Sheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
rowIndex = 0;
++rowIndex; //在worksheet中添加新行
for (int i = 0; i < columsCount; i++)
{
double_Sheet.Cells[rowIndex, i + 1].Value = doubleTable.Columns[i].ColumnName;
double_Sheet.Cells[rowIndex, i + 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
double_Sheet.Cells[rowIndex, i + 1].Style.Font.Bold = true;
}
++rowIndex;
for (int i = 0; i < doubleTable.Rows.Count; i++)
{
for (int j = 0; j < columsCount; j++)
{
double_Sheet.Cells[rowIndex + i, j + 1].Value = doubleTable.Rows[i][j].ToString();
}
}
#endregion
#region 输出到执行目录
try
{
this.cacheFileName = string.Format("航线查询明细日报v{0}.xlsx", DateTime.Now.ToString("yyyyMMddHHmmssfff"));
if (Directory.Exists(cacheDirectory) == false)
{
Directory.CreateDirectory(cacheDirectory);
}
string fullpath = cacheDirectory + this.cacheFileName;
FileStream fileStream = new FileStream(fullpath, FileMode.Create);
using (fileStream)
{
byte[] fileBytes = excelPackage.GetAsByteArray();
fileStream.Write(fileBytes, 0, fileBytes.Length);
fileStream.Close();
}
}
catch
{
return false;
}
return true;
#endregion
}
(2) 【读】读取.xslx的文件。
/// <summary>
/// 将统计结果发送到指定邮箱。
/// </summary>
/// <returns></returns>
private bool SendEmail()
{
ExcelPackage excelPackage = new ExcelPackage(new FileInfo(this.cacheDirectory + this.cacheFileName));
string mailMessagaBodyToHtml = ConvertExcelToHtml(excelPackage.Workbook.Worksheets);
string smtpClientHost=@"mail.ly.com";
string networkCredentialName="my08567";
string networkCredentialPassword= @"123qwe!@#";
string fromMailAddress="my08567@ly.com";
string toMailAddress="mymhj@live.com;my08567@live.com;yyy07386@ly.com";
string duplicateMailAddress="mwm07215@ly.com;mymhj@live.com";
string subject="航线查询日报表";
string body=ConvertExcelToHtml(excelPackage.Workbook.Worksheets);
bool isHtml=true;
MemoryStream attachmentSteam= new MemoryStream(excelPackage.GetAsByteArray());;
string attachmentFileName = DateTime.Today.ToString("yyyyMMdd") + "航线查询明细日报.xlsx";
try
{
SendEmailHelper.SendEMailNet(smtpClientHost, networkCredentialName, networkCredentialPassword, fromMailAddress,
toMailAddress, duplicateMailAddress, subject, body, isHtml, attachmentSteam, attachmentFileName);
return true;
}
catch
{
return false;
}
}
在网上搜集的过程中,还发现对Excel文件格式的操作,还有一下几个开源组件可以使用ExcelLibrary,NPOI等。
---------------------
作者:蒙遥
来源:CSDN
原文:https://blog.csdn.net/mymhj/article/details/38387239
版权声明:本文为博主原创文章,转载请附上博文链接!
VC 操作Excel sheet复制、重命名
CApplication ExcelApp;
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CRange range;
LPDISPATCH lpDisp = NULL;
LPDISPATCH lpDisp1 = NULL;
//创建Excel 服务器(启动Excel)
if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
{
AfxMessageBox(_T("启动Excel服务器失败!"));
return ;
}
ExcelApp.put_Visible(TRUE);
ExcelApp.put_UserControl(FALSE);
/*得到工作簿容器*/
books.AttachDispatch(ExcelApp.get_Workbooks());
CString strBookPath = _T("E:\\测试.xls");
try
{
/*打开一个工作簿*/
lpDisp = books.Open(strBookPath,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing);
book.AttachDispatch(lpDisp);
}
catch(...){}
/*得到工作簿中的Sheet的容器*/
sheets.AttachDispatch(book.get_Sheets());
CString strSheetName;
strSheetName = _T("XXXX表");
lpDisp = sheets.get_Item(_variant_t((long)7));
sheet.AttachDispatch(lpDisp);
sheet.Copy(vtMissing,_variant_t(sheet));
//lpDisp = sheets.get_Item(_variant_t("XXXX表(2)"));
//sheet.AttachDispatch(lpDisp);
//sheet.put_Name(_T("改名表"));
/*sheets.*/
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
ExcelApp.Quit();
ExcelApp.ReleaseDispatch();
c++操作excel(CApplication、CWorkbook、CWorksheet、CHyperlinks)代码
原文:https://blog.csdn.net/chanshibing/article/details/86304169
首先创建MFC,打开类向导,添加类(类型库中的MFC类),选择文件位置(EXCEL.exe),添加类需要的类(参考下面代码的头文件),会生成对应的头文件(CWorkbook.h、CHyperlinks.h…)
注释每个生成的头文件中的代码:
//#import "C:\\Program Files\\Microsoft Office\\Office15\\EXCEL.EXE" no_namespace
1
下面代码对excel操作:
#include "msexcel/CBorders.h"
#include "msexcel/CApplication.h"
#include "msexcel/CFont0.h"
#include "msexcel/CRange.h"
#include "msexcel/CWorkbook.h"
#include "msexcel/CWorkbooks.h"
#include "msexcel/CWorksheet.h"
#include "msexcel/CWorksheets.h"
#include "msexcel/CHyperlinks.h"
#include "afxdisp.h"
//参考注释,选取需要的代码
void opExcel(){
//获取当前绝对路径
char buffer[_MAX_PATH];
_getcwd(buffer, _MAX_PATH);
string v[6] = { "A1", "B1", "C1", "D1", "E1", "F1" };
string first_row[6] = { "类别", "坐标X1", "坐标Y1", "坐标X2", "坐标Y2", "类型" };
string head_v[6] = { "A", "B", "C", "D", "E", "F" };
CoInitialize(NULL);//初始化COM,最后还有CoUninitialize
COleVariant vMissing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CApplication app;
CWorkbooks workbooks;
CWorkbook workbook;
CWorksheet worksheet;
CRange range;
CHyperlinks hls;
if (!app.CreateDispatch(_T("EXCEL.application"))) //启动EXCEL
{
AfxMessageBox(_T("居然你连OFFICE都没有安装吗?"));
return;
}
app.put_Visible(FALSE);//是否显示excel
app.put_DisplayFullScreen(FALSE);//设置全屏显示
app.put_DisplayAlerts(FALSE);//屏蔽警告
//打开工作簿
CString strPath;//excel文件名
strPath.Format("%s", filename.c_str());
workbooks = app.get_Workbooks();
try
{
workbook = workbooks.Add(_variant_t(strPath));//打开excel文件
}
catch (CException* e)
{
workbook = workbooks.Add(vtMissing);//找不到就新建一个
}
worksheet = workbook.get_ActiveSheet();//获取当前工作表
//设置excel第一行的值
for (int i = 0; i < 6; i++){
range = worksheet.get_Range(_variant_t(v[i].c_str()), _variant_t(v[i].c_str()));
range.put_Value2(_variant_t(first_row[i].c_str()));//参数是二维数组可以批量设置单元格值
}
//插入数据
for (int i = 0; i < detectAlgorithm.instanceRect_vector.size(); i++)
{
stringstream ss;
ss << (i + 2);
string s1 = ss.str();
//类别
if (detectAlgorithm.instanceRect_vector[i].instanceClass == 1)//电阻
{
range = worksheet.get_Range(_variant_t((head_v[0] + s1).c_str()), _variant_t((head_v[0] + s1).c_str()));
range.put_Value2(_variant_t("电阻"));//参数是二维数组可以批量设置单元格值
}
else if (detectAlgorithm.instanceRect_vector[i].instanceClass == 2)//芯片
{
range = worksheet.get_Range(_variant_t((head_v[0] + s1).c_str()), _variant_t((head_v[0] + s1).c_str()));
range.put_Value2(_variant_t("芯片"));//参数是二维数组可以批量设置单元格值
}
//坐标
range = worksheet.get_Range(_variant_t((head_v[1] + s1).c_str()), _variant_t((head_v[1] + s1).c_str()));
range.put_Value2(_variant_t(detectAlgorithm.instanceRect_vector[i].left_top.x));//参数是二维数组可以批量设置单元格值
range = worksheet.get_Range(_variant_t((head_v[2] + s1).c_str()), _variant_t((head_v[2] + s1).c_str()));
range.put_Value2(_variant_t(detectAlgorithm.instanceRect_vector[i].left_top.y));//参数是二维数组可以批量设置单元格值
range = worksheet.get_Range(_variant_t((head_v[3] + s1).c_str()), _variant_t((head_v[3] + s1).c_str()));
range.put_Value2(_variant_t(detectAlgorithm.instanceRect_vector[i].right_bottom.x));//参数是二维数组可以批量设置单元格值
range = worksheet.get_Range(_variant_t((head_v[4] + s1).c_str()), _variant_t((head_v[4] + s1).c_str()));
range.put_Value2(_variant_t(detectAlgorithm.instanceRect_vector[i].right_bottom.y));//参数是二维数组可以批量设置单元格值
//类型
if (detectAlgorithm.instanceRect_vector[i].instanceWord != "")//如果器件上有数字
{
range = worksheet.get_Range(_variant_t((head_v[5] + s1).c_str()), _variant_t((head_v[5] + s1).c_str()));
range.put_Value2(_variant_t(detectAlgorithm.instanceRect_vector[i].instanceWord.c_str()));//参数是二维数组可以批量设置单元格值
}
else//否则 保存图片并插入图片超链接
{
string outImg_pathName = string(buffer) + "\\images\\" + head_v[5] + s1 + ".jpg";
//切割 并保存图片
Mat outImg = detectAlgorithm.cutRect(detectAlgorithm.detect_src_img, detectAlgorithm.instanceRect_vector[i].left_top, detectAlgorithm.instanceRect_vector[i].right_bottom);
cv::imwrite(outImg_pathName, outImg);
//插入超链接
hls = (worksheet.get_Hyperlinks());//超链接
COleVariant vCell((head_v[5] + s1).c_str());
COleVariant vText("图片");
COleVariant vTip("图片超链接");
hls.Add(worksheet.get_Range(vCell, vMissing), outImg_pathName.c_str(), vMissing, vTip, vText);//添加超链接
}
}
//保存文件
workbook.SaveAs(COleVariant(strPath), covOptional,
covOptional, covOptional,
covOptional, covOptional, (long)0, covOptional, covOptional, covOptional,
covOptional, covOptional);
//释放资源
hls.ReleaseDispatch();
worksheet.ReleaseDispatch();
workbook.ReleaseDispatch();
workbooks.ReleaseDispatch();
range.ReleaseDispatch();
app.Quit();
app.ReleaseDispatch();
CoUninitialize();//对应CoInitialize
}