Qt操作Word文檔

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,試圖打開操作會卡死,程序有機率崩潰

評價

可以用,但不是最佳…
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章