Qt操作Word文档
程序员文章站
2022-04-09 16:45:37
...
Qt提供QAxObject操作Word文档,实现写入文档
准备工作
1.Qt pro文件中加入QT += axcontainer
2.电脑上至少有Word或者WPS
操作Word
/********************************************************************
@brief: 通用的word操作类,报告创建一个word,保存,打印,表格操作,字体操作
注意:表格中的索引均是从1开始
*********************************************************************/
#ifndef WORDOPERATE_H
#define WORDOPERATE_H
#include <QObject>
#include <QObject>
#include <ActiveQt/QAxWidget>
#include <ActiveQt/QAxObject>
#include <QTextBlockFormat>
#include <qtextedit.h>
class WordOperate : public QObject
{
Q_OBJECT
public:
enum AlignmentType{
AlignmentTypeLeft,
AlignmentTypeCenter,
AlignmentTypeRight
};
enum SpaceType//
{
Space1,
Space15,
Space2,
SpaceAtLeast,
SpaceExactly,
SpaceMuti
};
explicit WordOperate(QObject *parent = 0);
WordOperate(const QString& strFile, QObject *parent = 0);
~WordOperate();
bool open(bool bVisable = false);
bool open(const QString& strFile, bool bVisable = true);
bool close();
bool isOpen();
void save();
bool saveAs(const QString& strSaveFile);
// 创建表格
void intsertTable(int row, int column);
// 设置表格内容
QAxObject* setCellString(int nTable, int row, int column, const QString& text);
// 合并单元格
void MergeCell(int nTable,int nStartRow,int nStartCol,int nEndRow,int nEndCol,bool bVerticalCenter = false );
//拆分单元格
void SplitCell(int nTable,int nStartRow,int nStartCol,int nRow,int nCol);
// 在表格中插入图片
void insertCellPic(int nTable, int row,int column,const QString& picPath);
// 设置文字
void SetFont(QString strFamily,int nSize,bool bBold = false,bool bItalic = false,bool bUnderLine = false);
// 设置表格文字字体
void SetTableFont(QAxObject* cell,QString strFamily,int nSize,bool bBold = false,bool bItalic = false);
// 设置表格文字字体
void SetTableFont(int nTable,int row,int column,QString strFamily,int nSize,bool bBold = false,bool bItalic = false,bool bUnderLine=false);
// 设置对其方式
void SetAlign(AlignmentType nAlign);
// 打印当期前document
void Print();
void Print(int nPageFrom,int nPageTo);
//光标移到末尾
void moveForEnd();
//插入图片
void InsertPicture(QString picturePath);
//插入文字
void SetText(QString strText);
//获取页边距
void GetPageMargin(double &dbLeft,double &dbTop,double &dbRight,double &dbBottom);
//设置页边距
void SetPageMargin(double dbLeft,double dbTop,double dbRight,double dbBottom);
//设置文档可见
void SetVisible(bool bVisable = true);
//设置表格行高
bool SetTableRowHeight(int nTable,int row,int height);
//设置段落行间距
void SetParagraphSpacing(SpaceType type,int space=0);
//设置列宽
void SetColumnWidth(int nTable, int column, int width);
//隐藏表格边框
void HideBorder(int nTable,int row,int column,int item);
//增加table行
void AddTableRow(int tableIndex ,int nRow,int rowCount);
public:
QAxObject *m_wordDocuments;
QAxObject *m_wordWidget;
QAxObject *m_selection;
private:
bool m_bOpened;
QString m_strFilePath;
signals:
public slots:
};
#endif // WORDOPERATE_H
提示
建议使用注册表查询是否存在word或者wps,QAxObject::setControl()
有几率卡住
/********************************************************************
@brief: word通用操作类
*********************************************************************/
#include "WordOperate.h"
#include "qt_windows.h"
WordOperate::WordOperate(QObject *parent):QObject(parent),
m_bOpened(false),
m_wordDocuments(NULL),
m_wordWidget(NULL),
m_selection(NULL)
{
}
WordOperate::WordOperate(const QString &strFile, QObject *parent):QObject(parent),
m_bOpened(false),
m_wordDocuments(NULL),
m_wordWidget(NULL),
m_selection(NULL),
m_strFilePath(strFile)
{
}
WordOperate::~WordOperate()
{
close();
}
/******************************************************************************
* 函数:open
* 功能:打开文件
* 参数:bVisable 是否显示弹窗
* 返回值: bool
*****************************************************************************/
bool WordOperate::open(bool bVisable)
{
//新建一个word应用程序,并设置为可见
m_wordWidget = new QAxObject();
bool bFlag = m_wordWidget->setControl( "word.Application" );
// bool bFlag = false;//使用wps打开报告
if(!bFlag)
{
// 用wps打开
bFlag = m_wordWidget->setControl( "kwps.Application" );
if(!bFlag)
{
return false;
}
}
m_wordWidget->setProperty("Visible", false);
//获取所有的工作文档
QAxObject *document = m_wordWidget->querySubObject("Documents");
if(!document)
{
return false;
}
//以文件template.dot为模版新建一个文档
document->dynamicCall("Add(QString)", m_strFilePath);
//获取当前**的文档
m_wordDocuments = m_wordWidget->querySubObject("ActiveDocument");
m_selection = m_wordWidget->querySubObject("Selection");
m_selection->dynamicCall("InsertAfter(QString&)", "\n");
m_bOpened = true;
return m_bOpened;
}
/******************************************************************************
* 函数:open
* 功能:打开文件
* 参数:strFilePath 文件路径;bVisable 是否显示弹窗
* 返回值:bool
*****************************************************************************/
bool WordOperate::open(const QString& strFilePath, bool bVisable)
{
m_strFilePath = strFilePath;
close();
return open(bVisable);
}
/******************************************************************************
* 函数:close
* 功能:关闭文件
* 参数:无
* 返回值:bool
*****************************************************************************/
bool WordOperate::close()
{
if (m_bOpened)
{
m_wordDocuments->dynamicCall("Close (bool)", false);
m_wordWidget->dynamicCall("Quit()");
m_bOpened = false;
delete m_wordWidget;
m_wordWidget = NULL;
}
return m_bOpened;
}
/******************************************************************************
* 函数:isOpen
* 功能:获得当前的打开状态
* 参数:无
* 返回值:bool
*****************************************************************************/
bool WordOperate::isOpen()
{
return m_bOpened;
}
/******************************************************************************
* 函数:save
* 功能:保存文件
* 参数:无
* 返回值:void
*****************************************************************************/
void WordOperate::save()
{
m_wordDocuments->dynamicCall("Save()");
}
/********************************************************************
description: 打印当前文档
返 回 值:
参 数:
********************************************************************/
void WordOperate::Print()
{
m_wordDocuments->dynamicCall("PrintOut()");
}
void WordOperate::Print(int nPageFrom,int nPageTo)
{
QList<QVariant> vars;
vars.push_back(QVariant(true));//background
vars.push_back(QVariant(false));//append
vars.push_back(QVariant("wdPrintRangeOfPages"));//range
vars.push_back(QVariant(""));//OutputFileName
vars.push_back(QVariant(nPageFrom));//From
vars.push_back(QVariant(nPageTo));//To
vars.push_back(QVariant("_wdPrintDocumentContent"));//Item
vars.push_back(QVariant(1));//Copy
vars.push_back(QVariant("1"));//Pages
vars.push_back(QVariant("_wdPrintAllPages"));//PageType
vars.push_back(QVariant(false));//PrintToFile
vars.push_back(QVariant(true));//Collate
vars.push_back(QVariant(""));//FileName
vars.push_back(QVariant(false));//ManualDuplexPrint
vars.push_back(QVariant(0));//PrintZoomCulumn
vars.push_back(QVariant(0));//PrintZoomRow
vars.push_back(QVariant(0));//PrintZoomPaperWidth
vars.push_back(QVariant(0));//PrintZoomPaperHeight
m_wordDocuments->dynamicCall("PrintOut(bool,bool,const QString&,const QString&,int,int,const QString&,int,const QString&,const QString&,bool,bool,const QString&,bool,int,int,int,int)",vars);
}
/******************************************************************************
* 函数:saveAs
* 功能:另存文件
* 参数:strSaveFile 文件路径
* 返回值:void
*****************************************************************************/
bool WordOperate::saveAs(const QString& strSaveFile)
{
return m_wordDocuments->dynamicCall("SaveAs (const QString&)",
strSaveFile).toBool();
}
/******************************************************************************
* 函数:intsertTable
* 功能:创建表格
* 参数:row hang; column 列
* 返回值: void
*****************************************************************************/
void WordOperate::intsertTable(int row, int column)
{
m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
//selection->dynamicCall("TypeText(QString&)", "Table Test");//设置标题
QAxObject *range = m_selection->querySubObject("Range");
QAxObject *tables = m_wordDocuments->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.toLatin1().data());
borders->dynamicCall("SetLineStyle(int)",1);
}
}
/******************************************************************************
* 函数:setCellString
* 功能:设置表格内容
* 参数:nTable 表格; row 行数; column 列数; text 插入文本
* 返回值:void
*****************************************************************************/
QAxObject* WordOperate::setCellString(int nTable, int row, int column, const QString& text)
{
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
if(table)
{
table->querySubObject("Cell(int, int)", row, column)
->querySubObject("Range")
->dynamicCall("SetText(QString)", text);
return table->querySubObject("Cell(int, int)", row, column);
}
}
/******************************************************************************
* 函数:insertCellPic
* 功能:在表格中插入图片
* 参数:nTable 表格; row 插入行; column 列数; picPath 图片路径
* 返回值:void
*****************************************************************************/
void WordOperate::insertCellPic(int nTable, int row, int column,
const QString& picPath)
{
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
QAxObject* range = table->querySubObject("Cell(int, int)", row, column)
->querySubObject("Range");
range->querySubObject("InlineShapes")
->dynamicCall("AddPicture(const QString&)",picPath);
}
/********************************************************************
description: 合并单元格
返 回 值: nTable 表格索引,从1开始
nStartRow合并起始行,从1开始,nStartCol合并起始列,从1开始
nEndRow合并终止行,nEndCol合并终止列
参 数:
********************************************************************/
void WordOperate::MergeCell(int nTable, int nStartRow, int nStartCol, int nEndRow, int nEndCol,bool bVerticalCenter)
{
QAxObject* tables = m_wordDocuments->querySubObject("Tables");
QAxObject* table = tables->querySubObject("Item(int)",nTable);
QAxObject* StartCell =table->querySubObject("Cell(int, int)",nStartRow,nStartCol);
QAxObject* EndCell = table->querySubObject("Cell(int, int)",nEndRow,nEndCol);
StartCell->querySubObject("Merge(QAxObject *)",EndCell->asVariant());
//设置对齐方式 -上下对齐
if(bVerticalCenter)
StartCell->dynamicCall("VerticalAlignment", "wdCellAlignVerticalCenter");
else
{
m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphJustify");
StartCell->dynamicCall("VerticalAlignment", "wdCellAlignVerticalTop");
}
}
/********************************************************************
description: 拆分单元格
返 回 值:
参 数: nTable 表格索引,从1开始,nStartRow行号,从1开始,nStartCol列号,从1开始
nRow为要拆分的行数,nCol为要拆分的列数
********************************************************************/
void WordOperate::SplitCell(int nTable, int nStartRow, int nStartCol, int nRow, int nCol)
{
QAxObject* tables = m_wordDocuments->querySubObject("Tables");
QAxObject* table = tables->querySubObject("Item(int)",nTable);
QAxObject* StartCell =table->querySubObject("Cell(int, int)",nStartRow,nStartCol);
StartCell->querySubObject("Split(int,int)",nRow,nCol);
}
/********************************************************************
description: 设置对齐方式
返 回 值: nAlign对齐方式 0-左对齐 1居中 2右对齐
参 数:
********************************************************************/
void WordOperate::SetAlign(AlignmentType nAlign)
{
switch(nAlign)
{
case 0:
m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphLeft");
break;
case 1:
m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter");
break;
case 2:
m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphRight");
break;
}
}
void WordOperate::SetTableFont(QAxObject* cell, QString strFamily, int nSize, bool bBold, bool bItalic)
{
QAxObject *font = cell->querySubObject("Select");
m_selection->querySubObject("Font")->setProperty("Name", strFamily);
m_selection->querySubObject("Font")->setProperty("Size", nSize);
m_selection->querySubObject("Font")->setProperty("Bold", bBold);
m_selection->querySubObject("Font")->setProperty("Italic", bItalic);
m_selection->dynamicCall("MoveRight(const QString&,int)", "wdCharacter",1);
}
/********************************************************************
description: 设置Table cell字体
返 回 值:
参 数: nTable 表格编号
row 行号
column 列号
strFamily 字体名称
nSize 字号
bBold 加粗
bItalic 斜体
bool 下划线
********************************************************************/
void WordOperate::SetTableFont(int nTable,int row,int column,QString strFamily,int nSize,bool bBold ,bool bItalic,bool bUnderLine)
{
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
if(table)
{
QAxObject* range = table->querySubObject("Cell(int, int)", row, column)
->querySubObject("Range");
range->querySubObject("Font")
->setProperty("Name", strFamily);
range->querySubObject("Font")->setProperty("Size", nSize);
range->querySubObject("Font")->setProperty("Bold", bBold);
range->querySubObject("Font")->setProperty("Italic", bItalic);
if(bUnderLine)
range->querySubObject("Font")->setProperty("Underline",2);
else
range->querySubObject("Font")->setProperty("Underline",0);
//为Table的一行设置字体
// QAxObject* rowRange = table->querySubObject("Rows(int)",row)->querySubObject("Select");
// m_selection->querySubObject("Font")->setProperty("Name", strFamily);
// m_selection->querySubObject("Font")->setProperty("Size", nSize);
// m_selection->querySubObject("Font")->setProperty("Bold", bBold);
// m_selection->querySubObject("Font")->setProperty("Italic", bItalic);
}
}
/********************************************************************
description: 设置字体
返 回 值: strFamily 字体,nSize 字号,bBold 粗体,bItalic 斜体
参 数:
********************************************************************/
void WordOperate::SetFont(QString strFamily, int nSize, bool bBold, bool bItalic,bool bUnderLine)
{
m_selection->querySubObject("Font")->setProperty("Name", strFamily);
m_selection->querySubObject("Font")->setProperty("Size", nSize);
m_selection->querySubObject("Font")->setProperty("Bold", bBold);
m_selection->querySubObject("Font")->setProperty("Italic", bItalic);
if(bUnderLine)
m_selection->querySubObject("Font")->setProperty("Underline",2);
else
m_selection->querySubObject("Font")->setProperty("Underline",0);
}
void WordOperate::InsertPicture(QString picturePath)
{
m_selection->querySubObject("InlineShapes")->dynamicCall("AddPicture(const QString&)",picturePath);
}
void WordOperate::moveForEnd()//光标移到末尾
{
QAxObject* selection = m_wordWidget->querySubObject("Selection");
QVariantList params;
params.append(6);
params.append(0);
selection->dynamicCall("EndOf(QVariant&, QVariant&)", params).toInt();
}
void WordOperate::SetText(QString strText)
{
m_selection->dynamicCall("TypeText(QString&)", strText);
}
void WordOperate::GetPageMargin(double &dbLeft, double &dbTop, double &dbRight, double &dbBottom)
{
QAxObject* pageSetup = m_selection->querySubObject("PageSetup");
dbLeft = pageSetup->property("LeftMargin").toDouble();
dbTop = pageSetup->property("TopMargin").toDouble();
dbRight = pageSetup->property("RightMargin").toDouble();
dbBottom = pageSetup->property("BottomMargin").toDouble();
}
void WordOperate::SetVisible(bool bVisable)
{
m_wordWidget->setProperty("Visible", bVisable);
}
void WordOperate::SetPageMargin(double dbLeft, double dbTop, double dbRight, double dbBottom)
{
QAxObject* pageSetup = m_selection->querySubObject("PageSetup");
pageSetup->setProperty("LeftMargin",dbLeft);
pageSetup->setProperty("RightMargin",dbRight);
pageSetup->setProperty("TopMargin",dbTop);
pageSetup->setProperty("BottomMargin",dbBottom);
}
bool WordOperate::SetTableRowHeight(int nTable,int row,int height)
{
bool flag=false;
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
if(table)
{
QAxObject* cell =table->querySubObject("Cell(int, int)",row,1);
flag = cell->setProperty("HeightRule", "wdRowHeightExactly");//wdRowHeightAtLeast wdRowHeightExactly wdRowHeightAuto
if(cell)
flag = cell->setProperty("Height", height);
}
return flag;
}
void WordOperate::SetParagraphSpacing(SpaceType type,int space)
{
QAxObject* para = m_selection->querySubObject("ParagraphFormat");
switch (type) {
case Space1:
para->setProperty("LineSpacingRule","wdLineSpaceSingle");
break;
case Space15:
para->setProperty("LineSpacingRule","wdLineSpace1pt5");
break;
case Space2:
para->setProperty("LineSpacingRule","wdLineSpaceDouble");
break;
case SpaceAtLeast:
para->setProperty("LineSpacingRule","wdLineSpaceAtLeast");
para->setProperty("LineSpacing",space);
break;
case SpaceExactly:
para->setProperty("LineSpacingRule","wdLineSpaceExactly");
para->setProperty("LineSpacing",space);
break;
case SpaceMuti:
para->setProperty("LineSpacingRule","wdLineSpaceMultiple");
para->setProperty("LineSpacing",space);
break;
default:
break;
}
}
void WordOperate::SetColumnWidth(int nTable, int column, int width)
{
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
if(table)
{
QAxObject* colum = table->querySubObject("Columns(int)",column);
if(colum)
colum->setProperty("Width",width);
}
}
void WordOperate::HideBorder(int nTable, int row, int column, int item)
{
QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" );
QAxObject* table = pTables->querySubObject("Item(int)", nTable);
QAxObject* cell =table->querySubObject("Cell(int, int)",row,column);
QAxObject* border = cell->querySubObject("Borders(int)",item);
if(border)
border->setProperty("Visible",false);
/*
QAxObject* Borders = table->querySubObject("Borders");
Borders->setProperty("InsideLineStyle",1);
Borders->setProperty("OutsideLineStyle",1);
*/
}
void WordOperate::AddTableRow(int tableIndex ,int nRow,int rowCount)
{
QAxObject* tables=m_wordDocuments->querySubObject("Tables");
QAxObject* table = tables->querySubObject("Item(int)",tableIndex);
QAxObject* rows =table->querySubObject("Rows");
int Count =rows->dynamicCall("Count").toInt();
if(0< nRow && nRow <= Count )
{
for(int i =0; i< rowCount; ++i)
{
QString sPos = QString("Item(%1)").arg(nRow+i);
QAxObject* row= rows->querySubObject(sPos.toStdString().c_str());
QVariant param =row ->asVariant();
rows->dynamicCall("Add(Variant)",param);
}
}
}
可能出现问题
1.生成的文档在Android端打不开
2.如果用户电脑上无word或wps,试图打开操作会卡死,程序有几率崩溃
评价
可以用,但不是最佳…
上一篇: JavaScript检测并限制复选框选中个数的方法
下一篇: Word Ladder