您的位置:首页 > 其它

在VS2010中利用MFC读取word、ppt、excel格式文件

2015-07-03 16:28 453 查看
本文源码的应用环境说明:Windows 7,Microsoft Visual Studio 2010,Microsoft
Office Excel 2013
最近自己在做一个利用OLE/COM的实现MFC读取word、excel和ppt格式里面的内容,虽然有关这方面的介绍很多,但是感觉比较杂,比较乱,因此将自己整理加修改的结果写出来,希望能够对以后做这方面格式读取的有帮助。

1、安装office软件。

由于利用的是Office的OLE/COM控件来读取,所以Office是要预先装好

2.导入并封装Word、Excel和PPT中的接口

VS2010导入OLE/COM组件的接口的步骤为:Project->Class
Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,然后再选择要导入的类型库中的接口。在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。



本文所导入的接口对应的类和头文件的说明如下所示:

Word接口

导入类

头文件

_Application

CApplication
CApplication

Documents

CDocuments
CDocuments

_Document

CDocument0
CDocument0

Worksheets

CRange
CRange

Excel接口

导入类

头文件

_Application

CApplication0
CApplication0

Workbooks

CWorkbooks
CWorkbooks

_Workbook

CWorkbook
CWorkbook

Worksheets

CWorksheets
CWorksheets
_Worksheet

CWorksheet
CWorksheet
Range

CRange0
CRange0
ppt接口

导入类

头文件

_Application

CApplication1
CApplication1
Presentations
CPresentations
CPresentations
_Presentation
CPresentation
CPresentation
Slides
CSlides
CSlides
_Slide
CSlide
CSlide
Shapes
CShapes
CShapes
_Shape
CShape
CShape
TextFrame
CTextFrame
CTextFrame
TextRange
CTextRange
CTextRange
3.导入类型库

对每个导入的word头文件中的#import
"E:\\Program Files\\Microsoft Office\\Office15\\MSWORD.OLB" no_namespace、excel头文件中的#import "E:\\Program Files\\Microsoft Office\\Office15\\EXCEL.EXE" no_namespace、ppt中的头文件中的#import "E:\\Program Files\\Microsoft Office\\Office15\\MSPPT.OLB" no_namespace注释掉,目的是防止重复导入,引起编译错误。

对于Excel中的CRange中的DialogBox报错的问题,在前面加下划线即可,即_DialogBox

4.包含对应的头文件,在一个文件中定义变量:

//word
CApplication  wordApp;  

     CDocuments  docs;  

     CDocument0  doc;  

     CRange  wordRange;  
//excel
CApplication0 excelApp;

    CWorkbooks books;

    CWorkbook book;

    CWorksheets sheets;

    CWorksheet sheet;

    CRange0 excelRange;
//ppt
CApplication1  pptApp; 
CPresentations presentations;
CPresentation presentation;
CSlides        slides; 
CSlide        slide;
CShapes shapes;
CShape shape;
CTextFrame textFrame;
CTextRange textRange;

5.操作步骤

这里以excel为例:

操作Excel的主要步骤如下:

(1)创建一个Excel应用程序。

(2)得到Workbook的容器。

(3)打开一个Workbook或者创建一个Workbook。

(4)得到Workbook中的Worksheet的容器。

(5)打开一个Worksheet或者创建一个WorkSheet。

(6)通过Range对WorkSheet中的单元格进行读写操作。

(7)保存Excel。

(8)释放资源。
这里用一个函数来实现读取excel表:
void
ReadExcel(CString filename)

{
LPDISPATCH lpDisp = NULL;
//
COleVariant vResult;
COleVariant

        covTrue((short)TRUE),

        covFalse((short)FALSE),

        vtMissing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);    

 
//打开指定路径文件
CString FileName=filename;
if (!excelApp.CreateDispatch(_T("Excel.Application"),NULL)) {
AfxMessageBox(_T("Excel failed to start!"));
return ;
}
//设置excel表不可见
excelApp.put_Visible(FALSE);

//创建一个文本文件
CFile   file;
file.Open(_T("tmp.txt"),CFile::modeCreate|CFile::modeWrite);
WORD unicode = 0xFEFF;
file.Write(&unicode,2);

try

    {

        //打开一个工作簿
books.AttachDispatch(excelApp.get_Workbooks());

        lpDisp = books.Open(FileName, 

            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,

            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, 

            vtMissing, vtMissing, vtMissing, vtMissing);

        book.AttachDispatch(lpDisp);

//得到Worksheets  
sheets.AttachDispatch(book.get_Worksheets());

//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  
lpDisp=book.get_ActiveSheet();  
sheet.AttachDispatch(lpDisp); 

//得到工作簿中的Sheet的容器
// sheets.AttachDispatch(book.get_Sheets());
 
//读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列
CRange0 usedRange;
usedRange.AttachDispatch(sheet.get_UsedRange());
excelRange.AttachDispatch(usedRange.get_Rows());
long iRowNum=excelRange.get_Count();                   //已经使用的行数

 
excelRange.AttachDispatch(usedRange.get_Columns());
long iColNum=excelRange.get_Count();                   //已经使用的列数

  
long iStartRow=usedRange.get_Row();               //已使用区域的起始行,从1开始
long iStartCol=usedRange.get_Column();            //已使用区域的起始列,从1开始
//
long i,j;
for(i=iStartRow;i<=iRowNum;i++)
for(j=iStartCol;j<=iColNum;j++)
{
//读取第一个单元格的值
excelRange.AttachDispatch(sheet.get_Cells()); 
excelRange.AttachDispatch(excelRange.get_Item(COleVariant((long)i),COleVariant((long)j)).pdispVal );
COleVariant vResult =excelRange.get_Value2();
CString str;
if(vResult.vt == VT_BSTR)       //字符串
{
 str=vResult.bstrVal;
}
else if (vResult.vt==VT_R8)     //8字节的数字 
{
 str.Format(_T("%f"),vResult.dblVal);
}
else 
str="";
//AfxMessageBox(str);
file.Write(str,wcslen(str)*sizeof(wchar_t));
}
}

    catch(...)

    {

       AfxMessageBox(_T("打开文件失败!"));

    }

//关闭文档
file.Flush();
file.Close();

    /*释放资源*/

    sheet.ReleaseDispatch();

    sheets.ReleaseDispatch();

    book.ReleaseDispatch();

    books.ReleaseDispatch();

    excelApp.Quit();

    excelApp.ReleaseDispatch();

//AfxMessageBox(aRange.get_Text());

}

至于word和ppt,操作过程类似,就这只给出操作代码,对于操作步骤的解释,就不赘述了。

void
ReadWord(CString filename)

{
try{
//打开指定路径文件
CString FileName=filename;
if (!wordApp.CreateDispatch(_T("Word.Application"),NULL)) {
AfxMessageBox(_T("Word failed to start!"));
return ;
}
wordApp.put_Visible(FALSE);
docs = wordApp.get_Documents();
COleVariant vTrue((short)TRUE);    
COleVariant vFalse((short)FALSE);
COleVariant vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//COleVariant vFileName(FileName + ".docx");
COleVariant vFileName(FileName);
doc = docs.Open(vFileName,vTrue,vTrue,vTrue,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional,vOptional);
wordRange = doc.Range(vOptional,vOptional);

//创建一个记事本文件
CFile   file;
file.Open(_T("tmp.txt"),CFile::modeCreate|CFile::modeWrite);
WORD unicode = 0xFEFF;
file.Write(&unicode,2);
//AfxMessageBox(wordRange.get_Text());
//将提取的word内容写入文件
CString str=wordRange.get_Text();
file.Write(str,wcslen(str)*sizeof(wchar_t));
//关闭文档
file.Flush();
file.Close();

  //释放资源
doc.ReleaseDispatch();

docs.ReleaseDispatch();
wordApp.ReleaseDispatch();
}catch(...)
{
AfxMessageBox(_T("打开文件失败!"));
}

}

PPT的操作代码:

void
ReadPowerPoint(CString filename)

{
CString strText;
//
if (!pptApp.CreateDispatch(_T("Powerpoint.Application"),NULL)) {
AfxMessageBox(_T("ppt failed to start!"));
return ;
}
//设置不可见
//pptApp.put_Visible(FALSE);
pptApp.put_Visible((long)TRUE);

try
{
//打开文件
presentations = pptApp.get_Presentations();

        presentation = presentations.Open(filename,0,0,1);

// 获取幻灯片数目
int i,j;
slides=presentation.get_Slides();
//
//创建一个文本文件,用来存储提取的结果
CFile   file;
file.Open(_T("tmp.txt"),CFile::modeCreate|CFile::modeWrite);
WORD unicode = 0xFEFF;
file.Write(&unicode,2);
//提取每一页上的文本
for(i = 1; i <=slides.get_Count(); i++) {
slide = slides.Range(COleVariant((long)(i)));
shapes=slide.get_Shapes();
for(j = 0; j < shapes.get_Count(); j ++) {
shape=shapes.Item(COleVariant((long)(j + 1)));
if(shape.get_HasTextFrame()) {
textFrame = shape.get_TextFrame();
textRange = textFrame.get_TextRange();
CString txt = textRange.get_Text();
if(txt.GetLength() > 0) {
//strText += txt;
//写入文本
file.Write(txt,wcslen(txt)*sizeof(wchar_t));
}
}
}
}

//关闭文档
file.Flush();
file.Close();
//AfxMessageBox(strText);
//释放资源
presentation.Close();
pptApp.Quit();

}catch(...)
{
AfxMessageBox(_T("ppt文件打开失败!"));
}

}

至于参考资料,由于离当时查找的时候已经比较久了,所以没能一一列出,抱歉了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息