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

环境:VS2017、Office2013、Windows10

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

效果:

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

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

void CExcelAndINIDlg::OnBnClickedBtnRead()

{

  // TODO: 在此添加控件通知处理程序代码

}

 

void CExcelAndINIDlg::OnBnClickedBtnWrite()

{

  // TODO: 在此添加控件通知处理程序代码

}

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类的头文件

#include "CApplication.h"

#include "CWorkbooks.h"

#include "CWorkbook.h"

#include "CWorksheets.h"

#include "CWorksheet.h"

#include "CRange.h"

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

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

    VARIANT _DialogBox()

    {

        VARIANT result;

        InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, nullptr);

        return result;

    }

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

int CExcelAndINIDlg::ReadINIFile()

{

    // TODO: 在此处添加实现代码.

    return 0;

}

 

 

int CExcelAndINIDlg::ReadExcelFile()

{

    // TODO: 在此处添加实现代码.

    return 0;

}

 

int CExcelAndINIDlg::GetWorkDir()

{

    // TODO: 在此处添加实现代码.用于获取程序所在路径

    return 0;

}

8.CExcelAndINIDlg新增如下Public变量

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

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

int CExcelAndINIDlg::GetWorkDir()
{
 // TODO: 在此处添加实现代码.
 TCHAR pFileName[MAX_PATH];
 GetCurrentDirectory(MAX_PATH, pFileName);
 CString dir(pFileName);
 strWorkDir = dir;

 return 0;
}

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

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

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

int CExcelAndINIDlg::ReadExcelFile()
{
 // TODO: 在此处添加实现代码.
 strExcleFilePath = strWorkDir + _T(".\\ExcelTest.xlsx");  //exe所在路径当前路径下的Excel文件
 CApplication app;
 CWorkbooks books;
 CWorkbook book;
 CWorksheets sheets;
 CWorksheet sheet;
 CRange range;
 LPDISPATCH lpDisp;
 COleVariant vResult;
 COleVariant
  covTrue((short)TRUE),
  covFalse((short)FALSE),
  covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
 if (!app.CreateDispatch(_T("Excel.Application")))
 {
  MessageBox(_T("Error!Creat Excel Application Server Faile!"));
  return -1;
 }
 books = app.get_Workbooks();   //获取工作薄集合
 
 lpDisp = books.Open(strExcleFilePath,
  covOptional, covOptional, covOptional, covOptional,
  covOptional, covOptional, covOptional, covOptional,
  covOptional, covOptional, covOptional, covOptional,
  covOptional, covOptional);
 book.AttachDispatch(lpDisp);
 //book = books.Add(covOptional); //获取当前工作薄,若使用此语句,则为新建一个EXCEL表
 sheets = book.get_Worksheets(); //获取当前工作薄页的集合
 sheet = sheets.get_Item(COleVariant((short)1)); //获取当前活动页,第一页sheet1
 //1.获取数据1
 range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1"))); //获取单元格
 vResult = COleVariant(range.get_Value2());
 strExcel1 = CString(vResult.bstrVal);
 //1.获取数据2
 range = sheet.get_Range(COleVariant(_T("B1")), COleVariant(_T("B1"))); //获取单元格
 vResult = COleVariant(range.get_Value2());
 strExcel2 = CString(vResult.bstrVal);
 MessageBox(strExcel1);
 MessageBox(strExcel2);
 //释放各对象,注意其顺序,若不执行以下步骤,Excel进程无法退出,打开任务管理器将会看到残留进程
 range.ReleaseDispatch();
 sheet.ReleaseDispatch();
 sheets.ReleaseDispatch();
 book.ReleaseDispatch(); //释放当前工作薄
 books.ReleaseDispatch(); //释放工作薄集
 app.Quit(); //退出EXCEL程序
 app.ReleaseDispatch(); //释放EXCEL程序
 return 0;
}

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

void CExcelAndINIDlg::OnBnClickedBtnRead()
{
 // TODO: 在此添加控件通知处理程序代码
 GetWorkDir();
 ReadINIFile();
 ReadExcelFile();
 
}

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

void CExcelAndINIDlg::OnBnClickedBtnWrite()
{
 // TODO: 在此添加控件通知处理程序代码
 strOutputExcleFilePath = strWorkDir + _T("\\Result.xlsx");  //指定要写入的文件名及其路径,若存在则覆盖

 CApplication app;
 CWorkbooks books;
 CWorkbook book;
 CWorksheets sheets;
 CWorksheet sheet;
 CRange range;
 COleVariant vResult;
 CString strTemp;
 COleVariant
  covTrue((short)TRUE),
  covFalse((short)FALSE),
  covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
 if (!app.CreateDispatch(_T("Excel.Application")))
 {
  MessageBox(_T("Error!Creat Excel Application Server Faile!"));
  return;
 }

 books = app.get_Workbooks();   //获取工作薄集合

 book = books.Add(covOptional); //获取当前工作薄,若使用此语句,则为新建一个EXCEL表
 sheets = book.get_Worksheets(); //获取当前工作薄页的集合
 sheet = sheets.get_Item(COleVariant((short)1)); //获取当前活动页
 //写入从ini文件中读取的键值
 range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1"))); //获取单元格
 strTemp.Format(_T("%s"), strINI1);//从ini文件中读取到的数据,需要用CString::Format()再次将字符串格式化一下才能正确写入到Excel中
 range.put_Value2(COleVariant(strTemp)); //将内容填入单元格
 range = sheet.get_Range(COleVariant(_T("A2")), COleVariant(_T("A2"))); //获取单元格
 strTemp.Format(_T("%s"), strINI2);
 range.put_Value2(COleVariant(strTemp));
 range = sheet.get_Range(COleVariant(_T("A3")), COleVariant(_T("A3"))); //获取单元格
 strTemp.Format(_T("%s"), strINI3);
 range.put_Value2(COleVariant(strTemp));
 range = sheet.get_Range(COleVariant(_T("A4")), COleVariant(_T("A4"))); //获取单元格
 strTemp.Format(_T("%s"), strINI4);
 range.put_Value2(COleVariant(strTemp));
 //写入从Excle表中读取的数据
 range = sheet.get_Range(COleVariant(_T("A5")), COleVariant(_T("A5"))); //获取单元格
 range.put_Value2(COleVariant(strExcel1));
 range = sheet.get_Range(COleVariant(_T("A6")), COleVariant(_T("A6"))); //获取单元格
 range.put_Value2(COleVariant(strExcel2));

 book.SaveCopyAs(COleVariant(strOutputExcleFilePath));
 book.put_Saved(true);
 app.put_Visible(FALSE); //FALSE表示操作完,不打开工作表,若此处为FALSE,则一定需要调用app.Quit(),以避免程序结束后,还有EXCEL进程

 range.ReleaseDispatch();
 sheet.ReleaseDispatch();
 sheets.ReleaseDispatch();
 book.ReleaseDispatch(); //释放当前工作薄
 books.ReleaseDispatch(); //释放工作薄集
 app.Quit(); //退出EXCEL程序
 app.ReleaseDispatch(); //释放EXCEL程序
 
}
 
 

说明:

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

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

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

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

猜你喜欢

转载自www.cnblogs.com/QSHL/p/10295271.html