工作经常遇到的需求之一,将数据保存至Excel中,然后对Excel中的数据进行一系列操作,本篇文章简单记录这个个过程。
本闻主要实现Excel的读写等一些基本操作,依赖于OLE/COM的Excel库实现,需要先对这些接口进行导入。接口主要是_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range、Interior、Cfond 类
部分接口说明如图下:
可以通过注册表或者文件的形式导入,注册表打开如果找不到对应的库,可以选择用文件,用everything全局搜索Excel.exe。在位置处搜索到该exe所在路径即可。
需要导入的接口如下图:
点击添加之后,进入各个头文件中注释掉 “#import "C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE" no_namespace”这句话,VC的特性,不需要再次import。
另外如果出现变量名重定义的话,可以对其做一个修改。具体修改方式可以自行百度,不太重要。
至此接口就添加完毕,include对应的.h之后就可以直接对表格内进行读写操作了。
- // 初始化Excel库
- bool CExcel_TestDlg::InitExcel()
- {
- HRESULT ht;
- ht = ::CoInitialize(NULL);
- if (ht == E_INVALIDARG)
- {
- MessageBox(_T("初始化COM失败"));
- }
-
- //创建Execel(启动Excel)
- if (!m_App.CreateDispatch(_T("Excel.application"), nullptr))
- {
- MessageBox(_T("Error!Creat Excel Application Sever Fail!"));
- exit(1);
- return FALSE;
- }
-
- m_App.put_Visible(FALSE);//是否显示EXCEL
- m_App.put_DisplayFullScreen(FALSE);//设置全屏显示
- m_App.put_DisplayAlerts(FALSE);//屏蔽警告
- return TRUE;
- }
- BOOL CExcel_TestDlg::CreatNewExcel(CString strPath)
- {
- //InitExcel();
-
- m_Books = m_App.get_Workbooks();
-
- try
- {
- m_WorkBook = m_Books.Add(_variant_t(strPath));//打开EXCEL文件
- }
- catch (CException* e)
- {
- m_WorkBook = m_Books.Add(vtMissing);//找不到就新建一个
- }
-
- m_OpenFileName = strPath;
-
- m_WorkSheet = m_WorkBook.get_ActiveSheet();//获取当前工作表
-
-
-
- //保存 定义变量//
- COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
-
- m_WorkBook.SaveAs(COleVariant(strPath),
- covOptional,
- covOptional,
- covOptional,
- covOptional,
- covOptional,
- 0,
- covOptional,
- covOptional,
- covOptional,
- covOptional,
- covOptional,
- covOptional);
- //释放资源 - 演示用,如果需要对其操作,当然是先不用关闭了
- close();
- //关闭应用
- m_App.Quit();
- m_App.ReleaseDispatch();
- m_App = nullptr;
-
- return TRUE;
- }
-
- void CExcel_TestDlg::close(BOOL ifSave /*= FALSE*/)
- {
- COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
- //如果文件已经打开,先关闭文件
- if (!m_OpenFileName.IsEmpty())
- {
- //如果保存,交给用户控制,让用户自己存,如果自己SAVE,会出现莫名的等待
- if (ifSave)
- {
-
- }
- else
- {
- m_WorkBook.Close(COleVariant(short(FALSE)), COleVariant(m_OpenFileName), covOptional);
- m_Books.Close();
- }
- //清空打开文件名称
- m_OpenFileName.Empty();
- }
-
- m_Sheets.ReleaseDispatch();
- m_WorkSheet.ReleaseDispatch();
- m_CurRange.ReleaseDispatch();
- m_WorkBook.ReleaseDispatch();
- m_Books.ReleaseDispatch();
- //m_App.Quit();
- return;
- }
- SYSTEMTIME sys;
- GetLocalTime(&sys);
- CString strFileName;
-
-
- strTmp.Format("%04d%02d%02d", sys.wYear, sys.wMonth, sys.wDay + 100);
- strFileName.Format("%s\\%s.xlsx", sPath, strTmp);
-
-
- CApplication app;
- CWorkbooks books;
- CWorkbook book;
- CWorksheets sheets;
- CWorksheet sheet;
- CRange range;
-
- LPDISPATCH lpDisp = NULL;
- COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
- if (!app.CreateDispatch(_T("Excel.Application")))
- {
- MessageBox(_T("Error!Creat Excel Application Sever Fail!"));
- exit(1);
- }
-
- books.AttachDispatch(app.get_Workbooks());
- //获得所有工作表
- books.AttachDispatch(app.get_Workbooks());
-
- try
- {
- lpDisp = books.Open(strFileName, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);
- }
- catch (CException* e)
- {
- // r如果该路径没有表格则生成一个表格
- CreatNewExcel(strFileName);
- // 再次打开
- lpDisp = books.Open(strFileName, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);
- m_IsNewCreat = TRUE;
- }
-
- book.AttachDispatch(lpDisp);//得到Workbook
- sheets.AttachDispatch(book.get_Worksheets());//得到Worksheets
-
- lpDisp = book.get_ActiveSheet();//得到当前活跃sheet,如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
- sheet.AttachDispatch(lpDisp);
- CString strTemp, strTemp1;
- CString str[] = { _T("时间(时分秒)") ,_T("结果"),"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20" };
- vector
HeadString(str, str + 22) ; -
- for (int i = 0; i < HeadString.size(); ++i)
- {
-
- range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1")));
- range.put_ColumnWidth(_variant_t((long)20)); // 指定区域 设置列宽
-
- COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
-
- range.AttachDispatch(sheet.get_Cells());
- range.AttachDispatch(range.get_Item(COleVariant((long)nRow), COleVariant((long)nCol)).pdispVal);
-
- // 给单元格写入值
- range.put_Value(covOptional, _variant_t(strValue));
-
- // 给单元格设置字体格式
- CFont0 ft;
- ft.AttachDispatch(range.get_Font());
- ft.put_Name(_variant_t(_T("宋体")));
- ft.put_Size(_variant_t(8));
- ft.put_Color(_variant_t(RGB(255, 0, 0)));
-
- // 给单元格设置底色
- interior.AttachDispatch(range.get_Interior());
- //将底色改为红色 44-对应浅黄色 具体数值对应颜色看这个链接 https://msdn.microsoft.com/en-us/library/cc296089.aspx
- interior.put_ColorIndex(_variant_t((long)44));
-
- }
- int rows,cols; // 整数型行列,以获取指定单元格
- rows = 1;
- cols = 1;
- range.AttachDispatch(range.get_Item(COleVariant((long)rows), COleVariant((long)cols)).pdispVal);
- COleVariant vResult;
- vResult = range.get_Value2();
- CString data;
- if (vResult.vt == VT_BSTR) //字符串
- {
- data = vResult.bstrVal;
- }
- else if (vResult.vt == VT_R8) //8字节的数字
- {
- data.Format("%.0f", vResult.dblVal);
- }
- else if(vResult.vt==VT_EMPTY) //单元格空的
- {
- data = "";
- }
- CRange UseRange1;
- UseRange1.AttachDispatch(sheet.get_UsedRange(), true);
- range.AttachDispatch(UseRange1.get_Rows(), true);
- //设置合并单元格的文字的对齐方式【水平垂直居中、竖直垂直居中】
- //水平对齐:默认=1,居中=-4108,左=-4131,右=-4152
- //垂直对齐:默认=2,居中=-4108,左=-4160,右=-4107
- UseRange1.put_HorizontalAlignment(_variant_t((long)-4108));
- UseRange1.put_VerticalAlignment(_variant_t((long)-4108));
- UseRange1.ReleaseDispatch();
- book.Save();
-
- books.Close();
- range.ReleaseDispatch();
- sheet.ReleaseDispatch();
- sheets.ReleaseDispatch();
- book.ReleaseDispatch();
- books.ReleaseDispatch();
- app.ReleaseDispatch();
- app.Quit();
至此就结束了excel的基本操作,其他的基本都是先找到单元格的位置,然后调用各自的接口进行想要的操作。接口不清楚只能去网上或者微软官网去查了。
Workbook 对象 (Excel) | Microsoft Docs
源码传送门: