最近由于项目需要,要用QT操作Word文档。具体的工作需求:在指定的Word文档(*.doc文件/*.docx文件)中查找关键字,找到后做高亮操作或者直接删除操作,然后另存为到别的目录(表示这个文件被操作过了)。

这个功能很简单,确实挺简单,但由于是第一次用QT操作Word文档,所以仍需要经过一番查找资料。网上用QT操作Word文档的资料不是很多(可能是我没找对地方),所以经过了一段时间的碰壁之后(没有现成的,哪怕是半成品),我决定还是从源头看起:

  1.查看帮助文档:Microsoft Word Visual Basic参考.chm。这是操作Word文档的VBA接口文档

  2.查看官方网站的帮助文档:https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word?view=word-pia

    “查找”在这:https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word.find.hithighlight?view=word-pia#Microsoft_Office_Interop_Word_Find_HitHighlight_System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__System_Object__

要想用QT操作office文档,就要用到QAxWidget类和QAxObject类首先要在pro文件中配置一个模块“qaxcontainer”,也就是添加一行代码,即:

  CONFIG += qaxcontainer

在找到关键字之后,我还保存了一些数据:文件名、文件所在的路径、关键字所处的位置。如果你不需要这些数据,可以删减掉。

QList<QString> fileNameList;    // 保存文件名
QList<QString> filePathList;    // 保存文件路径
QList<QStringList> keyWordsPositionList;    // 保存关键字所在位置

首先介绍一个函数,这个函数通过正则表达式用来定位关键字所处在的语句。这个函数会在后面的高亮操作函数和直接删除函数里调用到:

// 查找关键字的位置
// fileContent:文件内容;keyWord:关键字
QStringList findKeyWordsPosition(QString fileContent, QString keyWord)
{
QStringList resList;
if (fileContent.contains(keyWord)){
qDebug() << QObject::tr("包含子字符串 : %1").arg(keyWord); int startIndex = ;
// int count = 0;
int keyWordsLen = keyWord.length();
QRegExp rx(QObject::tr("[,。:\r]?([^,。:\r]*(%1)[^,。:\r]*)[,。:\r]?").arg(keyWord)); while ((startIndex = rx.indexIn(fileContent, startIndex)) != -){
QString resStr = rx.cap().mid(); // 提取子字符串所在的语句
if (resStr.contains("\r"))
resStr.replace("\r", "");
resList << resStr; // 找到子字符串
int findIndex = fileContent.indexOf(keyWord, startIndex);
// qDebug() << QObject::tr("keyWords 出现的位置 : %1").arg(findIndex);
startIndex = findIndex + keyWordsLen;
// qDebug() << QObject::tr("keyWords 出现的次数 : %1").arg(++count);
qDebug() << "\n";
} return resList;
}
return resList << "";
}

首先是高亮操作函数:

// 高亮操作函数
// dirName:是待检查文件的路径;keyWords:是要查找的关键字(查找的关键字可能是多个)
bool highLightKeyWordsinWordFile(QString dirName, QStringList keyWords)
{
int lastSeparatorIndex = dirName.lastIndexOf(QDir::separator());
QString saveAsFilePath = storeDir + dirName.mid(lastSeparatorIndex+); // 另存为的路径 QAxWidget wordApplication("Word.Application");
QAxObject *documents = wordApplication.querySubObject("Documents");
documents->dynamicCall("Open(const QString&)", dirName);
wordApplication.setProperty("Visible", QVariant(false));
QAxObject* m_doc = wordApplication.querySubObject("ActiveDocument"); // 获取当前工作簿
QAxObject* pRange = m_doc->querySubObject("Content()"); if (NULL != pRange)
{
// 查找关键字
QAxObject *pFind = pRange->querySubObject("Find()");
QStringList keyWordsPosition;
if (NULL != pFind)
{
pFind->dynamicCall("ClearFormatting()");
pFind->setProperty("Format", true);
pFind->setProperty("MatchCase", false);
pFind->setProperty("MatchWholeWord", false);
pFind->setProperty("MatchByte", true);
pFind->setProperty("MatchWildcards", false);
pFind->setProperty("MatchSoundsLike", false);
pFind->setProperty("MatchAllWordForms", false); for (int i=; i<keyWords.size(); ++i){
// 找到关键字所在的位置,得到一个position,将position添加到keyWordsPosition中。
QString keyWord = keyWords.at(i);
QStringList position = findKeyWordsPosition(pRange->property("Text").toString(), keyWord);
if (!position.contains("")){
keyWordsPosition << position; pFind->setProperty("Text", keyWord);
pFind->dynamicCall("Execute()");
while (pFind->property("Found").toBool())
{
bool isHighlight = pFind->parent()->setProperty("HighlightColorIndex","wdYellow");
pFind->dynamicCall("Execute()"); if (!isHighlight)
{
delete pFind;
pFind = NULL;
delete pRange;
pRange = NULL;
m_doc->dynamicCall("Close(boolean)", true);
wordApplication.dynamicCall("Quit ()");
delete m_doc;
m_doc = NULL;
return false;
}
}
}
}
}
if (keyWordsPosition.size() >= ){
QString fileName = dirName.mid(lastSeparatorIndex+);
QString filePath = dirName.mid(, lastSeparatorIndex+);
fileNameList << fileName;
filePathList << filePath;
keyWordsPositionList << keyWordsPosition; m_doc->dynamicCall("SaveAs(const QString)", saveAsFilePath);
}
delete pFind;
pFind = NULL;
delete pRange;
pRange = NULL;
m_doc->dynamicCall("Close(Boolean)", true);
m_doc->dynamicCall("Quit()");
delete m_doc;
m_doc = NULL;
return true;
}
return true;
}

下面这个是直接删除操作函数

// dirName:是待检查文件的路径;keyWords:是要查找的关键字(查找的关键字可能是多个)
bool directDeleteKeyWordsinWordFile(QString dirName, QStringList keyWords)
{
int lastSeparatorIndex = dirName.lastIndexOf(QDir::separator());
QString saveAsFilePath = storeDir + dirName.mid(lastSeparatorIndex+); // 另存为的路径 QAxWidget wordApplication("Word.Application");
QAxObject *documents = wordApplication.querySubObject("Documents");
documents->dynamicCall("Open(const QString&)", dirName);
wordApplication.setProperty("Visible", QVariant(false));
QAxObject* m_doc = wordApplication.querySubObject("ActiveDocument"); // 获取当前工作簿
QAxObject* pRange = m_doc->querySubObject("Content()");
QList<QVariant> vars; if (NULL != pRange)
{
// 查找关键字
QAxObject *pFind = pRange->querySubObject("Find()");
QStringList keyWordsPosition;
if (NULL != pFind)
{
pFind->dynamicCall("ClearFormatting()");
QAxObject *replacement = pFind->querySubObject("Replacement()");
replacement->dynamicCall("ClearFormatting()"); for (int i=; i<keyWords.size(); ++i){
QString keyWord = keyWords.at(i);
// 找到关键字所在的位置,得到一个position,将position添加到keyWordsPosition中。
QStringList position = findKeyWordsPosition(pRange->property("Text").toString(), keyWord);
if (!position.contains("")){
keyWordsPosition << position;
vars << keyWord << false << false << false << false
<< false << true << << false << ""
<< << false << false << false << false; // wdReplaceNone-->0;wdReplaceAll-->2;wdReplaceOne-->1
bool isReplaced = pFind->dynamicCall("Execute(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, "
"MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, "
"Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl)", vars).toBool();
if (!isReplaced){
delete pFind;
pFind = NULL;
delete pRange;
pRange = NULL;
m_doc->dynamicCall("Close(Boolean)", true);
m_doc->dynamicCall("Quit()");
delete m_doc;
m_doc = NULL;
QMessageBox openFileError(QMessageBox::Warning,
QObject::tr("文件处理错误"),
QObject::tr("文件 %1 处理错误,是否继续检查其他文件?").arg(dirName));
openFileError.addButton(QMessageBox::Yes);
openFileError.addButton(QMessageBox::No);
openFileError.setDefaultButton(QMessageBox::Yes);
if (openFileError.exec() == QMessageBox::No)
return false;
} }
}
}
if (keyWordsPosition.size() >= ){
QString fileName = dirName.mid(lastSeparatorIndex+);
QString filePath = dirName.mid(, lastSeparatorIndex+);
fileNameList << fileName;
filePathList << filePath;
keyWordsPositionList << keyWordsPosition; m_doc->dynamicCall("SaveAs(const QString)", saveAsFilePath);
}
delete pFind;
pFind = NULL;
delete pRange;
pRange = NULL;
m_doc->dynamicCall("Close(Boolean)", true);
m_doc->dynamicCall("Quit()");
delete m_doc;
m_doc = NULL;
return true;
}
return false;
}

好了,以上代码可能无法正常运行,因为缺少一些变量的定义、头文件的包含,我觉得这些你自己添加是完全OK的^-^。

因为自己需要的时候找不到资源,如果你也在找相似的资料,能给你带来帮助,我的目的就达到了,哈哈

我发现在网上下载Word VBA和Excel VBA帮助文档的时候需要金币什么的,很不方便。在此我还将Word VBA和Excel VBA帮助文档的百度网盘下载链接放在这里,供大家下载:

链接: https://pan.baidu.com/s/1-KTGdEVz_4C3yp_SBNlkIw 提取码: ri4p

有不足的地方,请指正。

通过QT查找Word中的关键字,并做高亮或删除操作的更多相关文章

  1. Word中的代码怎样语法高亮

    在平常我们粘贴代码到Word中的时候,经常会遇到代码粘贴到Word中后没有语法高亮,看着很乱很不友好,Word自带的样式---语法使用着也不尽人意, 网上有很多做法可以使得在插入在Word中的代码能够 ...

  2. word中使用MathType能做什么

    在Office中写论文,特别是一些比较专业的论文需要用到各种公式的.会发现有很多地方Office自带的公式编辑器都无法完成,所以要用到MathType公式编辑器这个好用的工具了.MathType是一款 ...

  3. MySQL查找数据中相同的数据,并进行删除

    查找表中多余的重复记录,重复记录是根据某个字段来判断 select * from 表名 where 字段 in (select 字段 from 表名 group by 字段 having count( ...

  4. Qt 向word中插入文字(使用QAxWidget和QAxObject)

    pro 文件中要加入 CONFIG += qaxcontainer 2. main.cpp #include <QApplication> #include <QAxWidget&g ...

  5. Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置

    QtreeView是ui中最常用的控件,Qt中QTreeWidget比QTreeView更简单,但没有QTreeView那么灵活(QTreeWidget封装的和MFC的CTreeCtrl很类似,没有m ...

  6. 在PHP中如何实现在做了么个操作后返回到指定页面

    我们经常会碰到类似用户在没有登录的情况下进行提问.评论,需要用户登录后返回刚才浏览的网页,这种功能用cookie保存当前url地址来实现.我用的是jquery,读者需要懂点jquery中的ajax请求 ...

  7. [Word]中批量修改图片大小和缩放比例方法

    最近小编遇到一个问题:需要将一篇厘米.打开.宏名起好了,单击"创建"进入.返回word,工具-宏-宏(或者直接按Alt+F8),再次进入宏的界面,选择刚才编辑好的宏,并单击&quo ...

  8. C# 在word中查找及替换文本

    C# 在word中查找及替换文本 在处理word文档时,很多人都会用到查找和替换功能.尤其是在处理庞大的word文档的时候,Microsoft word的查找替换功能就变得尤为重要,它不仅能让我们轻易 ...

  9. 用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理

    用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理 我测了一组数据存到txt文件中,是个WIFI信号强度文档,里面有我们需要得到的数据,有没用的数据,想用matla ...

随机推荐

  1. shiro框架学习-3- Shiro内置realm

    1. shiro默认自带的realm和常见使用方法 realm作用:Shiro 从 Realm 获取安全数据 默认自带的realm:idae查看realm继承关系,有默认实现和自定义继承的realm ...

  2. shiro框架学习-1-shiro基本概念

    1. 什么是权限控制 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源, ...

  3. 为什么要重写hashcode( )和equals( )?

    打个比方,一个名叫张三的人去住酒店,在前台登记完名字就去了99层100号房间,此时警察来前台找叫张三的这个人住在哪间房,经过查询,该酒店住宿的有50个叫张三的,需要遍历查询,查询起来很不方便. 那么就 ...

  4. docker跨主机通信-overlay

    使用consul 1,让两个网络环境下的容器互通,那么必然涉及到网络信息的同步,所以需要先配置一下consul. 直接运行下面命令.启动consul. docker run -d -p 8500:85 ...

  5. SpringBoot 入门实战篇

    SpringBoot入门 使用SpringBoot + mysql + Jpa 快速搭建一个spring项目 Spring Boot 2 + Spring Data JPA + MySQL 8 簡單範 ...

  6. 【spoj2774】最长公共子串

    题目描述: 给你两个字符串,求它们最长公共子串的长度,如果不存在公共子串则输出0. 样例输入: yeshowmuchiloveyoumydearmotherreallyicannotbelieveit ...

  7. Rust:剑指C++

    Rust:极富活力和前途的编程语言,剑指C++ 今天开始学习Rust,马上要回去休息了,只贴上一段实例代码,在后续的学习中,会对这种语言进行一个详尽的介绍(学习中....). extern crate ...

  8. [BZOJ4011][HNOI2015]落忆枫音:拓扑排序+容斥原理

    分析 又是一个有故事的题目背景.作为玩过原作的人,看题目背景都快看哭了ToT.强烈安利本境系列,话说SP-time的新作要咕到什么时候啊. 好像扯远了嘛不管了. 一句话题意就是求一个DAG再加上一条有 ...

  9. HDU1847--Good Luck in CET-4 Everybody!(SG函数)

    Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...

  10. Java数据结构之排序---快速排序

    快速排序是对冒泡排序的一种改进. 快速排序的基本思想: 假设我们以升序为例,它的执行流程可以概括为,每一趟选择当前所有子序列中的一个关键字(通常我们选择第一个,下述代码实现选择的也是第一个数)作为枢纽 ...