1. 程式人生 > >利用QT生成Word文件

利用QT生成Word文件

   前段時間因一個專案的需要,需要用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&)", "\n");
       //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&)", "\r\n");
      //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,很醜哈,莫吐槽,,