在这篇帖子中我将详细讲述如何在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应该+2if(!cell) return;cell->dynamicCall("Select(void)");cell->querySubObject("Range")->setProperty("Text",data.at(row).at(column));delete cell;}}
}

不足之处

这种方法读写文档的效率非常低,但是在Qt中Qwidget的派生类都无法在子线程中运行,所以当文件内容比较多的时候我们能做的只有等……或许你有更好的方法,请一定告诉我(_ _)。゜zzZ

以上就是如何在Qt中创建Word文档并修改word文档内容。如有不明白的地方欢迎留言或通过下面的邮件地址交流,若帖子中有错误的地方同样欢迎留言批评指正,在此谢过路过的各位大神。

在Qt中使用已有模板创建新Word文档相关推荐

  1. Word处理控件Aspose.Words功能演示:使用C#创建MS Word文档

    Aspose.Words是一种高级Word文档处理API,用于执行各种文档管理和操作任务.API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word. A ...

  2. MFC创建新Excel文档并设置其中的格式和字体

    MFC创建新Excel文档并设置其中的格式和字体 转载 生成Excel.obl对象类excel.h 创建对象 [cpp] view plaincopyprint? Range m_ExlRge;    ...

  3. Freemarker - 根据模板动态生成word文档

    文章目录 Freemarker 根据模板动态生成word文档 Freemarker 介绍: Freemarker 使用: freemarker加载模板目录的方法 参考资料 Freemarker 根据模 ...

  4. ASP.NET里创建Microsoft Word文档

    原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] 本文是应在ASP.NET里创建Microsoft Word文档之需而写的.这篇文章演示了在ASP.NET里怎么创建 ...

  5. 快速将非Word中的不可编辑的公式转换为Word文档中公式编辑器里可编辑的公式的办法

      因为我最近需要翻译一篇外文文献,其中的公式比较多,如果我自己去Word里用公式编辑器编辑,那么会翻译的会很慢,于是就搞出了一套可以自动将非Word中的不可编辑的公式转换为Word中可编辑的公式的办 ...

  6. 在Delphi中很精确地控制生成的WORD文档的格式

    原文地址:http://blog.163.com/laidedou@126/blog/static/1150740632012036110729/ var    WordApplication1: T ...

  7. ftl模板生成的word文档打不开

    使用ftl用ftl模板生成的word文档打不开,一直未响应的可能问题如下: 1.word模板另存为xml格式文件的时候,选择Word 2003 XML格式(兼容问题) 2.模板中有图片的时候,将ftl ...

  8. java-制作flt模板,导出word文档带图片循环

    java-制作flt模板,导出word文档带图片循环 模板制作 制作xml 编辑xml文档 将xml模板转换为flt 编写工具类 导出word工具类 获取远程图片 使用示例 使用示例--springb ...

  9. Word处理控件Aspose.Words功能演示:使用 C++ 创建 MS Word 文档 (DOC/DOCX)

    Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务.API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word.此 ...

最新文章

  1. Fragment之间传递数据的方式
  2. 漫画:骚操作系列(灯泡开关的经典面试题)
  3. j函数 判断以 什么开头
  4. 深入探究递归神经网络:大牛级的训练和优化如何修成?
  5. MySql数据库学习--存储过程(1)
  6. 深入浅出Attribute (转载)
  7. 网络协议入门(OSI七层和TCP/IC四层协议)
  8. numpy基础(part11)--特征值与奇异值分解
  9. \Grokking Algorithms\简介与作者采访
  10. java中判断 101-200 之间有多少个素数,并输出所有的素数
  11. eclipse中复制导入的项目并且修改了项目名字,项目后面的括号显示原来项目的名字
  12. python机器学习库sklearn——岭回归(Ridge、RidgeCV)(L2正则化)
  13. 朋友圈我快看不下去了!
  14. 刘宇凡:苍井空卖内衣 典型的情怀产品
  15. dft频谱泄漏matlab,对于DFT频谱泄漏问题的研究
  16. Java 生成N位随机数的方法
  17. 中国过氧化二异丙苯市场投资状况分析与前景趋势研究报告2022年版
  18. python和scre_前端大牛们都学过哪些东西?
  19. 免费的静态网页托管_如何使用自动管道免费托管静态站点
  20. 前端基础-04-盒子模型

热门文章

  1. 模式设计学习——工厂设计与策略设计
  2. ChatGPT团队中,3个清华学霸,1个北大学霸,共9位华人
  3. 用于LaTeX Python代码展现的minted包的安装及运行该包时TeXworks编译命令的设置
  4. 如何查看Ubuntu版本号
  5. Nexus+Docker私服+GitLab的一些记录
  6. Simple and Effective Few-Shot Named Entity Recognition with Structured Nearest Neighbor Learning
  7. JUnit测试常用断言
  8. Spark中POJO与Dataset相互转换
  9. 【NLP CS224N笔记】Assignment 1 - Exploring Word Vectors
  10. 计算机考研网校班,计算机考研网校