牛骨文教育服务平台(让学习变的简单)
博文笔记

利用QT生成Word文档

创建时间:2016-11-30 投稿人: 浏览次数:6923

   前段时间因一个项目的需要,需要用Qt生成Word报告,网上查阅并借鉴了相关资料终于解决了基本的问题。本文档中主要是基本数据的填充、数据表格和图片几种类型,所以是用word模板(.dot)和书签进行操作。(网上看有种方法是利用宏来进行操作,表示不是很懂,哈哈)。

一、主要方法

1、根据报告要求,设计word模板,定义好需要插入数据的标签,调好其他固定内容的格式。(以保证数据插入后文档内容排列有序)

2、编写word操作接口类,主要包括:打开、关闭、保存、插入文本、插入图片、插入表格、相关格式调整函数

3、编写生成报告界面类,调用接口函数生成word文档。

二、接口函数

WordEngine.h文件

#ifndef WORDENGINE_H
#define WORDENGINE_H
#include <QObject>
#include <QAxObject>
#include <QtCore>
class WordEngine : public QObject
{
    Q_OBJECT
public:
    WordEngine();
    ~WordEngine();

    /// 打开Word文件,如果sFile路径为空或错误,则打开新的Word文档
    bool Open(QString sFile, bool bVisible = true);

    void save(QString sSavePath);

    void close(bool bSave = true);

    bool replaceText(QString sLabel,QString sText);
    bool replacePic(QString sLabel,QString sFile);
    //插入一个几行几列表格
    QAxObject *insertTable(QString sLabel,int row,int column);
    //插入一个几行几列表格 并设置表头
    QAxObject *insertTable(QString sLabel,int row,int column,QStringList headList);
    //设置列宽
    void setColumnWidth(QAxObject *table,int column, int width);
    void SetTableCellString(QAxObject *table, int row,int column,QString text);

private:

    QAxObject *m_pWord;      //指向整个Word应用程序
    QAxObject *m_pWorkDocuments;  //指向文档集,Word有很多文档
    QAxObject *m_pWorkDocument;   //指向m_sFile对应的文档,就是要操作的文档

    QString m_sFile;
    bool m_bIsOpen;
    bool m_bNewFile;
};

#endif // WORDENGINE_H


WordEngine.cpp文件

#include "WordEngine.h"
#include "qt_windows.h"
WordEngine::WordEngine()
{
    m_pWord = NULL;
    m_pWorkDocuments = NULL;
    m_pWorkDocument = NULL;

    m_bIsOpen = false;
    m_bNewFile = false;

    HRESULT result = OleInitialize(0);

    if (result != S_OK && result != S_FALSE)
    {
        qDebug()<<QString("Could not initialize OLE (error %x)").arg((unsigned int)result);
    }
}

WordEngine::~WordEngine()
{
    //if(m_bIsOpen)
    //    close();

    OleUninitialize();
}

bool WordEngine::Open(QString sFile, bool bVisible)
{
     //新建一个word应用程序
     m_pWord = new QAxObject();
     bool bFlag = m_pWord->setControl( "word.Application" );
     if(!bFlag)
     {
        return false;
     }
     m_pWord->setProperty("Visible", bVisible);
     //获取所有的工作文档
     QAxObject *document = m_pWord->querySubObject("Documents");
     if(!document)
     {
        return false;
     }
     //以文件template.dot为模版新建一个文档
     document->dynamicCall("Add(QString)", sFile);
     //获取当前激活的文档
     m_pWorkDocument = m_pWord->querySubObject("ActiveDocument");
     if(m_pWorkDocument)
         m_bIsOpen = true;
     else
         m_bIsOpen = false;

     return m_bIsOpen;
}

void WordEngine::save(QString sSavePath)
{
    if(m_bIsOpen && m_pWorkDocument)
    {
        if(m_bNewFile){
            m_pWorkDocument->dynamicCall("Save()");
        }
        else{
            //m_pWorkDocument->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)",
             //                           m_sFile,56,QString(""),QString(""),false,false);
            m_pWorkDocument->dynamicCall("SaveAs (const QString&)", sSavePath);
        }
    }
    qDebug()<<"save Done.";
}

void WordEngine::close(bool bSave)
{
    if(bSave){
        //save();
    }
    if(m_pWord){
        m_pWord->setProperty("DisplayAlerts", true);
    }
    if(m_pWorkDocument){
        m_pWorkDocument->dynamicCall("Close(bool)", true);
    }
    if(m_pWord){
        m_pWord->dynamicCall("Quit()");
    }
    if(m_pWorkDocuments)
    {
        delete m_pWorkDocuments;
    }
    if(m_pWord)
    {
        delete m_pWord;
    }
    m_pWorkDocument = NULL;
    m_pWorkDocuments = NULL;
    m_pWord = NULL;

    m_bIsOpen   = false;
    m_bNewFile  = false;

}

bool WordEngine::replaceText(QString sLabel,QString sText)
{
    if(!m_pWorkDocument){
        return false;
    }
    //获取文档中名字为sLabel的标签
    QAxObject *pBookmark = m_pWorkDocument->querySubObject("Bookmarks(QString)",sLabel);
    if(pBookmark)
    {
        pBookmark->dynamicCall("Select(void)");
        pBookmark->querySubObject("Range")->setProperty("Text",sText);
        delete pBookmark;
    }
    return true;
}

bool WordEngine::replacePic(QString sLabel,QString sFile)
{
    if(!m_pWorkDocument)
        return false;

    QAxObject *bookmark_pic = m_pWorkDocument->querySubObject("Bookmarks(QString)",sLabel);
    if(bookmark_pic)
    {
        bookmark_pic->dynamicCall("Select(void)");
        QAxObject *Inlineshapes = m_pWorkDocument->querySubObject("InlineShapes");
        Inlineshapes->dynamicCall("AddPicture(const QString&)",sFile);
        delete Inlineshapes;
    }
    return true;
}

QAxObject *WordEngine::insertTable(QString sLabel, int row, int column)
{
     QAxObject *bookmark = m_pWorkDocument->querySubObject("Bookmarks(QVariant)", sLabel);
     if(bookmark)
     {
       bookmark->dynamicCall("Select(void)");
       QAxObject *selection = m_pWord->querySubObject("Selection");

       selection->dynamicCall("InsertAfter(QString&)", "
");
       //selection->dynamicCall("MoveLeft(int)", 1);
       selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
       //selection->dynamicCall("TypeText(QString&)", "Table Test");//设置标题

       QAxObject *range = selection->querySubObject("Range");
       QAxObject *tables = m_pWorkDocument->querySubObject("Tables");
       QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column);

       for(int i=1;i<=6;i++)
       {
           QString str = QString("Borders(-%1)").arg(i);
           QAxObject *borders = table->querySubObject(str.toAscii().constData());
           borders->dynamicCall("SetLineStyle(int)",1);
       }
       return table;
     }
}

QAxObject *WordEngine::insertTable(QString sLabel, int row, int column, QStringList headList)
{
    QAxObject *bookmark = m_pWorkDocument->querySubObject("Bookmarks(QVariant)", sLabel);
    if(headList.size() != column){
        return NULL;
    }
    if(bookmark)
    {
      bookmark->dynamicCall("Select(void)");
      QAxObject *selection = m_pWord->querySubObject("Selection");

      selection->dynamicCall("InsertAfter(QString&)", "
");
      //selection->dynamicCall("MoveLeft(int)", 1);
      selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
      //设置标题
      //selection->dynamicCall("TypeText(QString&)", "Table Test");

      QAxObject *range = selection->querySubObject("Range");
      QAxObject *tables = m_pWorkDocument->querySubObject("Tables");
      QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column);
      //表格自动拉伸列 0固定  1根据内容调整  2 根据窗口调整
      table->dynamicCall("AutoFitBehavior(WdAutoFitBehavior)", 2);

      //设置表头
      for(int i=0;i<headList.size();i++){
          table->querySubObject("Cell(int,int)",1,i+1)->querySubObject("Range")->dynamicCall("SetText(QString)", headList.at(i));
          //加粗
          table->querySubObject("Cell(int,int)",1,i+1)->querySubObject("Range")->dynamicCall("SetBold(int)", true);
      }

      for(int i=1;i<=6;i++)
      {
          QString str = QString("Borders(-%1)").arg(i);
          QAxObject *borders = table->querySubObject(str.toAscii().constData());
          borders->dynamicCall("SetLineStyle(int)",1);
      }
      return table;
    }
}

void WordEngine::setColumnWidth(QAxObject *table, int column, int width)
{
    if(!table){
        return;
    }
    table->querySubObject("Columns(int)",column)->setProperty("Width",width);
}

void WordEngine::SetTableCellString(QAxObject *table, int row,int column,QString text)
{
    if(!table)
        return;
    QAxObject *cell = table->querySubObject("Cell(int,int)",row,column);
    if(!cell)
        return ;
    cell->dynamicCall("Select(void)");
    cell->querySubObject("Range")->setProperty("Text", text);
}

注:对于给标签插入文本、图片比较简单,主要是在对于表格插入调试了很久,比如表头加粗、表格自动拉伸、边框调整。。。。当然,本文中插入的表格的都是比较简单的,并没有涉及合并,颜色控制等等,以后如有需要再研究。附上生成报告的demo,很丑哈,莫吐槽,,





声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。