簡
在這篇帖子中我將詳細講述如何在Qt環境下使用已有Word模板文件創建新的文檔,並對模板文檔內容填充。目前,我只對替換文字和對錶格進行操作進行了介紹,如何在文檔插入圖片未在本文中提及。
述
開發環境
本文中使用的開發環境是Qt5.10.0。由於本文中的實現方式是通過COM組件操作Word,需要在.pro文件中添加QT += axcontainer,在Qt4的版本中與Qt5是有點區別的,在Qt4中添加CONFIG += qaxcontainer。
從代碼中看過程
多餘的就不說了,具體過程看註釋吧。
WordEngine.h
#ifndef WORDENGINE_H
#define WORDENGINE_H
#include <QObject>
#include <QAxObject>
#include <QAxWidget>
class WordEngine : public QObject
{
Q_OBJECT
public:
explicit WordEngine(QObject *parent = 0);
public slots:
bool open(const QString &file);//打開文檔
void save(const QString &savePath);//保存並關閉文檔
void replaceText(const QString &label,const QString &text);//替換文檔中標籤出的文字
void alterTableRowCount(const QString &tabel, const int rowCount);//在表箇中添加新行
void fillTableCell(const QString &tabel,const QList<QStringList> &data);//填充表格內容
private:
QAxWidget *_word;//word主程序
QAxObject *_workDocument;//工作簿
bool _isOpen;//文檔打開狀態
QMap<QString,int> _tabelIndex;//文檔中的表格索引,注意word中表格的索引值是從1開始的,這裏根據不同的情況單獨實現
};
#endif // WORDENGINE_H
WordEngine.cpp
#include "WordEngine.h"
#include "qt_windows.h"
#include <QMessageBox>
WordEngine::WordEngine(QObject *parent) : QObject(parent)
{
_word = NULL;
_workDocument = NULL;
_isOpen = false;
/// 初始化表格索引,在word中可以直接獲取表格的索引而不是書籤來編輯表格內容,
/// 所以,這裏的索引是需要用戶手動進行維護的
_tabelIndex["table1"] = 1;
_tabelIndex["table2"] = 2;
}
/// Summary:根據傳入的模板文件地址創建新的word文檔並打開
/// parameters:
/// file:.dot模板文件的絕對地址,這裏只能使用絕對地址,否則找不到文件,並且建議使用QDir::toNativeSeparators()將地址中的'/'轉換成'\'
/// return:
/// 文檔是否打開
bool WordEngine::open(const QString& file)
{
_word = new QAxWidget("word.Application");
QAxObject *document = _word->querySubObject("Documents");//獲取所有打開的文檔
if (!document)
return false;
document->dynamicCall("Add(QString)",file);//使用模板文件創建新的文檔
_workDocument = _word->querySubObject("ActiveDocument");//激活文檔
if (_workDocument)
_isOpen = true;
else
_isOpen = false;
if (!_isOpen)
{
QMessageBox box(QMessageBox::Information,QString("提示"),QString("未找到模板文件:%0").arg(file));
box.addButton(QString("確定"),QMessageBox::AcceptRole);
box.exec();
}
return _isOpen;
}
/// Summary:將文檔保存到指定地址,並關閉word程序
/// parameters:
/// savePath:word的保存地址
void WordEngine::save(const QString &savePath)
{
//保存
if (_isOpen && _workDocument)
{
_workDocument->dynamicCall("SaveAs (const QString&)",savePath);
}
if (_word)
{
_word->setProperty("DisplayAlerts",true);
}
//關閉文檔
if (_workDocument)
{
_workDocument->dynamicCall("Close(bool)",true);
delete _workDocument;
_workDocument = NULL;
}
//推出word程序
if (_word)
{
_word->dynamicCall("Quit()");
delete _word;
_word = NULL;
}
_isOpen = false;
}
/// Summary:替換指定書籤處的內容
/// parameters:
/// label:書籤名稱,這裏的書籤對應的是在word中的插入->書籤
/// text:內容
void WordEngine::replaceText(const QString &label, const QString &text)
{
if (!_workDocument)
return ;
//查找書籤
QAxObject *bookmark = _workDocument->querySubObject("Bookmarks(QString)",label);
if (bookmark)
{
//選定書籤,並替換內容
bookmark->dynamicCall("Select(void)");
bookmark->querySubObject("Range")->setProperty("Text",text);
delete bookmark;
}
}
/// Summary:調整表格行數,目前只能插入不能刪除,在word模板中,在表格中至少需要有一行內容空行,否則在插入新行的時候,數據內容會跟隨表頭行的格式,有時候導出結果會非常難看
/// parameters:
/// tabel:表格名稱
/// rowCount:行數
void WordEngine::alterTableRowCount(const QString &tabel, const int rowCount)
{
if (NULL == _workDocument) return;
QAxObject *table = _workDocument->querySubObject("Tables(int)",_tabelIndex.value(tabel));//獲取表格
if (NULL == table) return;
//獲取表格目前的行數
QAxObject *rows = table->querySubObject("Rows");
qint32 count = rows->dynamicCall("Count").toInt();
//插入行
for (int i = count - 1; i < rowCount; ++i)
{
rows->querySubObject("Add()");
}
}
/// Summary:填充表格內容
/// parameters:
/// tabel:表格名稱
/// data:內容
void WordEngine::fillTableCell(const QString &tabel, const QList<QStringList> &data)
{
if (NULL == _workDocument) return;
QAxObject *table = _workDocument->querySubObject("Tables(int)",_tabelIndex.value(tabel));//獲取表格
if (NULL == table) return;
//獲取表格目前的行數
QAxObject *rows = table->querySubObject("Rows");
qint32 rowCount = rows->dynamicCall("Count").toInt();
//獲取表格目前的列數
QAxObject *columns = table->querySubObject("Columns");
qint32 columnCount = columns->dynamicCall("Count").toInt();
//當前表格行數小於數據的行數,調整到數據的行數
if (data.size()>rowCount)
{
alterTableRowCount(tabel,data.size());
}
//填充表格內容
for (int row = 0; row < data.size(); ++row)
{
for (int column = 0; column < data.at(row).size() && column < columnCount; ++column)
{
QAxObject *cell=table->querySubObject("Cell(int,int)",row+2,column+1);//獲取單元格,注意word中的索引是從1開始的,再加上表頭row應該+2
if(!cell) return;
cell->dynamicCall("Select(void)");
cell->querySubObject("Range")->setProperty("Text",data.at(row).at(column));
delete cell;
}
}
}
不足之處
這種方法讀寫文檔的效率非常低,但是在Qt中Qwidget的派生類都無法在子線程中運行,所以當文件內容比較多的時候我們能做的只有等……或許你有更好的方法,請一定告訴我(_ _)。゜zzZ
結
以上就是如何在Qt中創建Word文檔並修改word文檔內容。如有不明白的地方歡迎留言或通過下面的郵件地址交流,若帖子中有錯誤的地方同樣歡迎留言批評指正,在此謝過路過的各位大神。