利用QT生成Word文件
阿新 • • 發佈:2019-01-06
前段時間因一個專案的需要,需要用Qt生成Word報告,網上查閱並借鑑了相關資料終於解決了基本的問題。本文件中主要是基本資料的填充、資料表格和圖片幾種型別,所以是用word模板(.dot)和書籤進行操作。(網上看有種方法是利用巨集來進行操作,表示不是很懂,哈哈)。
一、主要方法
1、根據報告要求,設計word模板,定義好需要插入資料的標籤,調好其他固定內容的格式。(以保證資料插入後文檔內容排列有序)
2、編寫word操作介面類,主要包括:開啟、關閉、儲存、插入文字、插入圖片、插入表格、相關格式調整函式
3、編寫生成報告介面類,呼叫介面函式生成word文件。
二、介面函式
WordEngine.h檔案
WordEngine.cpp檔案#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
#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,很醜哈,莫吐槽,,