[簡單易上手]Qt5生成word快速上手

核心流程介紹

根據word模板生成文檔其實過程很簡單,不管是什麼語言
歸根到底就是
1.用office利用word模板生成一個新文檔(當然你可以設置這個過程不可見)
2.找到word文檔中的一些錨點(這些錨點是在word模板中就設置好了的)
3.在你需要的位置插入你想要放進去的內容
4.把這個文檔保存起來

需要注意的部分:
生成word很慢最好放在子線程裏面。QAxObject代替QAxWidget比較好。因爲看別的博客說在QAxWidget會在子線程報錯。本文用的都是QAxObject。

所以寫代碼的過程也就是這三個過程,下面依次給大家看看代碼:

0.準備過程

1.最開始應該是要設置ActiveQt(本質上就是後面cpp文件中加了幾個qt相關的.h的引用)
在vs中的設置如下

在這裏插入圖片描述
在這裏插入圖片描述
2.首先動動小手新建倆文件:doccreate.cpp和頭文件doccreate.h(代碼資源會放在文章後面)
先給doccreate.h的代碼。
之所以要先給出來是因爲後面會用到裏面的全局變量。
就是這三個大寶貝:
QAxObject *m_WordFile;//指向整個Word應用程序
QAxObject *Documents;//指向文檔集,Word有很多文檔
QAxObject *m_Document;//指向激活文檔,Word有很多文檔,這是目前激活的那個文檔

#pragma once
#include <QObject>
#include <string>
#include <QAxWidget>
#include <QAxObject>//用於word生成的插件QtActive
#include <QThread> 
using namespace std;
class doccreate : public QObject
{
	Q_OBJECT
public:
	doccreate(QObject *parent = nullptr);
	~doccreate();
	bool Open(QString Dir);
	void AddPicture(QString file);//插入圖片
	void insertEnter();//插入回車
	void typeText(QString text);//插入文字
	void findPos(QString posName);//selection找到位置
	void saveFile(QString dir);//保存文件
private:
	QAxObject *m_WordFile;//指向整個Word應用程序
	QAxObject *Documents;//指向文檔集,Word有很多文檔
	QAxObject *m_Document;//指向激活文檔,Word有很多文檔,這是目前激活的那個文檔
};

3.然後準備一個word模板,例如本文用到的template.dot
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

1.用office利用word模板生成一個新文檔(當然你可以設置這個過程不可見)

備註很詳細,自己看。

bool doccreate::Open(QString Dir)
{
	// 新建一個word應用程序,並設置爲可見
	m_WordFile = new QAxObject();//取代QAxWidget,使其在子線程中可用
	bool bFlag = m_WordFile->setControl("word.Application");
	if (NULL == m_WordFile)
	{
		cout << "word opening false" << endl;
		// 嘗試用wps打開
		bFlag = m_WordFile->setControl("kwps.Application");
		if (!bFlag)
		{
			return false;
		}
	}
        //設置打開的word應用可見,建議一開始可見。這樣你可以看到這個過程。
	m_WordFile->setProperty("Visible", true);
	// 獲取所有的工作文檔
	Documents = m_WordFile->querySubObject("Documents");
	if (NULL == Documents)
	{
		cout << "documents opening false" << endl;
		return false;
	}
	// 以文件template.dot爲模版新建一個文檔
	Documents->dynamicCall("Add(QString)", Dir);
	// 獲取當前激活的文檔
	m_Document = m_WordFile->querySubObject("ActiveDocument");
	cout <<"ActiveDocument:"<< m_WordFile << endl;
	/*cout << *m_WordFile << endl;*/
	if (NULL == m_Document)
	{
		cout << "Active Doc opening false" << endl;
		return false;
	}
	return true;
}

2.找到word文檔中的一些錨點(這些錨點是在word模板中就設置好了的)

所謂錨點,我看了一些博客,其實普遍有兩種方式來找。一般就配合着用。
第一種是找到word模板中的書籤,也就是剛剛在模板文件中的設置的。(Bookmark)
這個是萬用的找位置的辦法。
第二種是找到當前光標的位置。(Selection)
這個實際上是一種補充辦法,就比如在一個位置你要接着剛剛那個書籤位置輸入之後繼續寫,就很適合這種光標的辦法。

話不多說上代碼:

//先用bookmark找到書籤位置,再找到selection位置
void doccreate::findPos(QString posName) {
	//根據bookmark找到書籤位置
	QAxObject *bookmark_text = m_Document->querySubObject(QString("Bookmarks(%1)").arg(posName).toLocal8Bit().data());
        //根據bookmark找到selection,也就是光標位置
	bookmark_text->dynamicCall("Select(void)");
}

3.在你需要的位置插入你想要放進去的內容

我只用到了插入文字、換行和插入圖片。
需要更多的功能可以參考:https://blog.csdn.net/u010304326/article/details/82292195
代碼如下

//插入文字
void doccreate::typeText(QString text) {
	QAxObject* selection = m_WordFile->querySubObject("Selection");
	if (!selection)
	{
		return;
	}
	selection->dynamicCall("TypeText(const QString&)", text);
}

//插入回車
void doccreate::insertEnter() {
	QAxObject* selection = m_WordFile->querySubObject("Selection");
	if (!selection)
	{
		return;
	}
	selection->dynamicCall("TypeParagraph(void)");
}

//增加圖片
void doccreate::AddPicture(QString file) {
	//讀取到當前選中的位置,可以用Range和delect進行定位
	QAxObject* selection = m_WordFile->querySubObject("Selection");
	if (!selection)
	{
		return;
	}
	QString filename = file;
	/*filename.replace("/", "\\");*/
	//Inlineshapes是一個擁有函數AddPictures的對象
	QAxObject *Inlineshapes = selection->querySubObject("InlineShapes");
	Inlineshapes->dynamicCall("AddPicture(const QString&)", filename);
	delete Inlineshapes;
}

4.把這個文檔保存起來

保存一下文件,然後記得刪掉緩存嗷

//保存文件
void doccreate::saveFile(QString dir) {
	if (dir.isEmpty()) {
		cout << "輸入的文件名爲空!" << endl;
		return;
	}
	cout << "begin edit" << dir.toStdString().c_str() << endl;
	// 將文件另存爲outFileName,關閉工作文檔,退出應用程序  
	m_Document->dynamicCall("SaveAs (const QString&)", dir);
	m_Document->dynamicCall("Close (boolean)", true);  //關閉文本窗口
	m_WordFile->dynamicCall("Quit(void)");  //退出word
	delete m_Document;
	delete Documents;
	delete m_WordFile;
}

5.子線程的設置

https://blog.csdn.net/lm409/article/details/77965130
這一篇開頭講的很清楚,我不贅述了。我的資源裏面也是參考了這個博客的內容嗷。

6.項目代碼下載地址:

最後,把自己的代碼分享出來,不足之處大家多多指教嗷
https://download.csdn.net/download/sparkleyn/11943687

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章