在MFC中使用自动化接口操作WORD

来源:互联网 发布:java网页游戏开发 编辑:程序博客网 时间:2024/05/22 13:59

原文:怎么用VC读取Word文本框中的内容(http://www.cnitblog.com/lifw/articles/vcpp_officeword.html)

感恩这位热心的编程高手已经为我们做好了不少工作,让我可以省了不不少的工作.如果让我自己重新来做,像我的速度,又要花掉好几天.建立一个MFC基本Dialog的工期,通过类向导对话框将库MSWORD.OLB加自来,选中所有可以自动生成的类对象,确定之后将生成msword.h,msword.cpp这样,我们操作word就很方便了.现在我对原来的工程完善了一下,主要实现了:

(1)可以增加数据表格;

(2)可以读取书签附近带有下划线的所有字符;

(3)可以设置字体的大小,文本是否居中等.

下面这张图片就是通过程序,简单输出的一个word文档.

 

 

/* CWordOffice.h */

 

#ifndef WORDOFFICE_INCLUDE_H
#define WORDOFFICE_INCLUDE_H
//文字对齐方式
enum TEXT_ALIGNMENT
{
 ALIGN_LEFT = 0,   //水平居左
 ALIGN_MIDDLE = 1,
 ALIGN_RIGHT = 2
};

//文字读取起点类型
enum TEXT_READ_START_TYPE
{
 READ_START_ABS = 0, //绝对位置
    READ_START_MARK = 1,  //通过书签
};

//读取文本考虑的属性类型
enum TEXT_READ_FONT_TYPE
{
    READ_USE_UNDERLINED = 0, //读取考虑是否带有下划线的
    READ_USE_BOLD,   //读取考虑是否加粗的
 READ_USE_ITALIC, //读取考虑是否倾斜的
 READ_USE_FONTSIZE, //读取考虑固定大小的
};

//读取文本格式
typedef  struct
{
 bool bUnderLine; //是否带有下划线
 bool bBold; //是否加粗的
 bool bItalic; //是否倾斜的
    float fixedSize; //固定尺寸
}FONT_TYPE;

//文本读取参数
typedef struct
{
 TEXT_READ_START_TYPE readStartType; //起点读取类型
 /*readStartType =READ_START_ABS */
 long start;       //读取的绝对位置
    /*readStartType =READ_START_MARK */
 char *bookMark;   //读取的书签位置
 
 FONT_TYPE fontType;   //读取文本格式
 TEXT_READ_FONT_TYPE    *readFontTypes;// 读取文本要考虑的属性列表
 int ftReadTypeSize; //读取文本要考虑的属性列表长度
 int ftSearchWidth; //如果开始位置的字体格式不符合要求,向右搜索可能符合的字体的最大宽度

 bool bReadFixedLen; //是否读取固定长度的
 long fixedLength;   //读取固定长度

 bool bReadFinishedStr; //是否读到固定字符串结束
 char *finishedStr;     //读到此结束字符串为止
 long failMaxLength;    //结束字符串不存在时读取的最大长度
}WORD_TEXT_READ_ARGU;


//文字写入起点类型
enum TEXT_WRITE_START_TYPE
{
  WRITE_START_ABS = 0, //指定绝对位置
     WRITE_START_MARK = 1,  //通过书签指定位置
};

//文本写入参数
typedef struct
{
 char *text;  //写入的文本
 TEXT_WRITE_START_TYPE writeStartType; //文字写入起点类型
 /*writeStartType =WRITE_START_ABS */
 long start;       //读取的绝对位置
    /*writeStartType =WRITE_START_MARK */
 char *bookMark;   //读取的书签位置

 bool bUnderline; //是否带下划线
 bool bBold;//是否加粗
 bool bItalic;//是否倾斜
    bool bSetFixedSize; //是否设定字号
 float fixedSize; //字体尺寸
 bool bReWrited; //已经有文字时是否重新写入
 bool bDeleteOlds; //重新写入时是否删除原来的内容
}WORD_TEXT_WRITE_ARGU;


class CWordOffice
{
private:
    _Application m_wdApp;
    Documents m_wdDocs;
    _Document m_wdDoc;
    Selection m_wdSel;
    Range     m_wdRange;
    InlineShapes m_wdInlineShapes;
    InlineShape m_wdInlineShape;

public:
    CWordOffice();
    virtual ~CWordOffice();

public:
    //操作
    //**********************创建新文档*******************************************
    BOOL CreateApp();                    //创建一个新的WORD应用程序
    BOOL CreateDocuments();                //创建一个新的Word文档集合
    BOOL CreateDocument();                //创建一个新的Word文档
    BOOL Create();                        //创建新的WORD应用程序并创建一个新的文档
    void ShowApp();                        //显示WORD文档
    void HideApp();                        //隐藏word文档

    //**********************打开文档*********************************************
    BOOL OpenDocument(CString fileName);//打开已经存在的文档。
    BOOL Open(CString fileName);        //创建新的WORD应用程序并打开一个已经存在的文档。
    BOOL SetActiveDocument(short i);    //设置当前激活的文档。

    //**********************保存文档*********************************************
    BOOL SaveDocument();                //文档是以打开形式,保存。
    BOOL SaveDocumentAs(CString fileName);//文档以创建形式,保存。
    BOOL CloseDocument();
    void CloseApp();


    //**********************文本书写操作*****************************************
 void WriteText(CString szText,const WORD_TEXT_WRITE_ARGU &argu); //在当前光标或指定位置处写文本,可指定字号
 void WriteText(CString szText,long start=-1, float fontSize=-1);
 //! 读取文本
 CString GetText(const WORD_TEXT_READ_ARGU &argu,long &totalWidth);
 //! 根据起始,截止位置读取文本
    CString GetText(long start, long end);
 //! 读取当前位置所在表格单元格的文本
    CString GetCellText(long start);
 void SetFontSize(float fontSize); //设置字体大小
    float GetFontSize();//获取字体大小
    void SetFontUnderline(long value);//设置字体是否带有下划线
 long GetFontUnderline();//获取字体是否带有下划线
 void SetTextAlignment(TEXT_ALIGNMENT align); //设置当前位置的文字对齐方式
    void WriteNewLineText(CString szText, int nLineCount = 1); //换N行写字
    void WriteEndLine(CString szText);    //文档结尾处写文本

    void WholeStory();                    //全选文档内容
    void Copy();                        //复制文本内容到剪贴板
    void InsertFile(CString fileName);    //将本地的文件全部内容写入到当前文档的光标处。
   
    //**********************图片插入操作*****************************************
    void InsertShapes(CString fileName);//在当前光标的位置插入图片
   
    //**********************超链接插入操作*****************************************
    void InsertHyperlink(CString fileLink);//超级链接地址,可以是相对路径。


  //**********************当前光标移动操作*****************************************
 //! Moves the start position of the specified range or selection. This method returns an integer that indicates the number of units by which the start position or the range or selection actually moved, or it returns 0 (zero) if the move was unsuccessful.
    long MoveStart(long unit, long count);
    //! Moves the selection to the right and returns the number of units it's been moved.
    long MoveRight(long unit, long count, long extend);
    //! Moves the selection to the left and returns the number of units it's been moved.
    long MoveLeft(long unit, long count, long extend);
 long Delete(long unit, long count);
 long MoveUp(long unit, long count, long extend);
 long MoveDown(long unit, long count, long extend);

 //**********************表格处理*****************************************
 //! 根据某一表格中,某一行列上的单元格内容
    CString GetTableCellText(long tableIndex, long row, long col);
 //! 在某一表格中,某一行列上的单元格中写入内容
    void WriteTableCellText(long tableIndex, long row, long col, CString szText);
 //! 读取某一表格中所有单元格的内容,结果放在数组strArray中
    bool GetTableCellsText(long tableIndex, CString strArray[]);
 //!建立表格,可指定位置
 void CreateTable(long rowCount, long colCount,long start=-1);

 //**********************测试*****************************************
 //! 测试所有表格的文本
    void TestTablesText();
 //! 建立一个测试文档
 bool TestCreateDoc(CString fileName);
protected:
 //**********************书签处理*********************************************
 //! 查找书签位置
 long __GetMarkPosition(CString bookMark);

    //检查字体是否符合格式
 bool __isFontValid(TEXT_READ_FONT_TYPE *fontTypes, int ftTypeSize, const FONT_TYPE &fontType,  _Font &ft);
 //!读取以固定字符串结尾的文本
    CString  __GetTextWithEndStr(long start, const char *finishedStr,long failMaxLength, long& totalWidth);

 //! 从此处开始读取所有带有下划线的文本
 // start 开始位置
 // searchWidth 如果开始位置的文本不带有下划线,向右搜索可能带有下划线文本的最大宽度
 CString __GetUnderlineText(long start, long searchWidth, long &length);
 //! 读取固定长度文本
 CString  __GetFixedLenText(long start, long fixedLength);
};
#endif


 

/* CWordOffice.cpp */

#include "stdAfx.h"
#include "CWordOffice.h"
#include  <atlbase.h>
#include  <cmath>

CWordOffice::CWordOffice()
{

}

CWordOffice::~CWordOffice()
{
    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    //m_wdDoc.Save();
    m_wdApp.Quit(vFalse,    // SaveChanges.
             vTrue,            // OriginalFormat.
             vFalse            // RouteDocument.
             );
    //释放内存申请资源
    m_wdInlineShape.ReleaseDispatch();
    m_wdInlineShapes.ReleaseDispatch();
    //m_wdTb.ReleaseDispatch();
    m_wdRange.ReleaseDispatch();
    m_wdSel.ReleaseDispatch();
    //m_wdFt.ReleaseDispatch();
    m_wdDoc.ReleaseDispatch();
    m_wdDocs.ReleaseDispatch();
    m_wdApp.ReleaseDispatch();
}

//操作
BOOL CWordOffice::CreateApp()
{
    if (FALSE == m_wdApp.CreateDispatch("Word.Application"))
    {
        AfxMessageBox("Application创建失败,请确保安装了word 2000或以上版本!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    return TRUE;
}

BOOL CWordOffice::CreateDocuments()
{
    if (FALSE == CreateApp())
    {
        return FALSE;
    }
    m_wdDocs.AttachDispatch(m_wdApp.GetDocuments());
    if (!m_wdDocs.m_lpDispatch)
    {
        AfxMessageBox("Documents创建失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    return TRUE;
}

BOOL CWordOffice::CreateDocument()
{
    if (!m_wdDocs.m_lpDispatch)
    {
        AfxMessageBox("Documents为空!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }

    COleVariant varTrue(short(1),VT_BOOL),vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    CComVariant Template(_T(""));    //没有使用WORD的文档模板
    CComVariant NewTemplate(false),DocumentType(0),Visible;

    m_wdDocs.Add(&Template,&NewTemplate,&DocumentType,&Visible);   

    //得到document变量
    m_wdDoc = m_wdApp.GetActiveDocument();
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到selection变量
    m_wdSel = m_wdApp.GetSelection();
    if (!m_wdSel.m_lpDispatch)
    {
        AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到Range变量
    m_wdRange = m_wdDoc.Range(vOptional,vOptional);
    if(!m_wdRange.m_lpDispatch)
    {
        AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }

    return TRUE;
}

BOOL CWordOffice::Create()
{
    if (FALSE == CreateDocuments())
    {
        return FALSE;
    }
    return CreateDocument();
}

void CWordOffice::ShowApp()
{
    m_wdApp.SetVisible(TRUE);
}

void CWordOffice::HideApp()
{
    m_wdApp.SetVisible(FALSE);
}

BOOL CWordOffice::OpenDocument(CString fileName)
{
    if (!m_wdDocs.m_lpDispatch)
    {
        AfxMessageBox("Documents为空!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }

    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
                vZ((short)0);
    COleVariant     vFileName(_T(fileName));
   
    //得到document变量
    m_wdDoc.AttachDispatch(m_wdDocs.Open(
                                vFileName,        // FileName
                                vTrue,            // Confirm Conversion.
                                vFalse,            // ReadOnly.
                                vFalse,            // AddToRecentFiles.
                                vOptional,        // PasswordDocument.
                                vOptional,        // PasswordTemplate.
                                vOptional,        // Revert.
                                vOptional,        // WritePasswordDocument.
                                vOptional,        // WritePasswordTemplate.
                                vOptional,        // Format. // Last argument for Word 97
                                vOptional,        // Encoding // New for Word 2000/2002
                                vOptional,        // Visible
                                //*如下4个是word2003需要的参数。
                                vOptional,    // OpenAndRepair
                                vZ,            // DocumentDirection wdDocumentDirection LeftToRight
                                vOptional,    // NoEncodingDialog
                                vOptional
                                )                // Close Open parameters
                            );                    // Close AttachDispatch
   
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到selection变量
    m_wdSel = m_wdApp.GetSelection();
    if (!m_wdSel.m_lpDispatch)
    {
        AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到全部DOC的Range变量
    m_wdRange = m_wdDoc.Range(vOptional,vOptional);
    if(!m_wdRange.m_lpDispatch)
    {
        AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    return TRUE;
}

BOOL CWordOffice::Open(CString fileName)
{
    if (FALSE == CreateDocuments())
    {
        return FALSE;
    }
    return OpenDocument(fileName);
}

BOOL CWordOffice::SetActiveDocument(short i)
{
    COleVariant     vIndex(_T(i)),vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

    m_wdDoc.AttachDispatch(m_wdDocs.Item(vIndex));
    m_wdDoc.Activate();
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到selection变量
    m_wdSel = m_wdApp.GetSelection();
    if (!m_wdSel.m_lpDispatch)
    {
        AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到全部DOC的Range变量
    m_wdRange = m_wdDoc.Range(vOptional,vOptional);
    if(!m_wdRange.m_lpDispatch)
    {
        AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    HideApp();
    return TRUE;
}

BOOL CWordOffice::SaveDocument()
{
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    m_wdDoc.Save();
    return TRUE;
}

BOOL CWordOffice::SaveDocumentAs(CString fileName)
{
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    COleVariant vFileName(_T(fileName));
 m_wdDoc.SaveAs(
                vFileName,    //VARIANT* FileName
                vOptional,    //VARIANT* FileFormat
                vOptional,    //VARIANT* LockComments
                vOptional,    //VARIANT* Password
                vOptional,    //VARIANT* AddToRecentFiles
                vOptional,    //VARIANT* WritePassword
                vOptional,    //VARIANT* ReadOnlyRecommended
                vOptional,    //VARIANT* EmbedTrueTypeFonts
                vOptional,    //VARIANT* SaveNativePictureFormat
                vOptional,    //VARIANT* SaveFormsData
                vOptional,    //VARIANT* SaveAsAOCELetter
    vOptional,
    vOptional,
    vOptional,
    vOptional,
    vOptional
                );
    return    TRUE;
}

BOOL CWordOffice::CloseDocument()
{
    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    m_wdDoc.Close(vFalse,    // SaveChanges.
             vTrue,            // OriginalFormat.
             vFalse            // RouteDocument.
             );

 //如果当前已经没有激活的文档,则调用m_wdApp.GetActiveDocument()会出现异常
    m_wdDoc.AttachDispatch(m_wdApp.GetActiveDocument());
  AfxMessageBox("GetActiveDocument2 ", MB_OK|MB_ICONWARNING);
    if (!m_wdDoc.m_lpDispatch)
    {
        AfxMessageBox("Document获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到selection变量
    m_wdSel = m_wdApp.GetSelection();
    if (!m_wdSel.m_lpDispatch)
    {
        AfxMessageBox("Select获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
    //得到全部DOC的Range变量
    m_wdRange = m_wdDoc.Range(vOptional,vOptional);
    if(!m_wdRange.m_lpDispatch)
    {
        AfxMessageBox("Range获取失败!", MB_OK|MB_ICONWARNING);
        return FALSE;
    }
 AfxMessageBox("close Document success", MB_OK|MB_ICONWARNING);
    return TRUE;
}

void CWordOffice::CloseApp()
{
    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    m_wdDoc.Save();
    m_wdApp.Quit(vFalse,    // SaveChanges.
             vTrue,            // OriginalFormat.
             vFalse            // RouteDocument.
             );
    //释放内存申请资源
    m_wdInlineShape.ReleaseDispatch();
    m_wdInlineShapes.ReleaseDispatch();
    //m_wdTb.ReleaseDispatch();
    m_wdRange.ReleaseDispatch();
    m_wdSel.ReleaseDispatch();
    //m_wdFt.ReleaseDispatch();
    m_wdDoc.ReleaseDispatch();
    m_wdDocs.ReleaseDispatch();
    m_wdApp.ReleaseDispatch();
}

void CWordOffice::WriteText(CString szText, long start, float fontSize)
{
    if(-1 != start)//有指定写入位置
    {
        m_wdSel.SetStart(start);
    }
    if(-1 != fontSize)//有指定字号
    {
  _Font ft = m_wdSel.GetFont();
  ft.SetSize(fontSize);
    }
    m_wdSel.TypeText(szText);
}

void CWordOffice::WriteText(CString szText, const WORD_TEXT_WRITE_ARGU &argu)
{
 long start = 0;
    if(WRITE_START_ABS == argu.writeStartType)//指定绝对位置
 {
  start = argu.start;
 }
 else if(WRITE_START_MARK == argu.writeStartType)//通过书签指定位置
 {
  start = __GetMarkPosition(argu.bookMark);
 }
 else;

 long totalWidth = 0;
 CString oldText;

 //构造读取参数,读取在此位置已经写入的文字信息
 WORD_TEXT_READ_ARGU readArgu;
 readArgu.readStartType = READ_START_ABS;
    readArgu.start = start;
 TEXT_READ_FONT_TYPE  readFontTypes[4];
 int count = 0;
 if(argu.bUnderline)
 {
  readFontTypes[count++] = READ_USE_UNDERLINED;
  readArgu.fontType.bUnderLine = true;
 } 
 if(argu.bBold)
 {
  readFontTypes[count++] = READ_USE_BOLD;
  readArgu.fontType.bBold = true;
 }
 if(argu.bItalic)
 {
  readFontTypes[count++] = READ_USE_ITALIC;
  readArgu.fontType.bItalic = true;
 }
 if(argu.bSetFixedSize)
 {
  readFontTypes[count++] = READ_USE_FONTSIZE;
  readArgu.fontType.fixedSize = argu.fixedSize;
 }
    //读取已经写入的文字
 readArgu.readFontTypes = readFontTypes;
 readArgu.ftSearchWidth = 5;
 readArgu.ftReadTypeSize = count;
 readArgu.bReadFixedLen = false;
 readArgu.bReadFinishedStr = false;
 //
 oldText = GetText(readArgu, totalWidth);
    //AfxMessageBox("已经存在文本:"+oldText, MB_OK|MB_ICONWARNING);
    oldText.TrimLeft();
 oldText.TrimRight();
 if(!oldText.IsEmpty())
 {
    if(!argu.bReWrited)//已经有文字时不重新写入
  {
           //AfxMessageBox("已经有文字时不重新写入!", MB_OK|MB_ICONWARNING);
     return;
  }
  
 }

 //写入新的文字
    m_wdSel.SetStart(start);
 m_wdSel.SetEnd(start);

 _Font ft = m_wdSel.GetFont();
 ft.SetBold(argu.bBold);
 ft.SetUnderline(argu.bUnderline);
 ft.SetItalic(argu.bItalic);
 if(argu.bSetFixedSize)//设定固定字号
 {
  ft.SetSize(argu.fixedSize);
 }
    m_wdSel.TypeText(szText);

 // 删除以空格形式的所有格式符
 if(oldText.IsEmpty())
 {
  Delete(1,totalWidth);
 }
 else
 {
  if(argu.bDeleteOlds)//要求删除原来的文字信息
  {
   Delete(1,totalWidth);
  }
 }
}

void CWordOffice::SetFontSize(float fontSize)
{
 _Font ft = m_wdSel.GetFont();
 ft.SetSize(fontSize);
}

float CWordOffice::GetFontSize()
{
 _Font ft = m_wdSel.GetFont();
 return ft.GetSize();
}

void CWordOffice::SetFontUnderline(long value)
{
 _Font ft = m_wdSel.GetFont();
 ft.SetUnderline(value);

}

long CWordOffice::GetFontUnderline()
{
 _Font ft = m_wdSel.GetFont();
  return ft.GetUnderline();
}


void CWordOffice::SetTextAlignment(TEXT_ALIGNMENT align)
{
 _ParagraphFormat pf = m_wdSel.GetParagraphFormat();
 pf.SetAlignment((long)align);
}

void CWordOffice::WriteNewLineText(CString szText, int nLineCount /**//* = 1 */)
{
    int i;
    if (nLineCount <= 0)
    {
        nLineCount = 0;
    }
    for (i = 0; i < nLineCount; i++)
    {
        m_wdSel.TypeParagraph();
    }
    WriteText(szText);
}

void CWordOffice::WriteEndLine(CString szText)
{
    m_wdRange.InsertAfter(szText);
}

void CWordOffice::WholeStory()
{
    m_wdRange.WholeStory();
}

void CWordOffice::Copy()
{
    m_wdRange.CopyAsPicture();
}

void CWordOffice::InsertFile(CString fileName)
{
    COleVariant     vFileName(fileName),
                 vTrue((short)TRUE),
                 vFalse((short)FALSE),
                 vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
                 vNull(_T(""));
    /**//*
    void InsertFile(LPCTSTR FileName, VARIANT* Range, VARIANT* ConfirmConversions, VARIANT* Link, VARIANT* Attachment);
    */
    m_wdSel.InsertFile(
                    fileName,
                    vNull,
                    vFalse,
                    vFalse,
                    vFalse
                    );
}

void CWordOffice::InsertShapes(CString fileName)
{
    COleVariant vTrue((short)TRUE),   
                vFalse((short)FALSE),
                vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    m_wdInlineShapes=m_wdSel.GetInlineShapes();
    m_wdInlineShape=m_wdInlineShapes.AddPicture(fileName,vFalse,vTrue,vOptional);
}


void CWordOffice::InsertHyperlink(CString fileLink)
{
    COleVariant     vAddress(_T(fileLink)),vSubAddress(_T(""));
    Range aRange = m_wdSel.GetRange();
    Hyperlinks vHyperlinks(aRange.GetHyperlinks());

    vHyperlinks.Add(
                    aRange,            //Object,必需。转换为超链接的文本或图形。
                    vAddress,         //Variant 类型,可选。指定的链接的地址。此地址可以是电子邮件地址、Internet 地址或文件名。请注意,Microsoft Word 不检查该地址的正确性。
                    vSubAddress,     //Variant 类型,可选。目标文件内的位置名,如书签、已命名的区域或幻灯片编号。
                    vAddress,         //Variant 类型,可选。当鼠标指针放在指定的超链接上时显示的可用作“屏幕提示”的文本。默认值为 Address。
                    vAddress,         //Variant 类型,可选。指定的超链接的显示文本。此参数的值将取代由 Anchor 指定的文本或图形。
                    vSubAddress        //Variant 类型,可选。要在其中打开指定的超链接的框架或窗口的名字。
                    );
    vHyperlinks.ReleaseDispatch();
}

//! Moves the start position of the specified range or selection. This method returns an integer that indicates the number of units by which the start position or the range or selection actually moved, or it returns 0 (zero) if the move was unsuccessful.
long CWordOffice::MoveStart(long unit, long count)
{
 COleVariant uV(unit);
 COleVariant cV(count);
 long n = m_wdSel.MoveStart(&uV, &cV);
 return n;
}

//! Moves the selection to the right and returns the number of units it's been moved.
long CWordOffice::MoveRight(long unit, long count, long extend)
{
 COleVariant uV(unit);
 COleVariant cV(count);
    COleVariant eV(extend);
 long n = m_wdSel.MoveRight(&uV, &cV, &eV);
 return n;
}


//! Moves the selection to the left and returns the number of units it's been moved.
long CWordOffice::MoveLeft(long unit, long count, long extend)
{
 COleVariant uV(unit);
 COleVariant cV(count);
    COleVariant eV(extend);
 long n = m_wdSel.MoveLeft(&uV, &cV, &eV);
 return n;
}

long CWordOffice::Delete(long unit, long count)
{
 if(0 == count)
 {
  return 0;
 }
 long start = m_wdSel.GetEnd();
 m_wdSel.SetStart(start);
    m_wdSel.SetEnd(start);
 COleVariant uV(unit);
 COleVariant cV(count);
 long n = m_wdSel.Delete(&uV, &cV);
 return n;
}

long CWordOffice::MoveUp(long unit, long count, long extend)
{
 COleVariant uV(unit);
 COleVariant cV(count);
    COleVariant eV(extend);
 long n = m_wdSel.MoveUp(&uV, &cV, &eV);
 return n;
}

long CWordOffice::MoveDown(long unit, long count, long extend)
{
 COleVariant uV(unit);
 COleVariant cV(count);
    COleVariant eV(extend);
 long n = m_wdSel.MoveDown(&uV, &cV, &eV);
 return n;
}

//! 查找书签位置
long CWordOffice::__GetMarkPosition(CString bookMark)
{
 m_wdSel.GoTo(COleVariant((short)-1), COleVariant((short)0), COleVariant((short)0), COleVariant(bookMark));
 long start = m_wdSel.GetStart();
 return start;
}


//! 读取文本
CString CWordOffice::GetText(const WORD_TEXT_READ_ARGU &argu, long &totalWidth)
{
 long start = 0;
 totalWidth = 0;
 if(READ_START_ABS == argu.readStartType)//指定读取的绝对位置
 {
  start = argu.start;
 }
 else if(READ_START_MARK == argu.bookMark)//指定读取的书签位置
 {
  start = __GetMarkPosition(argu.bookMark);
 }
 else;
   
 CString szText;
 if(0 == argu.ftReadTypeSize && argu.bReadFixedLen) //没有指定字体格式,只读取固定长度
 {
  m_wdSel.SetStart(start);
     m_wdSel.SetEnd(start+argu.fixedLength);
     szText = m_wdSel.GetText();
  totalWidth = argu.fixedLength;
  return szText;
 }
 else if(0 == argu.ftReadTypeSize && argu.bReadFinishedStr) //没有指定字体格式,只读到此结束字符串为止
 {
  szText = __GetTextWithEndStr(start,argu.finishedStr,argu.failMaxLength,totalWidth);
  return szText;
 }
 else;

 _Font ft;
 long distance = 0;
 //搜索符合字体格式的文字起点
 if(argu.ftSearchWidth > 0)//有向右搜索可能符合的字体的最大宽度
 {
  int i = 0;
  for(; i < argu.ftSearchWidth; ++i)
  {
   m_wdSel.SetStart(start);
          m_wdSel.SetEnd(start+1);
      ft = m_wdSel.GetFont();
         if(__isFontValid(argu.readFontTypes, argu.ftReadTypeSize, argu.fontType,ft))//符合格式,找到读取起点
   {
      break;
   }
      ++start;
   ++distance;
  }
  if(i == argu.ftSearchWidth)//没有符合要求的字体
  {
   AfxMessageBox("没有符合要求的字体", MB_OK|MB_ICONWARNING);
   return szText;
  }
  else
  {
   CString str;
   str.Format("符合格式的文字与起点距离:%d", distance);
   AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  }
 }

 while(1)
 {
    if(argu.bReadFixedLen && totalWidth >= argu.fixedLength)
    {
    break;
    }
    if(argu.bReadFinishedStr && -1 != szText.Find(argu.finishedStr))
    {
    break;
    }
    m_wdSel.SetStart(start);
    m_wdSel.SetEnd(start+1);
    ft = m_wdSel.GetFont();//读取当前字符的格式
    if(!__isFontValid(argu.readFontTypes, argu.ftReadTypeSize,argu.fontType,ft))//不再符合格式了,找到读取终点
  {
      CString str;
   str.Format("不再符合格式了,找到读取终点.text:"+szText, distance);
   AfxMessageBox(str, MB_OK|MB_ICONWARNING);
      break;
  }
     CString t = m_wdSel.GetText();
     szText += t;

  ++totalWidth;
  ++start;
 }

 if(totalWidth > 0)//加上前面的一段距离
 {
  totalWidth += distance;
 }

 return szText;
}

//! 根据起始,截止位置读取文本
CString CWordOffice::GetText(long start, long end)
{
    m_wdSel.SetStart(start);
    m_wdSel.SetEnd(end);
    return m_wdSel.GetText();
}

//检查字体是否符合格式
bool CWordOffice::__isFontValid(TEXT_READ_FONT_TYPE *fontTypes, int ftTypeSize, const FONT_TYPE &fontType,  _Font &ft)
{
 for(int i = 0; i < ftTypeSize; ++i)
 {
  TEXT_READ_FONT_TYPE readFontType = fontTypes[i];
  bool isValid = false;
  CString str;
  bool tmpRet;
  
   switch(readFontType)
  {
   case READ_USE_UNDERLINED: //读取字符考虑是否带有下划线的
    tmpRet = ft.GetUnderline() != 0;
    isValid = tmpRet==fontType.bUnderLine;
    break;
   case READ_USE_BOLD:   //读取字符考虑是否加粗的
    tmpRet = ft.GetBold() != 0;
    isValid = tmpRet == fontType.bBold;
    break;
   case READ_USE_ITALIC: //读取字符考虑是否倾斜的
    tmpRet = ft.GetItalic()  != 0;
                isValid = tmpRet == fontType.bItalic;
    break;
   case READ_USE_FONTSIZE: //读取字符考虑是否固定大小的
    isValid = (fabs(ft.GetSize()-fontType.fixedSize) < 0.000001);
    break;
   default:
    break;
  }
  if(!isValid)
  {
   return false;
  }
 }
 return true;
}

//!读取以固定字符串结尾的文本
CString  CWordOffice::__GetTextWithEndStr(long start, const char *finishedStr,long failMaxLength, long& totalWidth)
{
    CString szText;
    m_wdSel.SetStart(start);
 m_wdSel.SetEnd(start+1);
    _Font ft = m_wdSel.GetFont();
 totalWidth = 0;

 //读取所有带有下划线的文本
 while(1)
 {
       m_wdSel.SetStart(start);
    m_wdSel.SetEnd(start+1);
    szText += m_wdSel.GetText();
       ++totalWidth;
    if(-1 != szText.Find(finishedStr))
    {
     break;
    }
    if(-1 != failMaxLength && totalWidth >= failMaxLength)
    {
     break;
    }
    ++start;
 }
 
 return szText;
}

//! 读取当前位置所在表格单元格的文本
CString CWordOffice::GetCellText(long start)
{
 m_wdSel.SetStart(start);
    m_wdSel.SelectCell();
 return m_wdSel.GetText();
}

 

//! 从此处开始读取所有带有下划线的文本
// start 开始位置
// searchWidth 如果开始位置的文本不带有下划线,向右搜索可能带有下划线文本的最大宽度
CString CWordOffice::__GetUnderlineText(long start, long searchWidth, long &length)
{
 CString szText;
    m_wdSel.SetStart(start);
 m_wdSel.SetEnd(start+1);
    _Font ft = m_wdSel.GetFont();
 length = 0;

    if(0 == ft.GetUnderline())//起始位置的文本不带有下划线,向右试探试搜索
 {
  int i = 0;
  for(; i < searchWidth; ++i)
  {
   ++start;
   m_wdSel.SetStart(start);
          m_wdSel.SetEnd(start+1);
      ft = m_wdSel.GetFont();
   if(0 != ft.GetUnderline())//找到文本带有下划线
   {
    break;
   }
  }
  if(i == searchWidth)//没有找到文本带有下划线
  {
    return szText;
  }
 }

 //读取所有带有下划线的文本
 while(1)
 {
       m_wdSel.SetStart(start);
    m_wdSel.SetEnd(start+1);
    _Font ft = m_wdSel.GetFont();
  if(0 != ft.GetUnderline())
  { 
   szText += m_wdSel.GetText();
   ++start;
   ++length;
  }
  else
  {
   break;
  }
 }
 
 return szText;
}

//! 读取固定长度文本
CString CWordOffice::__GetFixedLenText(long start, long fixedLength)
{
 m_wdSel.SetStart(start);
 m_wdSel.SetEnd(start);
 return m_wdSel.GetText();
}

 

//! 测试所有表格的文本
void CWordOffice::TestTablesText()
{
 Tables tables = m_wdDoc.GetTables();
 CString str;
 str.Format("表格总数:%d", tables.GetCount());
 AfxMessageBox(str, MB_OK|MB_ICONWARNING);
 for(int i = 1; i <= tables.GetCount(); ++i)
 {
  Table tb = tables.Item(i);
  Columns      WordCols;
  Rows         WordRows;
  WordRows.AttachDispatch(tb.GetRows());
  WordCols.AttachDispatch(tb.GetColumns());
  for(int r = 1; r <= WordRows.GetCount(); ++r)
  {
   for(int c = 1; c <= WordCols.GetCount(); ++c)
   {
    Cell cl = tb.Cell(r,c);
    Range rg = cl.GetRange();
    CString text = "单元格内容:"+rg.GetText();
    AfxMessageBox(text, MB_OK|MB_ICONWARNING);
   }
  }
 }

//! 根据某一表格中,某一行列上的单元格内容
CString CWordOffice::GetTableCellText(long tableIndex, long row, long col)
{
 ++tableIndex;
 ++row;
 ++col;
 CString szText;
 Tables tables = m_wdDoc.GetTables();
 if(tableIndex <= 0 || tableIndex > tables.GetCount())
 { 
  CString str= "访问的表格不存在!";
     AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  return szText;
 }
    Table   wordTable;
 Columns WordCols;
 Rows    WordRows;
    wordTable.AttachDispatch(tables.Item(tableIndex));
 WordRows.AttachDispatch(wordTable.GetRows());
 WordCols.AttachDispatch(wordTable.GetColumns());
 if(row <= 0 || row > WordRows.GetCount() || col <= 0 || col >= WordCols.GetCount())
 {
  CString str= "访问的单元格不存在!";
     AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  return szText;
 }
 IDispatch *dispatch = wordTable.Cell(row,col);
 Range rg;
 rg.AttachDispatch(dispatch);
 return rg.GetText();
}

//! 在某一表格中,某一行列上的单元格中写入内容
void CWordOffice::WriteTableCellText(long tableIndex, long row, long col, CString szText)
{
 ++tableIndex;
 ++row;
 ++col;
 Tables tables = m_wdDoc.GetTables();
 if(tableIndex <= 0 || tableIndex > tables.GetCount())
 { 
  CString str= "访问的表格不存在!";
     AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  return;
 }
    Table   wordTable;
 Columns WordCols;
 Rows    WordRows;
    wordTable.AttachDispatch(tables.Item(tableIndex));
 WordRows.AttachDispatch(wordTable.GetRows());
 WordCols.AttachDispatch(wordTable.GetColumns());
 if(row <= 0 || row > WordRows.GetCount() || col <= 0 || col >= WordCols.GetCount())
 {
  CString str= "访问的单元格不存在!";
     AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  return;
 }
 IDispatch *dispatch = wordTable.Cell(row,col);
 Range rg;
 rg.AttachDispatch(dispatch);
 rg.SetText(szText);
}

//! 读取某一表格中所有单元格的内容,结果放在数组strArray中
bool CWordOffice::GetTableCellsText(long tableIndex, CString strArray[])
{
 CString szText;
 Tables tables = m_wdDoc.GetTables();
 if(tableIndex <= 0 || tableIndex > tables.GetCount())
 { 
  CString str= "访问的表格不存在!";
     AfxMessageBox(str, MB_OK|MB_ICONWARNING);
  return false;
 }
    Table   wordTable;
 Columns WordCols;
 Rows    WordRows;
    wordTable.AttachDispatch(tables.Item(tableIndex));
 WordRows.AttachDispatch(wordTable.GetRows());
 WordCols.AttachDispatch(wordTable.GetColumns());
 int pos = 0;
 for(int r = 1; r <= WordRows.GetCount(); ++r)
 {
  for(int c = 1; c <= WordCols.GetCount(); ++c)
  {
   Cell cl = wordTable.Cell(r,c);
   Range rg = cl.GetRange();
   strArray[pos++] = rg.GetText();
  }
 }
    return true;
}

//!建立表格, //!建立表格,可指定位置
void CWordOffice::CreateTable(long rowCount, long colCount, long start)
{
 if(-1 != start)//有指定位置
 {
  m_wdSel.SetStart(start);
 }
 Tables tables = m_wdSel.GetTables();
 Range rg = m_wdSel.GetRange();
 Table table = tables.Add(rg, rowCount, colCount, COleVariant((short)0), COleVariant((short)0));
}

//! 建立一个测试文档
bool CWordOffice::TestCreateDoc(CString fileName)
{
 if(!this->Create())
 {
  return false;
 }
 //WriteEndLine("文件结尾");

 //写入文件内容
    CString szText = "  《中华人民共和国统计法》规定,统计调查对象必须依法真实、准确、完整、及时地提供统计调查所需的资料。";
 this->SetFontUnderline(true);
    this->WriteText(szText);
 this->SetFontUnderline(false);
 m_wdSel.TypeParagraph();
 InsertFile("D:/统计行政执法管理系统.txt");
 InsertShapes("D:/IMG0043A.jpg");
 m_wdSel.TypeParagraph();
 InsertHyperlink("http://www.gmjz8.com/index.php");
 int i;
 for(i = 0; i < 2; ++i)
 {
  m_wdSel.TypeParagraph();
 }

 //写入表格标题
 this->WriteText("案源登记表",-1,16);
 this->SetTextAlignment(ALIGN_MIDDLE);
    m_wdSel.TypeParagraph();
    this->SetTextAlignment(ALIGN_LEFT);
 m_wdSel.TypeParagraph();

    //建立一张测试表格
 Tables tables = m_wdSel.GetTables();
 Range rg = m_wdSel.GetRange();
 Table table = tables.Add(rg, 5, 4, COleVariant((short)0), COleVariant((short)0));

    //设置列宽
 Columns columns = table.GetColumns();
 Column column = columns.Item(1);
 column.SetWidth(60);

 column = columns.Item(2);
 column.SetWidth(120);

 column = columns.Item(3);
 column.SetWidth(60);

 column = columns.Item(4);
 column.SetWidth(160);

    //设置行高
 Rows rows = table.GetRows();
 Row row =  rows.Item(4);
 row.SetHeight(140);

 row =  rows.Item(5);
 row.SetHeight(140);

 //合并单元格
    Cell mergeFrom = table.Cell(4,2);
 mergeFrom.Merge(table.Cell(4,4));

 //合并单元格
 mergeFrom = table.Cell(5,2);
 mergeFrom.Merge(table.Cell(5,4));
 
 //向单元格写入文本
 this->WriteTableCellText(0, 0,0,"案源编号");
 this->WriteTableCellText(0, 0,1,"年月日加上顺序号3位数");
 this->WriteTableCellText(0, 0,2,"案源事由");
 this->WriteTableCellText(0, 1,0,"案件来源");
 this->WriteTableCellText(0, 1,2,"案件性质");
 this->WriteTableCellText(0, 2,0,"登记时间");
 this->WriteTableCellText(0, 2,2,"登记人");
 this->WriteTableCellText(0, 3,0,"附件列表");
 this->WriteTableCellText(0, 4,0,"审批意见");
  
 //保存文档到磁盘
 this->SaveDocumentAs(fileName);
 return true;
}

 

/* worddemoDlg.cpp */

void CWorddemoDlg::OnBtnCreateTestDoc()
{
 // TODO: Add your control notification handler code here
 CWordOffice wordOffice;
 CString szText;
 if(wordOffice.TestCreateDoc("D:/测试文档.doc"))
 {
  szText = "建立成功!";
  AfxMessageBox(szText, MB_OK|MB_ICONINFORMATION);
 }
 else
 {
        szText = "建立失败!";
   AfxMessageBox(szText, MB_OK|MB_ICONWARNING);
 }

}

void CWorddemoDlg::OnBtnModifyDoc()
{
 // TODO: Add your control notification handler code here
 
 CWordOffice wordOffice;
 CString szText;
 wordOffice.Open("E:/zyx/mfc/worddemo/Release/统计调查表催领通知书.doc");
 wordOffice.ShowApp();
 WORD_TEXT_WRITE_ARGU argu;
 argu.writeStartType = WRITE_START_MARK;
    argu.bookMark = "mymark";//根据书签位置来写入
    argu.bItalic = true; //倾斜的
 argu.bSetFixedSize = true; //固定尺寸的
 argu.fixedSize = 21;
 argu.bUnderline = true;//加下划线的
 argu.bBold = true;//加粗的
 argu.bReWrited = true; //已经有文字时重新写入
 argu.bDeleteOlds = true;//重新写入时删除原来的文字
 wordOffice.WriteText("一切生命,包括飞虫蚂蚁,自性都是平等圆满具足的",argu);

 wordOffice.SaveDocument();
 wordOffice.CloseApp();
 szText = "修改文档成功";
    AfxMessageBox(szText, MB_OK|MB_ICONWARNING);
}

void CWorddemoDlg::OnBtnRead()
{
 // TODO: Add your control notification handler code here
    CWordOffice wordOffice;
 CString szText;
 wordOffice.Open("E:/zyx/mfc/worddemo/Release/统计调查表催领通知书.doc");
 wordOffice.ShowApp();


 WORD_TEXT_READ_ARGU argu;
 argu.readStartType = READ_START_MARK; //通过书签来读取
    argu.bookMark = "mymark";

 TEXT_READ_FONT_TYPE array[3];

    array[0] = READ_USE_BOLD;  //读取的字体要考虑是否加粗的
 argu.fontType.bBold = true;  //只读取加粗的

 array[1] = READ_USE_UNDERLINED;  //读取的字体要考虑是否加下划线的
 argu.fontType.bUnderLine = true; //只读取加下划线的

    array[2] = READ_USE_FONTSIZE;  //读取的字体要考虑固定大小的
 argu.fontType.fixedSize = 21; //固定大小

    argu.ftReadTypeSize = 3;
    argu.readFontTypes = array;
 argu.ftSearchWidth = 5;

 argu.bReadFixedLen = true;
 argu.fixedLength = 5;

 argu.bReadFinishedStr = true;
 argu.finishedStr = "}}";
 argu.failMaxLength = 50;

 long totalWidth = 0;
    CString text = wordOffice.GetText(argu,totalWidth);
 wordOffice.CloseApp();
 AfxMessageBox(text, MB_OK|MB_ICONWARNING); 
}

 

原创粉丝点击