Qt操作Word文档

mac2025-03-02  4

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,试图打开操作会卡死,程序有几率崩溃

评价

可以用,但不是最佳…
最新回复(0)