Qt-QAxObject类-导出为word文件

2023-10-25 03:59
文章标签 qt 导出 word qaxobject

本文主要是介绍Qt-QAxObject类-导出为word文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 简介
  • 代码实现
  • 常见问题解决
    • 1、QAxObject对象在子线程中连接失败
    • 2、添加QAxObject头文件后编译报错:“无法打开源文件”
    • 3、修改单元格属性后未生效
  • 常见属性

简介

  • 本文主要介绍QAxObject类导出为word文件操作。以实现导出一份成绩单为例,介绍可能会出现的问题,如何去解决。同时会将word中常用的一些属性枚举封装为函数进行介绍,方便读者理解。

代码实现

  • 代码分析详见注释
  • custome_output_file_service.h
#pragma once
#include <QObject>
#include <QAxObject>
#include <QTextCodec>
#include <QDateTime>
#include <QDebug>
#include "custome_output_file_global.h"class CustomeOutputFileService:public ICustomeOutputFile
{
public:CustomeOutputFileService();~CustomeOutputFileService();virtual bool CreateRecordWord(CyCString _path);virtual bool SetRecordInformation(CyCString _name, int _count);virtual bool InsertRecordData(vector<std::string> _data);virtual bool Close();private:QAxObject *		word_;QAxObject *		act_doc_;QString			file_path_;int				count_;QAxObject*		simulation_table_;
};
  • custome_output_file_service.cpp
#include "custome_output_file_service.h"
#include "qt_windows.h"CustomeOutputFileService::CustomeOutputFileService():count_(2)
{
}CustomeOutputFileService::~CustomeOutputFileService()
{
}bool CustomeOutputFileService::CreateRecordWord(CyCString _path)
{file_path_ = StdString2QString(_path);count_ = 2;//因为COM是在GUI线程初始化和销毁的,在新开的线程里面并没有初始化,所以得自己初始化。HRESULT r_com = OleInitialize(0);if (r_com != S_OK && r_com != S_FALSE){qDebug("Qt: Could not initialize OLE (error %x)",(unsigned int)r_com);}//创建word文档//指向整个word应用程序word_ = new QAxObject();if (!word_->setControl("word.Application"))return false;word_->setProperty("Visible", false);QAxObject *documents = word_->querySubObject("Documents");if (!documents)return false;documents->dynamicCall("Add(void)");//获取当前激活的文档act_doc_ = word_->querySubObject("ActiveDocument");if (act_doc_ == nullptr)return false;QAxObject* selection = word_->querySubObject("Selection");selection->querySubObject("Font")->setProperty("Size", 11);selection->dynamicCall("TypeText(const QString&)", "");return true;
}bool CustomeOutputFileService::SetRecordInformation(CyCString _name, int _count)
{//当前日期QDateTime cur_data_time = QDateTime::currentDateTime();QString data_time = cur_data_time.toString("yyyy-MM-dd hh:mm:ss");//设置标题风格及内容QAxObject* selection = word_->querySubObject("Selection");selection->querySubObject("Font")->setProperty("Size", 14);selection->querySubObject("Font")->setProperty("Bold", true);selection->querySubObject("ParagraphFormat")->setProperty("Alignment", "wdAlignParagraphCenter");selection->dynamicCall("TypeText(const QString&)", QStringLiteral("成绩单\n"));//设置成绩单信息风格及内容selection->querySubObject("Font")->setProperty("Size", 11);selection->querySubObject("Font")->setProperty("Bold", false);selection->querySubObject("ParagraphFormat")->setProperty("Alignment", "wdAlignParagraphLeft");selection->dynamicCall("TypeText(const QString&)", QStringLiteral("教师:%1 日期:%2\n").arg(StdString2QString(_name)).arg(data_time));//设置数据内容格式QAxObject* tables = act_doc_->querySubObject("Tables");QAxObject* range = selection->querySubObject("Range");simulation_table_ = tables->querySubObject("Add(QAxObject*, int, int)", range->asVariant(), _count + 1, 6);QAxObject* border_line1 = simulation_table_->querySubObject("Borders(1)");border_line1->dynamicCall("SetLineStyle(int)", 1);QAxObject* border_line2 = simulation_table_->querySubObject("Borders(2)");border_line2->dynamicCall("SetLineStyle(int)", 1);QAxObject* border_line3 = simulation_table_->querySubObject("Borders(3)");border_line3->dynamicCall("SetLineStyle(int)", 1);QAxObject* border_line4 = simulation_table_->querySubObject("Borders(4)");border_line4->dynamicCall("SetLineStyle(int)", 1);QAxObject* border_line5 = simulation_table_->querySubObject("Borders(5)");border_line5->dynamicCall("SetLineStyle(int)", 1);QAxObject* border_line6 = simulation_table_->querySubObject("Borders(6)");border_line6->dynamicCall("SetLineStyle(int)", 1);QAxObject* trange = simulation_table_->querySubObject("Range");trange->querySubObject("ParagraphFormat")->setProperty("Alignment", "wdAlignParagraphCenter");trange->querySubObject("Cells")->setProperty("VerticalAlignment", "wdCellAlignVerticalCenter");selection->querySubObject("Font")->setProperty("Bold", true);simulation_table_->querySubObject("Cell(int, int)", 1, 1)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("姓名"));simulation_table_->querySubObject("Cell(int, int)", 1, 2)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("学号"));simulation_table_->querySubObject("Cell(int, int)", 1, 3)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("班级"));simulation_table_->querySubObject("Cell(int, int)", 1, 4)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("实验场次"));simulation_table_->querySubObject("Cell(int, int)", 1, 5)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("成绩"));simulation_table_->querySubObject("Cell(int, int)", 1, 6)->querySubObject("Range")->dynamicCall("SetText(QString)", QStringLiteral("评语"));return true;
}//插入数据
bool CustomeOutputFileService::InsertRecordData(vector<std::string> _data)
{if (_data.size() == 0){return false;}for (int i = 0; i < _data.size(); ++i){simulation_table_->dynamicCall("AutoFitBehavior(int)", 6);simulation_table_->querySubObject("Rows(int)", count_)->setProperty("Height", 20);simulation_table_->querySubObject("Cell(int, int)", count_, i + 1)->querySubObject("Range")->dynamicCall("SetText(QString)", StdString2QString(_data.at(i)));}count_++;return true;
}//关闭连接
bool CustomeOutputFileService::Close()
{act_doc_->dynamicCall("SaveAs (const QString&)", file_path_);act_doc_->dynamicCall("Close(bool)", true);word_->dynamicCall("Quit()");//关闭COMOleUninitialize();return true;
}

常见问题解决

1、QAxObject对象在子线程中连接失败

 word_->setControl("word.Application")
  1. 连接对象为QAxWidget类对象,GUI相关对象不能在子线程中进行操作,所以应该修改为QAxObject类对象。
  2. 如果对象为QAxObject类对象还是连接失败,则查看COM是否在子线程初始化,如果没有添加如下代码
//因为COM是在GUI线程初始化和销毁的,在新开的线程里面并没有初始化,所以得自己初始化。HRESULT r_com = OleInitialize(0);if (r_com != S_OK && r_com != S_FALSE){qDebug("Qt: Could not initialize OLE (error %x)",(unsigned int)r_com);}

2、添加QAxObject头文件后编译报错:“无法打开源文件”

  • 原因在于当前工程中并没有包含相应的模块,需要到项目属性设置中添加相应模块,并添加相应附加包含目录和附加依赖项。如下图所示:
    在这里插入图片描述

3、修改单元格属性后未生效

  1. 查看设置单元格为全局还是特定单元格。
  2. 是否设置属性后再插入数据。
  3. 属性字段是否正确。
  4. 单元格对象是否添加。

常见属性

  • 以下是一些word中表格常用的一些属性( QAxObject* selection_ = m_pWord->querySubObject(“Selection”);)
/** 排版方式* 纵行、横行
*/selection_->querySubObject("PageSetup")->setProperty("Orientation","wdOrientLandscape");    //纵selection_->querySubObject("PageSetup")->setProperty("Orientation","wdOrientPortrait");     //横
/** 获取页宽
*/int width_;width_ = selection_->querySubObject("PageSetup")->property("PageWidth").toInt();;
/**设置字号
*/selection_->querySubObject("Font")->setProperty("Size",14);
/**设置对齐方式
*/selection_->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphCenter");    //居中对齐selection_->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphJustify");   //分散对齐selection_->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphRight");     //右对齐selection_->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphLeft");      //左对齐
/**插入文字
*/
selection_->dynamicCall("TypeText(const QString&)","hello world!");
/**插入图片
*/QString filename = file;filename.replace("/","\\");     //转义字符替换QAxObject *Inlineshapes = selection_->querySubObject("InlineShapes");Inlineshapes->dynamicCall("AddPicture(const QString&)",filename);delete Inlineshapes;
/**插入回车
*/
selection_->dynamicCall("TypeParagraph(void)");
/** 光标移到末尾,跳出单元格
*/QVariantList params;params.append(6);params.append(0);selection->dynamicCall("EndOf(QVariant&, QVariant&)", params).toInt();
/*创建表格QStringList headList 添加表头
*/QAxObject* MainWindow::createTable(int row, int column, QStringList head_list)
{QAxObject* selection  = m_pWord->querySubObject("Selection");if(!selection){return false;}selection->dynamicCall("InsertAfter(QString&)", "\r\n");QAxObject *range = selection->querySubObject("Range");QAxObject *tables = m_pWorkDocument->querySubObject("Tables");QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column);table->setProperty("Style","网格型");//表格自动拉伸列 0固定  1根据内容调整  2 根据窗口调整table->dynamicCall("AutoFitBehavior(WdAutoFitBehavior)", 2);//设置表头for(int i=0;i<headList.size();i++){table->querySubObject("Cell(int,int)",1,i+1)->querySubObject("Range")->dynamicCall("SetText(QString)", head_list.at(i));//加粗table->querySubObject("Cell(int,int)",1,i+1)->querySubObject("Range")->dynamicCall("SetBold(int)", true);}return table;
}/*填充表格
*/void MainWindow::setCellText(QAxObject *table, int row, int column, QString text)
{QAxObject* range = table->querySubObject("Cell(int, int)",row+1,column+1)->querySubObject("Range");if( range)return;range->dynamicCall("SetText(QString)", text);
}/*表格插入图片
*/
void MainWindow::setAddPicture(QAxObject *table, int row, int column, QString picPath)
{QAxObject* range = table->querySubObject("Cell(int, int)",row+1,column+1)->querySubObject("Range");if(!range)return;range->querySubObject("InlineShapes")->dynamicCall("AddPicture(const QString&)",picPath);
}/**光标跳转,类似表格中的tab
*/selection->dynamicCall("MoveRight(int)",1);

以上是对QAxObject导出word文档表格的一些简单操作,新人第一次发博客,如果此文帮助到你( •̀ ω •́ )✧,动动小手点个赞可好O(∩_∩)O。
原创文章,转载请标明本文出处。

这篇关于Qt-QAxObject类-导出为word文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/279881

相关文章

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

Java高效实现Word转PDF的完整指南

《Java高效实现Word转PDF的完整指南》这篇文章主要为大家详细介绍了如何用Spire.DocforJava库实现Word到PDF文档的快速转换,并解析其转换选项的灵活配置技巧,希望对大家有所帮助... 目录方法一:三步实现核心功能方法二:高级选项配置性能优化建议方法补充ASPose 实现方案Libre

Python批量替换多个Word文档的多个关键字的方法

《Python批量替换多个Word文档的多个关键字的方法》有时,我们手头上有多个Excel或者Word文件,但是领导突然要求对某几个术语进行批量的修改,你是不是有要崩溃的感觉,所以本文给大家介绍了Py... 目录工具准备先梳理一下思路神奇代码来啦!代码详解激动人心的测试结语嘿,各位小伙伴们,大家好!有没有想

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按