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

相关文章

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

Java利用poi实现word表格转excel

《Java利用poi实现word表格转excel》这篇文章主要为大家详细介绍了Java如何利用poi实现word表格转excel,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、每行对象类需要针对不同的表格进行对应的创建。package org.example.wordToEx