文章目錄
核心流程介紹
根據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