本文主要是介绍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")
- 连接对象为QAxWidget类对象,GUI相关对象不能在子线程中进行操作,所以应该修改为QAxObject类对象。
- 如果对象为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、修改单元格属性后未生效
- 查看设置单元格为全局还是特定单元格。
- 是否设置属性后再插入数据。
- 属性字段是否正确。
- 单元格对象是否添加。
常见属性
- 以下是一些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文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!