[简单易上手]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

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