Qt利用QGraphicsScene编写Word排版工具导出PDF

本篇的目的是编写一个工具,能够方便的对富文本、表格、图片生成Report和导出PDF,并且必须要在ARM、MIPS平台的linux嵌入式系统中方便使用。

自定义Graphics图形系统

Graphic系统,可以良好的完成图形的编辑工作和显示工作,但是在嵌入式板子上并不能良好的工作,因为内部绘图机制在嵌入式屏幕上存在很大的失真问题。

QTEGraphicsItem

QTEGraphicsItem.h

#ifndef QTEGRAPHICSITEM_H
#define QTEGRAPHICSITEM_H

#include <QGraphicsItem>
#include <QGraphicsProxyWidget>

class QTEGraphicsItem : public QGraphicsItem
{
public:
    explicit QTEGraphicsItem(QTEGraphicsItem *parent = 0);

};

class QTEGraphicsTextItem : public QGraphicsTextItem
{
public:
    explicit QTEGraphicsTextItem(QTEGraphicsItem *parent = 0);


    // QGraphicsItem interface
public:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};


class QTEGraphicsSimpleTextItem : public QGraphicsSimpleTextItem
{
public:
    explicit QTEGraphicsSimpleTextItem(QTEGraphicsItem *parent = 0);

};


class QTEGraphicsPixmapItem : public QGraphicsPixmapItem
{
public:
    explicit QTEGraphicsPixmapItem(QTEGraphicsItem *parent = 0);

};

class QTEGraphicsRectItem : public QGraphicsRectItem
{
public:
    explicit QTEGraphicsRectItem(QTEGraphicsItem *parent = 0);


    // QGraphicsItem interface
public:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};


class QTEGraphicsLineItem : public QGraphicsLineItem
{
public:
    explicit QTEGraphicsLineItem(QTEGraphicsItem *parent = 0);


    // QGraphicsItem interface
public:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};




class QTEGraphicsPathItem : public QGraphicsPathItem
{
public:
    explicit QTEGraphicsPathItem(QTEGraphicsItem *parent = 0);

};


class QTEGraphicsEllipseItem : public QGraphicsEllipseItem
{
public:
    explicit QTEGraphicsEllipseItem(QTEGraphicsItem *parent = 0);

};


class QTEGraphicsPolygonItem : public QGraphicsPolygonItem
{
public:
    explicit QTEGraphicsPolygonItem(QTEGraphicsItem *parent = 0);

};

class QTEGraphicsItemGroup : public QGraphicsItemGroup
{
public:
    explicit QTEGraphicsItemGroup(QTEGraphicsItem *parent = 0);

};

class QTEGraphicsProxyWidget : public QGraphicsProxyWidget
{
public:
    explicit QTEGraphicsProxyWidget(QTEGraphicsItem *parent = 0);

};


#endif // QTEGRAPHICSITEM_H

QTEGraphicsItem.cpp

#include "hngraphicsitem.h"
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include "QTEDefine.h"

QTEGraphicsItem::QTEGraphicsItem(QTEGraphicsItem *parent) : QGraphicsItem(parent) {}


QTEGraphicsTextItem::QTEGraphicsTextItem(QTEGraphicsItem *parent) : QGraphicsTextItem(parent) {}


QTEGraphicsRectItem::QTEGraphicsRectItem(QTEGraphicsItem *parent) : QGraphicsRectItem(parent) {}


QTEGraphicsSimpleTextItem::QTEGraphicsSimpleTextItem(QTEGraphicsItem *parent) : QGraphicsSimpleTextItem(parent) {}


QTEGraphicsLineItem::QTEGraphicsLineItem(QTEGraphicsItem *parent) : QGraphicsLineItem(parent) {}


QTEGraphicsPixmapItem::QTEGraphicsPixmapItem(QTEGraphicsItem *parent) : QGraphicsPixmapItem(parent) {}


QTEGraphicsPathItem::QTEGraphicsPathItem(QTEGraphicsItem *parent) : QGraphicsPathItem(parent) {}


QTEGraphicsEllipseItem::QTEGraphicsEllipseItem(QTEGraphicsItem *parent) : QGraphicsEllipseItem(parent) {}


QTEGraphicsPolygonItem::QTEGraphicsPolygonItem(QTEGraphicsItem *parent) : QGraphicsPolygonItem(parent) {}


QTEGraphicsItemGroup::QTEGraphicsItemGroup(QTEGraphicsItem *parent) : QGraphicsItemGroup(parent) {}


QTEGraphicsProxyWidget::QTEGraphicsProxyWidget(QTEGraphicsItem *parent) : QGraphicsProxyWidget(parent) {}


void QTEGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QFont oldFont(painter->font());

    painter->setFont(font());
    //painter->fillRect(option->rect, Qt::SolidPattern);
    painter->drawText(option->rect, Qt::AlignCenter, toPlainText());

    if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
        ;

    if(toPlainText().contains("K1160"))
    {
        pline() << font().pointSize() << font().pixelSize();
        pline() << pos() << option->rect << option->exposedRect << toPlainText();
        pline() << option->matrix << option->matrix.mapRect(option->rect);
    }
    painter->setFont(oldFont);
}


void QTEGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen oldPen(painter->pen());

    qreal xratio = option->rect.width() / option->exposedRect.width();
    qreal yratio = option->rect.height() / option->exposedRect.height();

    QPen pn = pen();
    pn.setWidth(pn.width()*xratio);
    painter->setPen(pn);

    QLineF l = QLineF(option->rect.left(), option->rect.top(),
                          option->rect.right(), option->rect.top());

    painter->drawLine(l);
    if(0)
    {
        pline() << line() << l << option->rect << option->exposedRect;
        pline() << option->matrix << option->matrix.mapRect(option->rect);
    }

    painter->setPen(oldPen);
}


void QTEGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen oldPen(painter->pen());
    QBrush oldBrush(painter->brush());

    qreal xratio = option->rect.width() / option->exposedRect.width();
    qreal yratio = option->rect.height() / option->exposedRect.height();

    QPen pn = pen();
    pn.setWidth(pn.width()*xratio);
    painter->setPen(pn);

    QRectF r = QRectF(option->rect.left(), option->rect.top(),
                          option->rect.width(), option->rect.height());

    painter->setBrush(brush());
    painter->drawRect(r);

    if(0)
    {
        pline() << option->matrix << option->matrix.mapRect(option->rect) << r;
    }

    painter->setPen(oldPen);
    painter->setBrush(oldBrush);
}

QTEGraphicsScene

QTEGraphicsScene.h

#ifndef QTEGRAPHICSSCENE_H
#define QTEGRAPHICSSCENE_H

#include <QGraphicsScene>
#include "hngraphicsitem.h"

class QTEGraphicsScene : public QGraphicsScene
{
    Q_OBJECT
public:
    QTEGraphicsScene(QObject *parent = 0);
    QTEGraphicsScene(const QRectF &sceneRect, QObject *parent = 0);
    QTEGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = 0);
    virtual ~QTEGraphicsScene() {}

    void render(QPainter *painter,
                const QRectF &target = QRectF(), const QRectF &source = QRectF(),
                Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
    QTEGraphicsEllipseItem *addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
    inline QGraphicsEllipseItem *addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
    { return addEllipse(QRectF(x, y, w, h), pen, brush); }

    QTEGraphicsPathItem *addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush());
    QTEGraphicsPixmapItem *addPixmap(const QPixmap &pixmap);
    QTEGraphicsPolygonItem *addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush());
    QTEGraphicsTextItem *addText(const QString &text, const QFont &font = QFont());
    QTEGraphicsSimpleTextItem *addSimpleText(const QString &text, const QFont &font = QFont());
    QTEGraphicsProxyWidget *addWidget(QWidget *widget, Qt::WindowFlags wFlags = 0);
    QTEGraphicsLineItem *addLine(const QLineF &line, const QPen &pen = QPen());
    inline QTEGraphicsLineItem *addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen())
    { return addLine(QLineF(x1, y1, x2, y2), pen); }
    QTEGraphicsRectItem *addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
    inline QTEGraphicsRectItem *addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
    { return addRect(QRectF(x, y, w, h), pen, brush); }

signals:

public slots:


    // QGraphicsScene interface
protected:
    void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget = 0);

private:
};

#endif // QTEGRAPHICSSCENE_H

QTEGraphicsScene.cpp

#include "hngraphicsscene.h"
#include <QGraphicsItem>
#include <QPainter>
#include "QTEDefine.h"

QTEGraphicsScene::QTEGraphicsScene(QObject *parent) :
    QGraphicsScene(parent)
{
}

QTEGraphicsScene::QTEGraphicsScene(const QRectF &sceneRect, QObject *parent) :
    QGraphicsScene(sceneRect, parent)
{

}

QTEGraphicsScene::QTEGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent) :
    QGraphicsScene(x, y, width, height, parent)
{

}

/** * @brief QTEGraphicsScene::render * 经过测试,失真是由于render放缩QPainter和drawItems里面的itemPaint共同导致失真 * 现在规整理如下,原则:Qpainter不允许改变 * 重写itemPaint函数 * @param painter * @param target * @param source * @param aspectRatioMode */
void QTEGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source, Qt::AspectRatioMode aspectRatioMode)
{
    // Find the ideal x / y scaling ratio to fit a source into a target.
    QRectF sourceRect = sceneRect();
    QRectF targetRect = sourceRect;
    if(!source.isEmpty())
        sourceRect = source;
    if(!target.isEmpty())
        targetRect = target;

    qreal xratio = targetRect.width() / sourceRect.width();
    qreal yratio = targetRect.height() / sourceRect.height();

    QList<QGraphicsItem *> itemList = items();
    QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
    int numItems = itemList.size();
    for (int i = 0; i < numItems; ++i)
        itemArray[numItems - i - 1] = itemList.at(i);
    itemList.clear();

    painter->save();

    // Generate the style options
    QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
    for (int i = 0; i < numItems; ++i) {
        QGraphicsItem *item = itemArray[i];
        QStyleOptionGraphicsItem option;
        option.state = QStyle::State_None;
        if (item->isSelected())
            option.state |= QStyle::State_Selected;
        if (item->isEnabled())
            option.state |= QStyle::State_Enabled;
        if (item->hasFocus())
            option.state |= QStyle::State_HasFocus;
        if (item == mouseGrabberItem())
            option.state |= QStyle::State_Sunken;

        option.exposedRect = item->boundingRect();

        option.rect.setLeft(item->pos().x()*xratio);
        option.rect.setWidth(option.exposedRect.width()*xratio);
        option.rect.setTop(item->pos().y()*yratio);
        option.rect.setHeight(option.exposedRect.height()*yratio);

        //pline() << xratio << yratio << item->pos() << option.rect << option.exposedRect;

        styleOptionArray[i] = option;
    }
    // Render the scene.
    drawBackground(painter, targetRect);
    drawItems(painter, numItems, itemArray, styleOptionArray);
    drawForeground(painter, targetRect);
    delete [] itemArray;
    delete [] styleOptionArray;

    painter->restore();
}

QTEGraphicsTextItem *QTEGraphicsScene::addText(const QString &text, const QFont &font)
{
    QTEGraphicsTextItem* item = new QTEGraphicsTextItem;
    item->setFont(font);
    item->setPlainText(text);
    addItem(item);
    return item;
}

QTEGraphicsRectItem *QTEGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
{
    QTEGraphicsRectItem* item = new QTEGraphicsRectItem;
    item->setRect(rect);
    item->setPen(pen);
    item->setBrush(brush);
    item->moveBy(rect.x(), rect.y());
    addItem(item);
    return item;
}

QTEGraphicsLineItem *QTEGraphicsScene::addLine(const QLineF &line, const QPen &pen)
{
    QTEGraphicsLineItem* item = new QTEGraphicsLineItem;
    item->setLine(line);
    item->setPen(pen);
    item->moveBy(line.x1(), line.y1());

    addItem(item);
    return item;
}


void QTEGraphicsScene::drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget)
{
    for (int i = 0; i < numItems; ++i) {

        QTEGraphicsItem *item = (QTEGraphicsItem*)items[i];
        if (item->flags() & QGraphicsItem::ItemClipsToShape) {
            //painter->setClipPath(item->shape(), Qt::IntersectClip);
        }
        item->paint(painter, &options[i], widget);
    }

}

Word排版工具

支持添加Table、图片、文本,支持导出pdf、jpg、png、svg,支持预览。

QTEWordExpress

QTEWordExpress.h

#ifndef QTEWORDEXPRESS_H
#define QTEWORDEXPRESS_H

#include <QObject>
#include "hngui-qt.h"
#include "hnprinter.h"
#include "hngraphicsscene.h"

class QTEWordExpress : public QObject
{
    Q_OBJECT
public:
    explicit QTEWordExpress(QObject *parent = 0);

    void addText(const QString& text, QFont m_font = QFont(),
                 Qt::Alignment align = Qt::AlignHCenter, QPointF point= QPointF(0, 0));
    void addSignoffText(const QString& text, QFont m_font = QFont());
    void addTable(const QTableView* table, QPointF pos = QPointF(0, 0));

    int pageNum() { return pageSceneVector.size(); }
    QTEGraphicsScene* getPage(int num);
    void exportPdf(const QString &pdf);
    void print();

    QRectF margin();
    void setMargin(qreal left = 0, qreal right = 0,
                   qreal top = 0, qreal botoom = 0);
    void setLineSpacing(qreal mainSpacing = 0);
    void setHeaderSize(qreal size = 0);
    void setFooterSize(qreal size = 0);

    QFont font() { return m_font; }
    void setFont(QFont m_font = QFont());
    void setHeaderFont(QFont m_font = QFont());
    QFont mainFont() { return m_mainFont; }
    QFont titleFont() { return m_titleFont; }
    QFont title2Font() { return m_title2Font; }
    QFont headerFont() { return m_headerFont; }
    void setHeaderLine(bool show = false);
    void setFooterLine(bool show = false);
    void setHeaderText(const QString &text, QFont m_font = QFont(),
                       Qt::Alignment align = Qt::AlignHCenter);
    void setFooterText(const QString& text, QFont m_font = QFont(),
                       Qt::Alignment align = Qt::AlignHCenter);
    /** * @brief initWordExpress 初始化纸张,第一张空白纸 */
    void initWordExpress();

protected:
    virtual void adjustdy(qreal dy0);
    virtual void createFrame();
    virtual void paintPageHeader();
    virtual void paintPageFooter();
signals:

public slots:

private:
    //输出
    QTEPrinter* pr;
    //对页面元素高度不能迅速统计的场景
    QVector<QTEGraphicsScene*> pageSceneVector;
    QTEGraphicsScene* pageScene;

    //页面元素
    int logicalDpiX;
    int logicalDpiY;
    QRectF sceneRect;

    qreal xpos, xpos2, ypos, ypos2;
    qreal dx, dy;

    qreal leftMargin;
    qreal rightMargin;
    qreal topMargin;
    qreal bottomMargin;

    qreal mainHeight;
    qreal titleHeight;
    qreal title2Height;
    qreal headerHeight;
    qreal mainSpacing;
    qreal titleSpacing;
    qreal title2Spacing;
    qreal headerSpacing;

    //页眉
    qreal headerSize;
    QFont m_headerFont;
    QFontMetrics *headerFmt;
    QString headerText;
    //页脚
    qreal footerSize;
    QString footerStdText;
    QString footerText;
    //标题
    QFont m_titleFont;
    QFontMetrics *titleFmt;
    //二号标题
    QFont m_title2Font;
    QFontMetrics *title2Fmt;
    //正文
    QFont m_mainFont;
    QFontMetrics *mainFmt;
    //使用中
    QFont m_font;
    QFontMetrics *fmt;
};

#endif // QTEWORDEXPRESS_H

QTEWordExpress.cpp

#include "hnwordexpress.h"
#include "QTEDefine.h"

QTEWordExpress::QTEWordExpress(QObject *parent) :
    QObject(parent),
    fmt(0), mainFmt(0),headerFmt(0),titleFmt(0), title2Fmt(0)
{
    //setup printer
    pr= new QTEPrinter(QPrinter::HighResolution);
    pr->setFullPage(true);
    pr->setColorMode(QPrinter::Color);
    pr->setPaperSize(QPrinter::A4);
    pr->setOrientation(QPrinter::Portrait);
    pr->setOutputFormat(QPrinter::PdfFormat);

    //Font目标是打印纸上,所见即所得。
    //Pos目标不是纸上的,是屏幕上的,所以更换屏幕,必须更换DPI;
    //这个数值是迪文屏上的标准分辨率,打印机使用会失真;
    //迪文View 142,138 //PCView 96 //打印机View 1200
    //打印机分辨率1200不会失真,绘图必须进行坐标变换。
    //数值增大,DrawText可用空间减小甚至切掉一部分
#ifdef __MIPS_LINUX__
    //这是实验结果,和理论结果不符合。
    logicalDpiX = 136;
    logicalDpiY = 156;
#else
    logicalDpiX = 96;
    logicalDpiY = 96;
#endif

    QRect rect = pr->paperRect();
    sceneRect = QRectF(0.0, 0.0, logicalDpiX *rect.width()/pr->logicalDpiX(), logicalDpiY*rect.height()/pr->logicalDpiY());

#if 0
    //1200 9917,14033 printerRect 固定
    //116 958,1356 sceneRect
    //142 1113,1660 sceneRect
    pline() << pr->logicalDpiX() << pr->logicalDpiY();
    pline()  << logicalDpiX << logicalDpiY << pr->pageRect() << sceneRect;
    pline() << pr->paperRect(QPrinter::DevicePixel);
    pline() << pr->paperRect(QPrinter::Millimeter);
    pline() << pr->paperRect(QPrinter::Point);
    pline() << pr->paperRect(QPrinter::Inch);
    pline() << pr->paperRect(QPrinter::Pica);
    pline() << pr->paperRect(QPrinter::Didot);
    pline() << pr->paperRect(QPrinter::Cicero);
#endif

    m_mainFont = QApplication::font();
    if(mainFmt)
        delete mainFmt;
    mainFmt = new QFontMetrics(m_mainFont);
    m_titleFont= QApplication::font();
    m_titleFont.setPointSize(22);
    if(titleFmt)
        delete titleFmt;
    titleFmt = new QFontMetrics(m_titleFont);
    m_title2Font = QApplication::font();;
    m_title2Font.setPointSize(16);
    if(title2Fmt)
        delete title2Fmt;
    title2Fmt =new QFontMetrics(m_title2Font);

    setMargin();
    setHeaderSize();
    setFooterSize();

    setFont();
    setHeaderFont();
    setLineSpacing();

    setHeaderLine();
    setFooterLine();

    initWordExpress();
}

void QTEWordExpress::setMargin(qreal left, qreal right, qreal top, qreal botoom)
{
    leftMargin=134.6;
    rightMargin=134.6;
    topMargin=177.7;
    bottomMargin=177.7;
}

QRectF QTEWordExpress::margin()
{
    return QRectF(leftMargin, topMargin,
                  sceneRect.width()-leftMargin-rightMargin,
                  sceneRect.height()-topMargin-bottomMargin);
}

void QTEWordExpress::setFont(QFont font)
{
    //normal font 11
    m_font = QApplication::font();
    if(fmt)
        delete fmt;
    fmt = new QFontMetrics(m_font);
}

void QTEWordExpress::setLineSpacing(qreal spacing)
{
    //单倍行距
    mainHeight = mainFmt->height();
    titleHeight = titleFmt->height();
    title2Height = title2Fmt->height();
    headerHeight = headerFmt->height();

    mainSpacing = mainFmt->height() * 2;
    titleSpacing = titleFmt->height() * 2;
    title2Spacing = title2Fmt->height() * 2;
    headerSpacing = headerFmt->height() * 1;
}

void QTEWordExpress::addText(const QString &text, QFont font, Qt::Alignment align, QPointF point)
{
    QFontMetrics fmt = QFontMetrics(font);
    int spacing = fmt.height() * 2;
    int height = fmt.height();
    int width=fmt.width(text);

    pline() << font.pointSize() << fmt.height();

    adjustdy(height + spacing);

    QTEGraphicsTextItem* item = pageScene->addText(text, font);

    if(align & Qt::AlignLeft)
        item->moveBy(dx, dy+height);
    else if(align & Qt::AlignRight)
        item->moveBy(xpos2 - width, dy+height);
    else if(align & Qt::AlignHCenter)
        item->moveBy((pageScene->width()/2)-(width/2), dy+height);
    dy += height + spacing;
}

void QTEWordExpress::addSignoffText(const QString &text, QFont font)
{
    adjustdy(mainHeight + mainSpacing);

    int ddy = dy;

    dy = ypos2 - ( (mainHeight + mainSpacing) * 2 );

    addText(text, m_mainFont, Qt::AlignRight);

    dy = ddy;
}

void QTEWordExpress::addTable(const QTableView *table, QPointF pos)
{
    const QTableView *tableView = table;
    QAbstractItemModel* model = tableView->model();
    QFont tableFont = tableView->font();
    QFontMetrics tableFmt = QFontMetrics(tableFont);

    int tableRowHeight = tableView->horizontalHeader()->height();
    adjustdy(tableRowHeight);
    for (int i=0; i<model->columnCount(); i++) {
        int logicalIndex=tableView->horizontalHeader()->logicalIndex(i);
        int actColSize= tableView->columnWidth(logicalIndex);

        QPen pen(Qt::gray, 0.1);
        QBrush brush(QColor(255, 250, 250));
        //QBrush brush(tableView->horizontalHeader()->palette().background());
        pageScene->addRect(dx,dy, actColSize,tableRowHeight, pen, brush);

        QString txt = model->headerData(logicalIndex,Qt::Horizontal,Qt::DisplayRole).toString();
        txt = tableFmt.elidedText(txt, Qt::ElideRight, actColSize-2);
        QTEGraphicsTextItem *item = pageScene->addText(txt, tableFont);
        item->moveBy(dx, dy);
        dx += actColSize;
    }
    dy += tableRowHeight;

    //Table rows
    QPen pen(Qt::gray, 0.1);
    QBrush brush(Qt::gray, Qt::SolidPattern);
    int row = 0;
    for (;;) {
        if (row >= model->rowCount()) {
            break;
        }

        tableRowHeight = tableView->rowHeight(row);
        adjustdy(tableRowHeight);
        for (int j=0; j<model->columnCount(); j++) {
            int logicalIndex=tableView->horizontalHeader()->logicalIndex(j);
            int actColSize=tableView->columnWidth(logicalIndex);

            QPen pen(Qt::gray, 0.1);
            QBrush brush(tableView->palette().window());
            bool balt = tableView->alternatingRowColors();
            if(balt)
            {
                int modulo= row % 2;
                if (modulo != 0) {
                    //rectangle grey
                    pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen, brush);
                }
                else
                {
                    pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen);
                }
            }
            else
            {
                pageScene->addRect(dx,dy,actColSize,tableRowHeight, pen);
            }

            QString txt = model->data(model->index(row,logicalIndex)).toString();
            txt=tableFmt.elidedText(txt,Qt::ElideRight,actColSize-2);
            QTEGraphicsTextItem *item = pageScene->addText(txt, tableFont);
            item->moveBy(dx,dy);

            dx+=actColSize;
        }
        row++;
        dy += tableRowHeight;
        dx = xpos;
    }
}

void QTEWordExpress::exportPdf(const QString &pdf)
{
    // setup printer
    pr->setOutputFileName(pdf);

    // print pdf
    QPainter p(pr);

    QTEGraphicsScene* pageScene = 0;
    foreach (pageScene, pageSceneVector) {

        pageScene->render(&p, pr->paperRect(), sceneRect);

        if(pageScene != pageSceneVector.last())
            pr->newPage();
    }
}

QTEGraphicsScene *QTEWordExpress::getPage(int num)
{
    if(num < 1 || num > pageSceneVector.size())
        return NULL;
    return pageSceneVector.at(num-1);
}

void QTEWordExpress::print()
{
    pr->print();
}

void QTEWordExpress::setHeaderFont(QFont font)
{
    //header font
    m_headerFont = QApplication::font();;
    m_headerFont.setPointSize(9);
    if(headerFmt)
        delete headerFmt;
    headerFmt =new QFontMetrics(m_headerFont);
}

void QTEWordExpress::setHeaderSize(qreal size)
{
    headerSize=70;
}

void QTEWordExpress::setHeaderLine(bool show)
{

}

void QTEWordExpress::setHeaderText(const QString &text, QFont font, Qt::Alignment align)
{
    headerText = text;
    paintPageHeader();
}

void QTEWordExpress::setFooterSize(qreal size)
{
    footerSize=70;
}

void QTEWordExpress::setFooterLine(bool show)
{

}

void QTEWordExpress::setFooterText(const QString &text, QFont font, Qt::Alignment align)
{
    footerText = text;
    paintPageFooter();
}

void QTEWordExpress::initWordExpress()
{
    while ( ! pageSceneVector.isEmpty() ) {
        QTEGraphicsScene* pageScene = pageSceneVector.first();
        pageScene->clear();
        delete pageScene;
        pageSceneVector.remove(0);
    }
    headerText = "";
    footerText = "";
    createFrame();
}

void QTEWordExpress::adjustdy(qreal dy0)
{
    dx = xpos;
    if(dy + dy0 < ypos2)
        return;
    createFrame();
}


void QTEWordExpress::createFrame()
{
    xpos = leftMargin;
    xpos2 = sceneRect.width() - rightMargin;
    ypos = topMargin;
    ypos2 = sceneRect.height() - bottomMargin;
    dx = xpos;
    dy = ypos;

    pageScene = new QTEGraphicsScene(sceneRect);
    pageSceneVector.append(pageScene);
    paintPageHeader();
    paintPageFooter();
}

void QTEWordExpress::paintPageHeader()
{
    // Page header
    if (headerText.isEmpty())
        return;

    int sx = xpos;
    int sy = ypos-headerSize;
    //页眉
    QTEGraphicsTextItem *headerItem = pageScene->addText(headerText, m_headerFont);
    headerItem->moveBy(sx, sy);

    //std text
    QString date=QDate::currentDate().toString(QLocale().dateFormat());
    QString time=QTime::currentTime().toString(QLocale().timeFormat(QLocale::ShortFormat));
    QString headerStdText;
    headerStdText = date+" "+time;
    QTEGraphicsTextItem *item = pageScene->addText(headerStdText, m_headerFont);
    item->moveBy(xpos2 - headerFmt->width(headerStdText), sy);

    sy += headerItem->boundingRect().height();

    //line
    pageScene->addLine(xpos, sy, xpos2, sy, QPen(Qt::black, 1.0));
}

void QTEWordExpress::paintPageFooter()
{
    if (footerText.isEmpty())
        return;

    // footer
    int sx = xpos;

    QString footerStdText = tr("第 ") + QString::number(pageSceneVector.size()) + tr(" 页");
    QTEGraphicsTextItem *item=pageScene->addText(footerStdText, m_headerFont);
    int height = item->boundingRect().height();
    int sy = ypos2 + footerSize - height;
    item->moveBy(xpos2 - headerFmt->width(footerStdText), sy);

    pageScene->addLine(xpos, sy, xpos2, sy, QPen(Qt::black, 1.0));

    QTEGraphicsTextItem *footerItem=pageScene->addText(footerText, m_headerFont);
    footerItem->moveBy(xpos, sy);
}

QTEReport

QTEReport.h

#ifndef QTEREPORT_H
#define QTEREPORT_H

#include "hnwordexpress.h"

class QTEReport : public QTEWordExpress
{
    Q_OBJECT
public:
    explicit QTEReport(QObject *parent = 0);

    void createSampleReport(const QString& head, const QString& foot, const QString& title,
                              const QTableView* table);
    void GenerateComplexReport();
signals:

public slots:


    // QTEWordExpress interface
protected:

private:
};

QTEReport* QTEReportInstance(QObject* parent);

#endif // QTEREPORT_H

QTEReport.cpp

#include "hnreport.h"

QTEReport::QTEReport(QObject *parent) :
    QTEWordExpress(parent)
{
}

void QTEReport::createSampleReport(const QString &head, const QString &foot, const QString &title, const QTableView *table)
{
    initWordExpress();
    setHeaderText(head);
    setFooterText(foot);
    addText(title, titleFont());
    addText("试验结果", title2Font(), Qt::AlignLeft);
    addTable(table);
    addSignoffText("打印人:___________");
}

void QTEReport::GenerateComplexReport()
{
}


QTEReport *QTEReportInstance(QObject *parent)
{
    static QTEReport* r = new QTEReport(parent);
    return r;
}

转载于:https://my.oschina.net/tianduanrui/blog/1536594

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值