这篇文章在原博客上加上了一些原博主没有写出的一些细节访问的东西,(间接抄袭.......)
原博客 :http://blog.youkuaiyun.com/zhangfuliang123/article/details/53413477
这个操作是利用 word模板(.dot)和书签进行操作 .所以,在运行此代码前,先制作好对应的模板,模板中设定好书签.
书签 的主要作用就是使用该程序的时候可以去搜索并且替换调书签位置的内容.以达到批量生成的目的;
看我测试的时候使用的模板
(设置书签:选择你要设置的文本,然后点下 word文档中的插入下面的书签就可以了)
主要方法
1、根据报告要求,设计word模板,定义好需要插入数据的标签,调好其他固定内容的格式。(以保证数据插入后文档内容排列有序)
2、编写word操作接口类,主要包括:打开、关闭、保存、插入文本、插入图片、插入表格、相关格式调整函数
3、编写生成报告界面类,调用接口函数生成word文档。
二、接口函数
WordEngine.h文件
#ifndef WORDENGINE_H
#define WORDENGINE_H
#include <QObject>
#include <QAxObject>
#include <QtCore>
class WordEngine : public QObject
{
Q_OBJECT
public:
explicit WordEngine(QObject *parent = 0);
//WordEngine();
~WordEngine();
/// 打开Word文件,如果sFile路径为空或错误,则打开新的Word文档
bool Open(QString sFile, bool bVisible = true);
void save(QString sSavePath);
void close(bool bSave = true);
bool replaceText(QString sLabel,QString sText);
bool replacePic(QString sLabel,QString sFile);
//插入一个几行几列表格
// QAxObject *insertTable(QString sLabel,int row,int column);
//插入一个几行几列表格 并设置表头
QAxObject *insertTable(QString sLabel,int row,int column,QStringList headList);
QAxObject *insertTable(QString sLabel,int column,QList<QStringList> headList);
//设置列宽
void setColumnWidth(QAxObject *table,int column, int width);
void SetTableCellString(QAxObject *table, int row,int column,QString text);
signals:
public slots:
private:
QAxObject *m_pWord; //指向整个Word应用程序
QAxObject *m_pWorkDocuments; //指向文档集,Word有很多文档
QAxObject *m_pWorkDocument; //指向m_sFile对应的文档,就是要操作的文档
QString m_sFile;
bool m_bIsOpen;
bool m_bNewFile;
};
#endif // WORDENGINE_H
WordEngine.cpp文件
#include "wordengine.h"
#include "WordEngine.h"
#include "qt_windows.h"
WordEngine::WordEngine(QObject *parent) : QObject(parent)
{
m_pWord = NULL;
m_pWorkDocuments = NULL;
m_pWorkDocument = NULL;
m_bIsOpen = false;
m_bNewFile = false;
HRESULT result = OleInitialize(0);
if (result != S_OK && result != S_FALSE)
{
qDebug()<<QString("Could not initialize OLE (error %x)").arg((unsigned int)result);
}
}
WordEngine::~WordEngine()
{
//if(m_bIsOpen)
// close();
OleUninitialize();
}
bool WordEngine::Open(QString sFile, bool bVisible)
{
//新建一个word应用程序
m_pWord = new QAxObject();
bool bFlag = m_pWord->setControl( "word.Application" );
if(!bFlag)
{
return false;
}
m_pWord->setProperty("Visible", bVisible);
//获取所有的工作文档
QAxObject *document = m_pWord->querySubObject("Documents");
if(!document)
{
return false;
}
//以文件template.dot为模版新建一个文档
document->dynamicCall("Add(QString)", sFile);
//获取当前激活的文档
m_pWorkDocument = m_pWord->querySubObject("ActiveDocument");
if(m_pWorkDocument)
m_bIsOpen = true;
else
m_bIsOpen = false;
return m_bIsOpen;
}
void WordEngine::save(QString sSavePath)
{
if(m_bIsOpen && m_pWorkDocument)
{
if(m_bNewFile){
m_pWorkDocument->dynamicCall("Save()");
}
else{
//m_pWorkDocument->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)",
// m_sFile,56,QString(""),QString(""),false,false);
m_pWorkDocument->dynamicCall("SaveAs (const QString&)", sSavePath);
}
}
qDebug()<<"save Done.";
}
void WordEngine::close(bool bSave)
{
if(bSave){
//save();
}
if(m_pWord){
m_pWord->setProperty("DisplayAlerts", true);
}
if(m_pWorkDocument){
m_pWorkDocument->dynamicCall("Close(bool)", true);
}
if(m_pWord){
m_pWord->dynamicCall("Quit()");
}
if(m_pWorkDocuments)
{
delete m_pWorkDocuments;
}
if(m_pWord)
{
delete m_pWord;
}
m_pWorkDocument = NULL;
m_pWorkDocuments = NULL;
m_pWord = NULL;
m_bIsOpen = false;
m_bNewFile = false;
}
bool WordEngine::replaceText(QString sLabel,QString sText)
{
if(!m_pWorkDocument){
return false;
}
//获取文档中名字为sLabel的标签
QAxObject *pBookmark = m_pWorkDocument->querySubObject("Bookmarks(QString)",sLabel);
if(pBookmark)
{
pBookmark->dynamicCall("Select(void)");
pBookmark->querySubObject("Range")->setProperty("Text",sText);
delete pBookmark;
}
return true;
}
bool WordEngine::replacePic(QString sLabel,QString sFile)
{
if(!m_pWorkDocument)
return false;
QAxObject *bookmark_pic = m_pWorkDocument->querySubObject("Bookmarks(QString)",sLabel);
if(bookmark_pic)
{
bookmark_pic->dynamicCall("Select(void)");
QAxObject *Inlineshapes = m_pWorkDocument->querySubObject("InlineShapes");
Inlineshapes->dynamicCall("AddPicture(const QString&)",sFile);
delete Inlineshapes;
}
return true;
}
//QAxObject *WordEngine::insertTable(QString sLabel, int row, int column)
//{
// QAxObject *bookmark = m_pWorkDocument->querySubObject("Bookmarks(QVariant)", sLabel);
// if(bookmark)
// {
// bookmark->dynamicCall("Select(void)");
// QAxObject *selection = m_pWord->querySubObject("Selection");
// selection->dynamicCall("InsertAfter(QString&)", "\n");
// //selection->dynamicCall("MoveLeft(int)", 1);
// selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
// //selection->dynamicCall("TypeText(QString&)", "Table Test");//设置标题
// QAxObject *range = selection->querySubObject("Range");
// QAxObject *tables = m_pWorkDocument->querySubObject("Tables");
// QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column);
// for(int i=1;i<=6;i++)
// {
// QString str = QString("Borders(-%1)").arg(i);
// QAxObject *borders = table->querySubObject(str.toLocal8Bit().constData());
// borders->dynamicCall("SetLineStyle(int)",1);
// }
// return table;
// }
// return NULL;
//}
QAxObject *WordEngine::insertTable(QString sLabel, int row, int column, QStringList headList)
{
QAxObject *bookmark = m_pWorkDocument->querySubObject("Bookmarks(QVariant)", sLabel);
if(headList.size() != column){
return NULL;
}
if(bookmark)
{
bookmark->dynamicCall("Select(void)");
QAxObject *selection = m_pWord->querySubObject("Selection");
selection->dynamicCall("InsertAfter(QString&)", "\r\n");
//selection->dynamicCall("MoveLeft(int)", 1);
selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
//设置标题
//selection->dynamicCall("TypeText(QString&)", "Table Test");
QAxObject *range = selection->querySubObject("Range");
QAxObject *tables = m_pWorkDocument->querySubObject("Tables");
QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column);
//表格自动拉伸列 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)", headList.at(i));
//加粗
table->querySubObject("Cell(int,int)",1,i+1)->querySubObject("Range")->dynamicCall("SetBold(int)", true);
}
for(int i=1;i<=6;i++)
{
QString str = QString("Borders(-%1)").arg(i);
QAxObject *borders = table->querySubObject(str.toLocal8Bit().constData());
borders->dynamicCall("SetLineStyle(int)",1);
}
return table;
}
return NULL;
}
/**
* @brief WordEngine::insertTable
* @param sLabel 模板中的标签
* @param column 某行最长列
* @param headList 数据 里面存放这每一行的数据
* @return
*/
QAxObject *WordEngine::insertTable(QString sLabel, int column, QList<QStringList> headList)
{
QAxObject *bookmark = m_pWorkDocument->querySubObject("Bookmarks(QVariant)", sLabel);
if(bookmark)
{
bookmark->dynamicCall("Select(void)");
QAxObject *selection = m_pWord->querySubObject("Selection");
selection->dynamicCall("InsertAfter(QString&)", "\r\n");
//selection->dynamicCall("MoveLeft(int)", 1);
selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
//设置标题
//selection->dynamicCall("TypeText(QString&)", "Table Test");
QAxObject *range = selection->querySubObject("Range");
QAxObject *tables = m_pWorkDocument->querySubObject("Tables");
QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),headList.size(),column);
//表格自动拉伸列 0固定 1根据内容调整 2 根据窗口调整
table->dynamicCall("AutoFitBehavior(WdAutoFitBehavior)", 2);
//设置表头和数据
for(int i=0;i<headList.size();i++){
QStringList columnList=headList.at(i);
for(int j=0;j<columnList.size();j++){
table->querySubObject("Cell(int,int)",i+1,j+1)->querySubObject("Range")->dynamicCall("SetText(QString)", columnList.at(j));
//加粗
table->querySubObject("Cell(int,int)",1,j+1)->querySubObject("Range")->dynamicCall("SetBold(int)", true);
}
}
for(int i=1;i<=6;i++)
{
QString str = QString("Borders(-%1)").arg(i);
QAxObject *borders = table->querySubObject(str.toLocal8Bit().constData());
borders->dynamicCall("SetLineStyle(int)",1);
}
return table;
}
return NULL;
}
void WordEngine::setColumnWidth(QAxObject *table, int column, int width)
{
if(!table){
return;
}
table->querySubObject("Columns(int)",column)->setProperty("Width",width);
}
void WordEngine::SetTableCellString(QAxObject *table, int row,int column,QString text)
{
if(!table)
return;
QAxObject *cell = table->querySubObject("Cell(int,int)",row,column);
if(!cell)
return ;
cell->dynamicCall("Select(void)");
cell->querySubObject("Range")->setProperty("Text", text);
}
我的测试方法:
void test(){
WordEngine *w=new WordEngine();
w->Open("e://b.doc",false);
// w->replaceText("a","test");
w->replacePic("a","D:/q.jpg");
QStringList list;
list.append("1");
list.append("2");
list.append("3");
list.append("4");
QStringList list2;
list2.append("5");
list2.append("6");
list2.append("7");
list2.append("8");
QList<QStringList> l1;
l1.append(list);
l1.append(list2);
w->insertTable("b",4,l1);
w->save("e://a.doc");
w->close();
}
'
然后按照原博主的一步一步来,就会发现报错了.这里还有一个坑,就是得在.pro 文件中加入
QT += axcontainer
然后如果还报错就 qmake一下.
还有,这种方式首先本地得安装好 word文档, 记得检查本地的word文档是否安装正确,注册表是否没出问题..
个人觉得这种方式缺陷很大....
the end;