• Qt 报表实现---QPainter+QPrinter


    Qt报表实现-QPainter + QPrinter

    QPainter是可以在QPrinter上绘制图形和文字的,利用这个方法,可以绘制任何图形或者文字、表格等,可以实现复杂的表格绘制,如果报表比较特殊,可以尝试使用这个方法,下面简单介绍一下实现的过程。

    报表绘制

    实现简介

    我这边里封装了一个报表打印类,用于打印报表,当前并没有传入数据和参数,实际实际项目是需要传入参数和数据的。

    首先是打印的接口代码:

    1. 1    void printWithPreview();
    2. 2    void printDirect();
    3. 3    void printOnePage(QPainter *painter, int no);

    printWithPreview 是用于调出打印预览窗口;
    printDirect 是直接打印
    printOnePage 是打印一页;因为可能会打印多个页,所以这里把一页的绘制单独封装为一个函数

    打印信号处理槽函数,用于接收打印信号,在这个函数里调用printOnePage去绘制要打印的报表。

    1    void printDocument(QPrinter *printer);
    

    打印版式设置

    横向打印和纵向打印;
    打印方向 Portrait 纵向,Landscape:横向
    使用如下函数设置

    1. 1enum Orientation { Portrait, Landscape };
    2. 2void setOrientation(Orientation);

    代码

    头文件:

    1. 1#ifndef CTESTREPORT_H
    2. 2#define CTESTREPORT_H
    3. 3
    4. 4#include <QObject>
    5. 5#include <QAbstractItemModel>
    6. 6#include <QPrinter>
    7. 7#include <QVariantMap>
    8. 8#include <QVariantList>
    9. 9
    10. 10class CTestReport:public QObject
    11. 11{
    12. 12    Q_OBJECT
    13. 13public:
    14. 14    explicit CTestReport(QObject *parent = nullptr);
    15. 15    virtual ~CTestReport();
    16. 16
    17. 17
    18. 18
    19. 19    void printWithPreview();
    20. 20    void printDirect();
    21. 21    void printOnePage(QPainter *painter, int no);
    22. 22
    23. 23private:
    24. 24    void drawTable(QPainter *painter, int no);
    25. 25signals:
    26. 26
    27. 27public slots:
    28. 28
    29. 29private slots:
    30. 30    void printDocument(QPrinter *printer);
    31. 31
    32. 32private:
    33. 33
    34. 34    int m_startx;    //整体表格在A4纸中的起始x坐标
    35. 35    int m_starty;    //整体表格在A4纸中的起始y坐标
    36. 36    int m_width;     //整体表格的宽
    37. 37    int m_height;    //整体表格的高
    38. 38
    39. 39    int m_titleHeight;    //标题栏的高
    40. 40
    41. 41    int m_colNum ;   //表格的总列数
    42. 42    int m_rowNum ;   //表格的总行数
    43. 43    int m_rowHeight; //单元表格高
    44. 44    int m_colWidth;  //单元表格宽
    45. 45
    46. 46};
    47. 47
    48. 48
    49. 49#endif // CTESTREPORT_H

    类实现源文件:

    1. 1#include <QPrintPreviewDialog>
    2. 2#include <QPrintDialog>
    3. 3#include <QPrinter>
    4. 4#include <QDateTime>
    5. 5#include <QDebug>
    6. 6#include <QPainter>
    7. 7#include <QDateTime>
    8. 8#include "ctestreport.h"
    9. 9
    10. 10CTestReport::CTestReport(QObject *parent)
    11. 11{
    12. 12    m_startx = 30;
    13. 13    m_starty = 30;
    14. 14    m_width  = 720;   //试出来的尺寸像素点
    15. 15    m_height = 1035;
    16. 16
    17. 17    m_titleHeight = 35;
    18. 18
    19. 19    m_colNum = 10;            //初始化
    20. 20    m_rowNum = 40;           //计算表格的行数
    21. 21    m_colWidth = m_width / m_colNum;
    22. 22    m_rowHeight= m_height / m_rowNum;
    23. 23
    24. 24}
    25. 25
    26. 26CTestReport::~CTestReport()
    27. 27{
    28. 28
    29. 29}
    30. 30
    31. 31void CTestReport::printWithPreview()
    32. 32{
    33. 33    QPrinter printer(QPrinter::ScreenResolution);
    34. 34    printer.setPageSize(QPrinter::A4);
    35. 35    printer.setOrientation(QPrinter::Portrait); //打印方向 Portrait 纵向,Landscape:横向
    36. 36//    printer.setOutputFormat(QPrinter::NativeFormat);
    37. 37    QPrintPreviewDialog preview(&printer);
    38. 38    connect(&preview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(printDocument(QPrinter*)));
    39. 39    preview.setWindowState(Qt::WindowMaximized);
    40. 40    preview.exec();
    41. 41}
    42. 42
    43. 43void CTestReport::printDirect()
    44. 44{
    45. 45    QPrinter printer(QPrinter::ScreenResolution);
    46. 46    printer.setPageSize(QPrinter::A4);
    47. 47    QPrintDialog printDialog(&printer);
    48. 48    printer.setOrientation(QPrinter::Portrait); //打印方向
    49. 49
    50. 50    if (printDialog.exec() == QDialog::Accepted)
    51. 51    {
    52. 52        printDocument(&printer);
    53. 53    }
    54. 54}
    55. 55
    56. 56
    57. 57void CTestReport::drawTable(QPainter *painter, int no)
    58. 58{
    59. 59    //调整表格整体的高度
    60. 60
    61. 61    //总框体
    62. 62    painter->drawRect(m_startx,m_starty,m_width,m_height);
    63. 63    //标题栏
    64. 64    painter->drawLine(m_startx,m_starty+m_titleHeight,m_startx+m_width,m_starty+m_titleHeight);
    65. 65    painter->setFont(QFont("宋体"20));
    66. 66    painter->drawText(QRect(m_startx,m_starty+3,m_width,m_titleHeight), Qt::AlignCenter, QString("测试报表%1").arg(no));
    67. 67    painter->drawLine(m_startx,m_starty+m_height,m_startx+m_width,m_starty+m_height);
    68. 68
    69. 69
    70. 70    int x1,y1,x2,y2;
    71. 71
    72. 72    painter->setFont(QFont("宋体"10));
    73. 73    //绘制表格列单元线
    74. 74    for (int i = 1; i < m_colNum; i++)
    75. 75    {
    76. 76        x1 = m_startx + m_colWidth*i;
    77. 77        y1 = m_startx + m_titleHeight;
    78. 78        x2 = m_startx + m_colWidth*i;
    79. 79        y2 = m_starty + m_height;
    80. 80        painter->drawLine(x1, y1, x2, y2);
    81. 81
    82. 82        painter->drawText(QRectF(x1,y1,m_colWidth,m_rowHeight), Qt::AlignCenter, QString("%1列").arg(i));
    83. 83    }
    84. 84
    85. 85
    86. 86    //第一行为序号
    87. 87    for (int rowNo = 1; rowNo <= m_rowNum; rowNo++)
    88. 88    {
    89. 89        x1 = m_startx;
    90. 90        y1 = m_starty+m_titleHeight + m_rowHeight*rowNo;
    91. 91        x2 = m_startx + m_width;
    92. 92        y2 = m_starty+m_titleHeight + m_rowHeight*rowNo;
    93. 93
    94. 94        //标题
    95. 95        if (rowNo > 1)
    96. 96        painter->drawText(QRect(x1,y1-m_rowHeight, m_colWidth,m_rowHeight), Qt::AlignCenter, QString("%1").arg(rowNo-1));
    97. 97
    98. 98
    99. 99        //行线
    100. 100        if ( rowNo == m_rowNum) //最后一行不划线
    101. 101        {
    102. 102            break;
    103. 103        }
    104. 104
    105. 105        painter->drawLine(x1, y1, x2, y2);
    106. 106    }
    107. 107
    108. 108    //表最下面的备注
    109. 109    painter->drawText(QRect(m_startx,m_starty+m_height+2,450,25), Qt::AlignLeft, "注:测试报表备注信息。");
    110. 110
    111. 111    //制表时间 2020-12-28
    112. 112    QString dateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    113. 113    painter->drawText(QRect(m_startx+m_width-200,m_starty+m_height+2,200,m_rowHeight), Qt::AlignRight, "制表时间:"+dateTime);
    114. 114
    115. 115}
    116. 116
    117. 117void CTestReport::printDocument(QPrinter *printer)
    118. 118{
    119. 119    QPainter painter;
    120. 120
    121. 121    painter.begin(printer);
    122. 122
    123. 123    painter.setPen(Qt::black);
    124. 124
    125. 125    for (int i = 0; i < 5; i++)
    126. 126    {
    127. 127        printOnePage(&painter,i+1);
    128. 128
    129. 129        if ( i != 4 ) //判断是否最后一页,如果不是最后一页则新建一页
    130. 130        {
    131. 131            printer->newPage(); //新建页
    132. 132            painter.setPen(Qt::black);
    133. 133        }
    134. 134    }
    135. 135
    136. 136    painter.end();
    137. 137}
    138. 138
    139. 139void CTestReport::printOnePage(QPainter *painter, int no)
    140. 140{
    141. 141//    qDebug()<<"reportInfo title: "<<reportInfo->getTitle();
    142. 142
    143. 143    //正常使用painter 绘制文字、pixmap等在printer上
    144. 144
    145. 145    drawTable(painter,no);
    146. 146
    147. 147
    148. 148}

    测试调用代码,我是放到一个按键的槽函数里调用的:

    1. 1void MainWindow::on_btnReport_clicked()
    2. 2{
    3. 3    CTestReport reporter;
    4. 4
    5. 5    reporter.printWithPreview();
    6. 6
    7. 7}

    效果

    效果

     

  • 相关阅读:
    操作系统学习笔记---计算机系统概述
    30 个 Python 教程和技巧
    [Lua][Love] 打砖块游戏实现过程与知识点
    您的企业从在线直播中可以获益的4种方式
    基于Qt实现的可视化大屏监控
    【新日语2】单元复习(一)
    幻兽帕鲁(Palworld 1.4.1)私有服务器搭建(docker版)
    自助报表和 BI 能解决多少事?
    牛客CM11 - 链表分割【环形链表雏形】
    ChainSafe跨链桥部署教程
  • 原文地址:https://blog.csdn.net/delphigbg/article/details/127941934