基于MFC对Office Excel、INI文件的操作

环境:VS2017、Office2013、Windows10

本实例功能:从一个INI文件、一个现有的Office Excel中读取数据,写入到一个新的Excel中

效果:

 

 

1.新建一个基于对话框的MFC程序,本实例项目名为ExcelAndINI,如下

 

2. 新增Read、Write按钮的响应事件,如下

 1 void CExcelAndINIDlg::OnBnClickedBtnRead()
 2 
 3 {
 4 
 5   // TODO: 在此添加控件通知处理程序代码
 6 
 7 }
 8 
 9  
10 void CExcelAndINIDlg::OnBnClickedBtnWrite()
11 
12 {
13 
14   // TODO: 在此添加控件通知处理程序代码
15 
16 }
View Code

 

3. 增加Excel _Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range六个操作类,如下

 

4.在新增的六个OFFICE类的头文件中,做如下动作

//#import "D:\\Program Files\\office\\Office15\\EXCEL.EXE" no_namespace       注释掉此语句

// CRange 包装器类

#pragma once      //增加此语句

 

5.ExcelAndINIDlg.cpp中增加六个OFFICE类的头文件

 1 #include "CApplication.h"
 2 
 3 #include "CWorkbooks.h"
 4 
 5 #include "CWorkbook.h"
 6 
 7 #include "CWorksheets.h"
 8 
 9 #include "CWorksheet.h"
10 
11 #include "CRange.h"
View Code

 

6.此时编译出现如下错误

解决方法:双击此error调到此方法实现处,在此方法名前增加下划线_,重新编译即OK

 1     VARIANT _DialogBox()
 2 
 3     {
 4 
 5         VARIANT result;
 6 
 7         InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, nullptr);
 8 
 9         return result;
10 
11     }
View Code

 

 7.  在CExcelAndINIDlg类中新增三个Public方法

 1 int CExcelAndINIDlg::ReadINIFile()
 2 
 3 {
 4 
 5     // TODO: 在此处添加实现代码.
 6 
 7     return 0;
 8 
 9 }
10 
11  
12 
13 int CExcelAndINIDlg::ReadExcelFile()
14 
15 {
16 
17     // TODO: 在此处添加实现代码.
18 
19     return 0;
20 
21 }
22 
23  
24 
25 int CExcelAndINIDlg::GetWorkDir()
26 
27 {
28 
29     // TODO: 在此处添加实现代码.用于获取程序所在路径
30 
31     return 0;
32 
33 }
View Code

 

8.CExcelAndINIDlg新增如下Public变量

 1  CString strINI1; //读取INI文件内容CString变量1
 2  CString strINI2; //读取INI文件内容CString变量2
 3  CString strINI3; //读取INI文件内容CString变量3
 4  CString strINI4; //读取INI文件内容CString变量4
 5  CString strExcel1; //读取Excel文件内容CString变量1
 6  CString strExcel2; //读取Excel文件内容CString变量2
 7  CString strINIFilePath;   //用于保存数据源INI文件路径
 8  CString strExcleFilePath;  //用于保存数据源Excel文件路径
 9  CString strOutputExcleFilePath;  //用于保存输出Excel文件路径
10  CString strWorkDir;     //用于保存exe所在路径
View Code

 

9.CExcelAndINIDlg::GetWorkDir()方法中增加如下代码

 1 int CExcelAndINIDlg::GetWorkDir()
 2 {
 3  // TODO: 在此处添加实现代码.
 4  TCHAR pFileName[MAX_PATH];
 5  GetCurrentDirectory(MAX_PATH, pFileName);
 6  CString dir(pFileName);
 7  strWorkDir = dir;
 8 
 9  return 0;
10 }
View Code

 

10.CExcelAndINIDlg::ReadINIFile()方法中增加如下代码

 1 int CExcelAndINIDlg::ReadINIFile()
 2 {
 3  // TODO: 在此处添加实现代码.
 4  strINIFilePath = strWorkDir + _T("\\INITest.ini");  //exe所在路径当前路径下的ini文件
 5  GetPrivateProfileString(_T("Section1"), _T("Item1"), _T(""), strINI1.GetBuffer(MAX_PATH), MAX_PATH, strINIFilePath); //读取ini文件中Secton1节点下的Item1键下的键值,若不存在则给strINI1附一个空字符串,strINI最多读取和储存MAX_PATH个字符
 6  GetPrivateProfileString(_T("Section1"), _T("Item2"), _T(""), strINI2.GetBuffer(MAX_PATH), MAX_PATH, strINIFilePath);
 7  GetPrivateProfileString(_T("Section2"), _T("Item1"), _T(""), strINI3.GetBuffer(MAX_PATH), MAX_PATH, strINIFilePath);
 8  GetPrivateProfileString(_T("Section2"), _T("Item2"), _T(""), strINI4.GetBuffer(MAX_PATH), MAX_PATH, strINIFilePath);
 9  return 0;
10 }
View Code

 

11.int CExcelAndINIDlg::ReadExcelFile()方法中增加如下代码

 1 int CExcelAndINIDlg::ReadExcelFile()
 2 {
 3  // TODO: 在此处添加实现代码.
 4  strExcleFilePath = strWorkDir + _T("\\ExcelTest.xlsx");  //exe所在路径当前路径下的Excel文件
 5  CApplication app;
 6  CWorkbooks books;
 7  CWorkbook book;
 8  CWorksheets sheets;
 9  CWorksheet sheet;
10  CRange range;
11  LPDISPATCH lpDisp;
12  COleVariant vResult;
13  COleVariant
14   covTrue((short)TRUE),
15   covFalse((short)FALSE),
16   covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
17  if (!app.CreateDispatch(_T("Excel.Application")))
18  {
19   MessageBox(_T("Error!Creat Excel Application Server Faile!"));
20   return -1;
21  }
22  books = app.get_Workbooks();   //获取工作薄集合
23  
24  lpDisp = books.Open(strExcleFilePath,
25   covOptional, covOptional, covOptional, covOptional,
26   covOptional, covOptional, covOptional, covOptional,
27   covOptional, covOptional, covOptional, covOptional,
28   covOptional, covOptional);
29  book.AttachDispatch(lpDisp);
30  //book = books.Add(covOptional); //获取当前工作薄,若使用此语句,则为新建一个EXCEL表
31  sheets = book.get_Worksheets(); //获取当前工作薄页的集合
32  sheet = sheets.get_Item(COleVariant((short)1)); //获取当前活动页,第一页sheet1
33  
34  //1.获取数据1
35  range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1"))); //获取单元格
36  vResult = COleVariant(range.get_Value2());
37  strExcel1 = CString(vResult.bstrVal);
38  
39  //1.获取数据2
40  range = sheet.get_Range(COleVariant(_T("B1")), COleVariant(_T("B1"))); //获取单元格
41  vResult = COleVariant(range.get_Value2());
42  strExcel2 = CString(vResult.bstrVal);
43  MessageBox(strExcel1);
44  MessageBox(strExcel2);
45  
46  //释放各对象,注意其顺序,若不执行以下步骤,Excel进程无法退出,打开任务管理器将会看到残留进程
47  range.ReleaseDispatch();
48  sheet.ReleaseDispatch();
49  sheets.ReleaseDispatch();
50  book.ReleaseDispatch(); //释放当前工作薄
51  books.ReleaseDispatch(); //释放工作薄集
52  app.Quit(); //退出EXCEL程序
53  app.ReleaseDispatch(); //释放EXCEL程序
54  return 0;
55 }
View Code

 

12.在void CExcelAndINIDlg::OnBnClickedBtnRead()方法中增加如下代码

1 void CExcelAndINIDlg::OnBnClickedBtnRead()
2 {
3  // TODO: 在此添加控件通知处理程序代码
4  GetWorkDir();
5  ReadINIFile();
6  ReadExcelFile();
7  
8 }
View Code

 

13.void CExcelAndINIDlg::OnBnClickedBtnWrite()方法中增加如下代码

 1 void CExcelAndINIDlg::OnBnClickedBtnWrite()
 2 {
 3  // TODO: 在此添加控件通知处理程序代码
 4  strOutputExcleFilePath = strWorkDir + _T("\\Result.xlsx");  //指定要写入的文件名及其路径,若存在则覆盖
 5 
 6  CApplication app;
 7  CWorkbooks books;
 8  CWorkbook book;
 9  CWorksheets sheets;
10  CWorksheet sheet;
11  CRange range;
12  COleVariant vResult;
13  CString strTemp;
14  COleVariant
15   covTrue((short)TRUE),
16   covFalse((short)FALSE),
17   covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
18  if (!app.CreateDispatch(_T("Excel.Application")))
19  {
20   MessageBox(_T("Error!Creat Excel Application Server Faile!"));
21   return;
22  }
23 
24  books = app.get_Workbooks();   //获取工作薄集合
25 
26  book = books.Add(covOptional); //获取当前工作薄,若使用此语句,则为新建一个EXCEL表
27  sheets = book.get_Worksheets(); //获取当前工作薄页的集合
28  sheet = sheets.get_Item(COleVariant((short)1)); //获取当前活动页
29  
30  //写入从ini文件中读取的键值
31  range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1"))); //获取单元格
32  strTemp.Format(_T("%s"), strINI1);//从ini文件中读取到的数据,需要用CString::Format()再次将字符串格式化一下才能正确写入到Excel中
33  range.put_Value2(COleVariant(strTemp)); //将内容填入单元格
34  range = sheet.get_Range(COleVariant(_T("A2")), COleVariant(_T("A2"))); //获取单元格
35  strTemp.Format(_T("%s"), strINI2);
36  range.put_Value2(COleVariant(strTemp));
37  range = sheet.get_Range(COleVariant(_T("A3")), COleVariant(_T("A3"))); //获取单元格
38  strTemp.Format(_T("%s"), strINI3);
39  range.put_Value2(COleVariant(strTemp));
40  range = sheet.get_Range(COleVariant(_T("A4")), COleVariant(_T("A4"))); //获取单元格
41  strTemp.Format(_T("%s"), strINI4);
42  range.put_Value2(COleVariant(strTemp));
43  
44  //写入从Excle表中读取的数据
45  range = sheet.get_Range(COleVariant(_T("A5")), COleVariant(_T("A5"))); //获取单元格
46  range.put_Value2(COleVariant(strExcel1));
47  range = sheet.get_Range(COleVariant(_T("A6")), COleVariant(_T("A6"))); //获取单元格
48  range.put_Value2(COleVariant(strExcel2));
49 
50  book.SaveCopyAs(COleVariant(strOutputExcleFilePath));
51  book.put_Saved(true);
52  app.put_Visible(FALSE); //FALSE表示操作完,不打开工作表,若此处为FALSE,则一定需要调用app.Quit(),以避免程序结束后,还有EXCEL进程
53 
54  range.ReleaseDispatch();
55  sheet.ReleaseDispatch();
56  sheets.ReleaseDispatch();
57  book.ReleaseDispatch(); //释放当前工作薄
58  books.ReleaseDispatch(); //释放工作薄集
59  app.Quit(); //退出EXCEL程序
60  app.ReleaseDispatch(); //释放EXCEL程序
61  
62 }
View Code

 

说明:

1.对于有下拉菜单的Excel表项,其读写方式与普通单元格没有差别。

2.对于合并单元格的读写,可以按照普通单元格读写,如B1、C1为合并单元格,对B1按照普通单元格操作即可。

3.对从ini文件读取的内容写入到Excel表中前,一定要先使用Format方法格式化一下,不然写入到Excel为空。

 

 

实例代码链接:https://pan.baidu.com/s/1nS3t1n4HkkYdGXzJ1nxJNQ     提取码:kkjn

posted @ 2019-01-20 16:20  秋水寒林  阅读(2099)  评论(0编辑  收藏  举报