功能:可以新建一份word文档,并且在文档中自动设置(一部分)格式排版。在Qt4.8.1版本下。
方案思路:这个示例完成了大部分功能,很有用;
其他思路:
*利用写好的模板,向标签插入内容:这个例子思路很好,但是可能因为版本问题,没有调试通过,只能够打开word应用程序,不能生成文档。修改了两个绝对路径也不好使,希望后面有机会再调一调。
*还试过在生成“空白(三栏)”(word内置构建基块)页眉的时候,录制宏,然后把宏转换成C++语言,但是构建基块的语言不起作用。
问题:COM、ActiveX、Windows API、VBA到C++的转换。
这个地址提供了office的VBA的参考,需要把用到的转为C++语言。
需要用到:QAxObject和QAxWidget类,调用COM组件,和Word连接。
注意:工程中要加入.lib库
代码:
Pro文档:
#-------------------------------------------------
#
# Project created by QtCreator 2020-11-27T10:48:51
#
#-------------------------------------------------
QT += core gui
QT += qaxcontainer
LIBS += C:QtSDKDesktopQt4.8.1msvc2008libQAxContainerd.lib
LIBS += C:QtSDKDesktopQt4.8.1msvc2008libQAxServerd.lib
TARGET = QWord
TEMPLATE = app
SOURCES += main.cpp
QWord.cpp
generatedoc.cpp
HEADERS +=
QWord.h
generatedoc.h
FORMS +=
funcTest函数:
void QWord::funcTest()
{
QAxObject* viewPage = m_word->querySubObject("ActiveWindow");
viewPage->querySubObject("View")->querySubObject("SeekView")->querySubObject("WdSeekView","wdSeekCurrentPageHeader");
QAxObject* selection = m_word->querySubObject("Selection");
selection->querySubObject("HeaderFooter")->querySubObject("Range")->querySubObject("Text","text");
viewPage->querySubObject("View")->querySubObject("SeekView")->querySubObject("WdSeekView","wdSeekMainDocument");
QAxObject* view = m_word->querySubObject("View");
view->querySubObject("SeekView")->querySubObject("WdViewType","wdSeekCurrentPageHeader");
selection->dynamicCall("TypeText(const QString&)","test");
view->querySubObject("SeekView")->querySubObject("WdViewType","wdSeekMainDocument");
ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary) _
.PageNumbers(1).Alignment = wdAlignPageNumberCenter
// QAxObject* section = m_document->querySubObject("Sections(1)");
// section->querySubObject("Footers")->querySubObject("PageNumbers(1)");
// ActiveWindow.View.SeekView = WdSeekView.wdSeekCurrentPageFooter;
// this.Application.Selection.HeaderFooter.LinkToPrevious = false;
// this.Application.Selection.HeaderFooter.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
// ActiveWindow.ActivePane.Selection.InsertAfter(footer);
// //跳出页眉页脚设置
// ActiveWindow.View.SeekView = WdSeekView.wdSeekMainDocument;
// QAxObject* selection = m_word->querySubObject("Selection");
QAxObject* viewPage = m_word->querySubObject("ActiveWindow");
//页脚激活
QAxObject* selection = m_word->querySubObject("Selection");
viewPage->querySubObject("View")->querySubObject("WdSeekView","wdSeekCurrentPageFooter");
// selection->dynamicCall("TypeText(const QString&)","text");
// m_word->querySubObject("Selection")->querySubObject("Footers")->querySubObject("Range")->dynamicCall("InsertAfter(QString&)","test");
QAxObject* section = m_document->querySubObject("Sections(1)");
section->querySubObject("Footers(wdHeaderFooterPrimary)")->querySubObject("Range")->querySubObject("Text","第 页");
section->querySubObject("Footers(wdHeaderFooterPrimary)")->querySubObject("Range")->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphCenter");
// selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphCenter");
// section->querySubObject("Footers(wdHeaderFooterPrimary)")->querySubObject("PageNumbers")->querySubObject("Size","14");
section->querySubObject("Footers(wdHeaderFooterPrimary)")->querySubObject("PageNumbers")->dynamicCall("Add(int)",1);
section->querySubObject("Footers(wdHeaderFooterPrimary)")->querySubObject("Range")->querySubObject("Font")->setProperty("Name",(QString)"宋体");
// selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphRight");
//页脚关闭
viewPage->querySubObject("View")->querySubObject("WdSeekView","wdSeekMainDocument");
//页眉激活
viewPage->querySubObject("View")->querySubObject("WdSeekView","wdSeekCurrentPageHeader");
// QAxWidget* range = section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range");
// selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphJustify");
// section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range")->querySubObject("Text","测试 测试报告 ");
// section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range")->dynamicCall("Collapse(QVariant&)","wdCollapseEnd");
section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range")->dynamicCall("InsertDateTime(QVariant&, bool)","MM/dd/yyyy",false);
// section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range")->querySubObject("Font")->setProperty("Name",(QString)"宋体");
section->querySubObject("Headers(wdHeaderFooterPrimary)")->querySubObject("Range")->dynamicCall("InsertBefore(QString&)","测试 测试报告 ");
// QAxWidget* range = section->dynamicCall("SetRange(int, int)", 77,86);
// QAxObject* selection = m_word->querySubObject("Selection");
// selection->dynamicCall("SetRange(int, int)", 77,86);
// selection->querySubObject("Font")->setProperty("Name","Times New Roman");
// range->querySubObject("Font")->setProperty("Name",(QString)"Times New Roman");
// m_word->querySubObject("Selection")->querySubObject("Footers")->querySubObject("Range")->dynamicCall("InsertBefore(QString&)","test");
//页眉关闭
viewPage->querySubObject("View")->querySubObject("WdSeekView","wdSeekMainDocument");
}
funcTest函数用来设置三栏页眉和页脚页码,三栏页眉还没找到合适的方法。
还是需要完成后记录,之前写好的没上传,结果断电丢失了,虽然保存了,但新写的还是丢了。
其他参考内容:
C#的操作小结;
这也是一个例子,不过是Qt5的,没有再尝试,QWordDemo,有网盘链接;
InsertAfter。
202012041620
之前在main()函数里面实例化了一个QWord类的对象:word,然后调用word的成员函数顺序执行,这样的话main()函数里面的重复代码太多了,容易干扰。所以,新建了一个GenerateDoc类,它继承自QWord类,所以有QWord的所有成员函数,另外再加一个public成员函数:docAction(),在这个函数中,先初始化好一些标准,然后实例化一个QWord对象,并顺序执行成员函数,生成word文档。
GenerateDoc.h文件:
#ifndef GENERATEDOC_H
#define GENERATEDOC_H
#include "QWord.h"
class GenerateDoc : public QWord
{
Q_OBJECT
public:
explicit GenerateDoc(QWord *parent = 0);
~GenerateDoc();
void docAction();
signals:
public slots:
};
#endif // GENERATEDOC_H
它使用public方式继承了QWord类,定义了构造函数和析构函数;暂时没有定义信号和槽函数。
GenerateDoc.cpp文件:
#include "generatedoc.h"
#include <QtCore>
GenerateDoc::GenerateDoc(QWord *parent) :
QWord(parent)
{
}
GenerateDoc::~GenerateDoc()
{
}
//QWord的一系列动作都合在docAction函数中,顺序执行,无返回值,有参数列表
void GenerateDoc::docAction() //现在考虑参数
{
QTextCodec *codec = QTextCodec::codecForName("GB2312"); //标准的定义
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
QWord word;
word.createNewWord();
word.setPageOrientation(0); //页面纵向
word.setWordPageView(3); //页面视图
word.setFontSize(15); //字体大小
word.setParagraphAlignment(0); //下面文字置中
word.setFontBold(true); //字体加粗
word.setFontName((QString)"宋体");
word.insertText(QString("测试报告"));//插入文字
word.setFontBold(false); //字体加粗
word.insertMoveDown();
word.setParagraphAlignment(1); //下面文字置左
word.setFontSize(12);
word.insertMoveDown();
word.insertMoveDown();
word.insertText(QString(""));//插入文字
word.insertMoveDown();
word.funcTest();
word.close();
}
这样的话,main()函数中的语句会很少,很清楚。
main().cpp
#include "qword.h"
#include "generatedoc.h"
#include <QtGui/QApplication>
#include <QtCore>
#include <QMessageBox>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GenerateDoc geneTest;
geneTest.docAction();
// return a.exec();这句话加上的话,进程不能自动结束
}