MFC打开已有的excel文件,并编辑,保存

时间:2022-10-24 00:27:26

MFC打开已有的excel文件,并编辑,保存

问题1.创建excel文件并保存

载入excel API

vs 2010 --》project--》class wizard --》Add Class --》MFC Class From TypeLib --》File  如下图 MFC打开已有的excel文件,并编辑,保存

program file --》Microsoft office --》office14--》Excel.exe 如下图:

MFC打开已有的excel文件,并编辑,保存


在出现的接口列表中,选择_Applicatioin,_Workbook,_Worksheet,Worksheets,Workbooks,Range,让后生成对应的类文件,这些类文件就封装了调用excel的API函数,用通过编译还需要将其中的#import ....内容注释掉,并加上头文件#include <afxdisp.h>,如下图: MFC打开已有的excel文件,并编辑,保存

创建excel文件

如下代码:
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CApplication app;

CRange range;
CRange cols;

COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app.CreateDispatch("Excel.Application"))
{
AfxMessageBox("无法创建excel应用",MB_OK|MB_ICONWARNING);
return;
}
//excel是一个多文档的应用程序,下面的两行确定是哪一个视图
books = app.get_Workbooks();
book = books.Add(covOptional);
//确定视图后得到视图中的全部的页,并确定具体是哪一页
sheets = book.get_Worksheets();
//得到该视图中的第一页
sheet = sheets.get_Item(COleVariant((short)1));
//保存时间
if(m_isSaveTime)
{
range = sheet.get_Range(COleVariant("A1"),COleVariant("A1"));
CTime curTime = CTime::GetCurrentTime();
CString strTime = curTime.Format("%Y-%m-%d %H:%M:%S");
range.put_Value2(COleVariant(strTime));
}
//得到当前编辑页发的A2单元
range = sheet.get_Range(COleVariant("A2"),COleVariant("A2"));
//让数字以字符串显示
result1 = "\'"+result1;
range.put_Value2(COleVariant(result1));
range = sheet.get_Range(COleVariant("A3"),COleVariant("A3"));
range.put_Value2(COleVariant(result2));
//设置整列的宽度自适应
cols = range.get_EntireColumn();
cols.AutoFit();
//保存数据
book.SaveCopyAs(COleVariant(m_saveFilePath));
book.put_Saved(TRUE);
//释放对象
cols.ReleaseDispatch();
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//不能乱序
app.Quit();
app.ReleaseDispatch();

代码中的注释有较详细的说明。

问题2.打开已存在的excel文件,并编辑保存

CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CApplication app;
CRange range;

LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app.CreateDispatch("Excel.Application"))
{
AfxMessageBox("无法打开Excel应用",MB_OK|MB_ICONWARNING);
return;
}
books.AttachDispatch(app.get_Workbooks());
//打开文件
lpDisp = books.Open(m_saveFilePath,covOptional,covOptional,covOptional,covOptional,covOptional
,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,
covOptional,covOptional);
//得到得到视图workbook
book.AttachDispatch(lpDisp);
//得到worksheets
sheets.AttachDispatch(book.get_Worksheets());
//得到sheet
lpDisp = book.get_ActiveSheet();
sheet.AttachDispatch(lpDisp);
//取得用户区
CRange userRange;
userRange.AttachDispatch(sheet.get_UsedRange());
//得到用户区的行数
range.AttachDispatch(userRange.get_Rows());
long rowNum = range.get_Count();
//得到用户区的列数
range.AttachDispatch(userRange.get_Columns());
long colNum = range.get_Count();
//得到用户区的开始行和开始列
long startRow = userRange.get_Row();
long startCol = userRange.get_Column();

long startWriteRow = startRow + rowNum ;
long startWriteCol = startCol + colNum ;

CString writeLocation;
if(m_isSaveTime)
{
CTime curTime = CTime::GetCurrentTime();
CString strTime = curTime.Format("%Y-%m-%d %H:%M:%S");

writeLocation.Format("A%d",startWriteRow+1);
range=sheet.get_Range(COleVariant(writeLocation),COleVariant(writeLocation));
range.put_Value2(COleVariant(strTime));
}
//得到数据的位置
writeLocation.Format("A%d",startWriteRow+2);
//取得要编辑的区域
range = sheet.get_Range(COleVariant(writeLocation),COleVariant(writeLocation));
result1 = "\'" + result1;
//将数据放入取得的区域中
range.put_Value2(COleVariant(result1));

writeLocation.Format("A%d",startWriteRow+3);
range = sheet.get_Range(COleVariant(writeLocation),COleVariant(writeLocation));
range.put_Value2(COleVariant(result2));
//////写入数据的方法二知道行号和列号写数据
//range.AttachDispatch(sheet.get_Cells());
//range.AttachDispatch(range.get_Item(COleVariant((long)2),COleVariant((long)2)).pdispVal);
//range.put_Value2(COleVariant("test"));
//保存修改后的数据
book.Save();
//释放对象
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();

app.Quit();
app.ReleaseDispatch();

主要打开文件的语句是:
lpDisp = books.Open(m_saveFilePath,covOptional,covOptional,covOptional,covOptional,covOptional
,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,
covOptional,covOptional);

在通过AttachDispatch方法来取得具体的视图中的具体页,取得具体的编辑单元有两种方法:

方法1.get_Range方法

通过sheet中的get_Range方法,获得编辑的范围,但是这种方法需要字母与数字组成的位置字符串:
writeLocation.Format("A%d",startWriteRow+1);
range=sheet.get_Range(COleVariant(writeLocation),COleVariant(writeLocation));
range.put_Value2(COleVariant(strTime));

方法2.get_Item方法

通过行号和列号来得到要编辑的单元,具体代码如下:
////写入数据的方法二知道行号和列号写数据
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(COleVariant((long)2),COleVariant((long)2)).pdispVal);
range.put_Value2(COleVariant("test"));

编辑数据好,需要调用CWorkbook中的Save()函数进行保存,如果不保存,在关闭应用的时候会出现是否保存的提示对话框。

问题3.得到用户区

得到用户已经使用的区域,通过下面的代码:
//取得用户区
CRange userRange;
userRange.AttachDispatch(sheet.get_UsedRange());
//得到用户区的行数
range.AttachDispatch(userRange.get_Rows());
long rowNum = range.get_Count();
//得到用户区的列数
range.AttachDispatch(userRange.get_Columns());
long colNum = range.get_Count();
//得到用户区的开始行和开始列
long startRow = userRange.get_Row();
long startCol = userRange.get_Column();
主要是通过CWorksheet中的get_UsedRange()函数实现,得到用户已使用的行数和列数,以及用户开始的行和列,开始行和列都是从1开始计数。

更加详细见:点击打开链接