├── example ├── main.cpp ├── TablePrintExample.pro ├── widget.h ├── widget.ui └── widget.cpp ├── .gitignore ├── LICENSE ├── README.md ├── tableprinter.h └── tableprinter.cpp /example/main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | Widget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | #QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | -------------------------------------------------------------------------------- /example/TablePrintExample.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-03-16T18:21:24 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui printsupport sql 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = example 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | widget.cpp \ 17 | ../tableprinter.cpp 18 | 19 | HEADERS += widget.h \ 20 | ../tableprinter.h 21 | 22 | FORMS += widget.ui 23 | -------------------------------------------------------------------------------- /example/widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | 6 | class QPrinter; 7 | class QSqlTableModel; 8 | 9 | namespace Ui { 10 | class Widget; 11 | } 12 | 13 | class Widget : public QWidget { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit Widget(QWidget* parent = 0); 18 | ~Widget(); 19 | 20 | private: 21 | Ui::Widget* ui; 22 | void initDb(); 23 | QSqlTableModel *model; 24 | private slots: 25 | void print(QPrinter *printer); 26 | void print_two_tables(QPrinter *printer); 27 | void uglyPrint(QPrinter *printer); 28 | void on_pushButton_2_clicked(); 29 | void on_pushButton_clicked(); 30 | void on_pushButton_3_clicked(); 31 | }; 32 | 33 | #endif // WIDGET_H 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Anton Onishchenko 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or other 12 | materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors may 15 | be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /example/widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 520 10 | 359 11 | 12 | 13 | 14 | Table Print Example 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Qt::Horizontal 26 | 27 | 28 | 29 | 40 30 | 20 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Two tables 39 | 40 | 41 | 42 | 43 | 44 | 45 | Death-to-designers example 46 | 47 | 48 | 49 | 50 | 51 | 52 | Simplest example 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qt Table Printer 2 | ## About 3 | TablePainter is a simple class for qt-based applications that can print 4 | all kinds of tables inherited from QAbstractItemModel such QSqlTableModel, 5 | QSqlQueryModel, QTableWidget (using QTableWidget::model() method) or your custom 6 | table model. TablePainter works using QPrinter class. 7 | 8 | ## Features 9 | * border style 10 | * table margins 11 | * cell margins 12 | * column width 13 | * column headers 14 | * column headers font and color 15 | * content font and color 16 | * printing of standart elements on each page containing table (page number, border, service information etc.) 17 | * maximum row height 18 | 19 | ## Usage 20 | The simplest usage may look like: 21 | 22 | QPrinter printer 23 | // printer setup 24 | QPainter painter; 25 | painter.begin(&printer); 26 | TablePrinter tablePrinter(&painter, &printer); 27 | QVector columnStretch = QVector() << 1 << 5 << 5 << 5; 28 | tablePrinter.printTable(model, columnStretch); 29 | painter.end(); 30 | Where model is a child of QAbstractItemModel you want to print. 31 | TablePrinter starts to print table from point (tablePrinter.leftblank, current_Y_position) so if you have some content above the table you need to set initial vertical position with 32 | 33 | painter.translate(0, dy); 34 | After `printTable()` call `painter.transform.dx()` equals to `painter.transform.dx()` before printing, and `painter.transform.dy()` 35 | equals to `y` coordinate of last horizontal line of printed table. 36 | If wrong data was passed to TablePrinter then table will not be printed and printTable returns false. You can get an error description from TablePrinter::lastError() method. 37 | 38 | if(!tablePrinter.printTable(model, columnStretch)) { 39 | qDebug() << tablePrinter.lastError(); 40 | } 41 | If you need to print some data on each page, like page numbers, you need to create new class inherited from PagePrepare and reimplement preparePage(QPainter *painter) function. 42 | 43 | You can find two examples of TablePrinter usage (one of which demonstrates applying of all TablePrinter settings but looks pretty wierd) in /example catalog. 44 | ## License 45 | [BSD License](./LICENSE) -------------------------------------------------------------------------------- /tableprinter.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (c) 2016, Anton Onishchenko 4 | ** All rights reserved. 5 | ** 6 | ** Redistribution and use in source and binary forms, with or without modification, 7 | ** are permitted provided that the following conditions are met: 8 | ** 9 | ** 1. Redistributions of source code must retain the above copyright notice, this 10 | ** list of conditions and the following disclaimer. 11 | ** 12 | ** 2. Redistributions in binary form must reproduce the above copyright notice, this 13 | ** list of conditions and the following disclaimer in the documentation and/or other 14 | ** materials provided with the distribution. 15 | ** 16 | ** 3. Neither the name of the copyright holder nor the names of its contributors may 17 | ** be used to endorse or promote products derived from this software without 18 | ** specific prior written permission. 19 | ** 20 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 24 | ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ** 31 | ****************************************************************************/ 32 | 33 | #ifndef TABLEPRINTER_H 34 | #define TABLEPRINTER_H 35 | 36 | #include 37 | #include 38 | 39 | class QPrinter; 40 | class QPainter; 41 | class QAbstractItemModel; 42 | 43 | /** 44 | * @brief The PagePrepare Abstract class - base class for 45 | * classes that will print something like headers, borders... 46 | * on each page with table 47 | */ 48 | class PagePrepare { 49 | public: 50 | virtual void preparePage(QPainter *painter) = 0; 51 | virtual ~PagePrepare() {} 52 | }; 53 | 54 | class TablePrinter 55 | { 56 | public: 57 | TablePrinter(QPainter *painter, QPrinter *printer); 58 | bool printTable(const QAbstractItemModel* model, const QVector columnStretch, 59 | const QVector headers = QVector()); 60 | QString lastError(); 61 | void setCellMargin(int left = 10, int right = 5, int top = 5, int bottom = 5); 62 | void setPageMargin(int left = 50, int right = 20, int top = 20, int bottom = 20); 63 | void setPagePrepare(PagePrepare *prepare); 64 | void setPen(QPen pen); // for table borders 65 | void setHeadersFont(QFont font); 66 | void setContentFont(QFont font); 67 | void setHeaderColor(QColor color); 68 | void setContentColor(QColor color); 69 | void setMaxRowHeight(int height); 70 | private: 71 | QPainter *painter; 72 | QPrinter *printer; 73 | PagePrepare *prepare; 74 | QPen pen; // for table borders 75 | QFont headersFont; 76 | QFont contentFont; 77 | QColor headerColor; 78 | QColor contentColor; 79 | // cell margins 80 | int topMargin; 81 | int bottomMargin; 82 | int leftMargin; 83 | int rightMargin; 84 | 85 | // margins for table 86 | int headerHeight; 87 | int bottomHeight; 88 | int leftBlank; 89 | int rightBlank; 90 | 91 | int maxRowHeight; 92 | 93 | QString error; 94 | }; 95 | 96 | #endif // TABLEPRINTER_H 97 | -------------------------------------------------------------------------------- /example/widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include "ui_widget.h" 3 | #include "../tableprinter.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // ----------------- example of inharitance from PagePrepare --------------------- 15 | 16 | class PrintBorder : public PagePrepare { 17 | public: 18 | virtual void preparePage(QPainter *painter); 19 | static int pageNumber; 20 | }; 21 | 22 | int PrintBorder::pageNumber = 0; 23 | 24 | void PrintBorder::preparePage(QPainter *painter) { // print a border on each page 25 | QRect rec = painter->viewport(); 26 | painter->setPen(QPen(QColor(0, 0, 0), 1)); 27 | painter->drawRect(rec); 28 | painter->translate(10, painter->viewport().height() - 10); 29 | painter->drawText(0, 0, QString("Page %1").arg(pageNumber)); 30 | pageNumber += 1; 31 | } 32 | 33 | // -------------------------------------------------------------------------------- 34 | 35 | Widget::Widget(QWidget* parent) : 36 | QWidget(parent), 37 | ui(new Ui::Widget) { 38 | ui->setupUi(this); 39 | initDb(); 40 | model = new QSqlTableModel; 41 | model->setTable("exampleTable"); 42 | model->select(); 43 | ui->tableView->setModel(model); 44 | } 45 | 46 | Widget::~Widget() { 47 | delete ui; 48 | delete model; 49 | } 50 | 51 | void Widget::print(QPrinter *printer) { 52 | 53 | // ------------------ simplest example -------------------------- 54 | 55 | QPainter painter; 56 | if(!painter.begin(printer)) { 57 | qWarning() << "can't start printer"; 58 | return; 59 | } 60 | // print table 61 | TablePrinter tablePrinter(&painter, printer); 62 | QVector columnStretch = QVector() << 2 << 5 << 10 << 15; 63 | if(!tablePrinter.printTable(ui->tableView->model(), columnStretch)) { 64 | qDebug() << tablePrinter.lastError(); 65 | } 66 | painter.end(); 67 | } 68 | 69 | void Widget::print_two_tables(QPrinter *printer) { 70 | 71 | // ------------------ two tables example -------------------------- 72 | 73 | QPainter painter; 74 | if(!painter.begin(printer)) { 75 | qWarning() << "can't start printer"; 76 | return; 77 | } 78 | // print table 79 | TablePrinter tablePrinter(&painter, printer); 80 | QVector columnStretch = QVector() << 2 << 5 << 10 << 15; 81 | if(!tablePrinter.printTable(ui->tableView->model(), columnStretch)) { 82 | qDebug() << tablePrinter.lastError(); 83 | } 84 | // print second table 85 | painter.translate(0, 100); 86 | if(!tablePrinter.printTable(ui->tableView->model(), columnStretch)) { 87 | qDebug() << tablePrinter.lastError(); 88 | } 89 | painter.end(); 90 | } 91 | 92 | void Widget::uglyPrint(QPrinter *printer) { 93 | 94 | // ---------------- death-to-designers example ------------------ 95 | 96 | QPainter uglyPainter; 97 | if(!uglyPainter.begin(printer)) { 98 | qWarning() << "can't start printer"; 99 | return; 100 | } 101 | TablePrinter uglyTablePrinter(&uglyPainter, printer); 102 | QVector colStretch = QVector() << 5 << 5 << 0 << 10; 103 | uglyTablePrinter.setPen(QPen(QColor(0, 100, 255), 3, Qt::DotLine)); // pen for borders 104 | uglyTablePrinter.setHeaderColor(Qt::red); 105 | uglyTablePrinter.setContentColor(Qt::green); 106 | QFont font1; // font for headers 107 | font1.setBold(true); 108 | QFont font2; // font for content 109 | font2.setItalic(true); 110 | uglyTablePrinter.setHeadersFont(font1); 111 | uglyTablePrinter.setContentFont(font2); 112 | PrintBorder *printB = new PrintBorder; 113 | printB->pageNumber = 1; 114 | uglyTablePrinter.setPagePrepare(printB); 115 | QVector headers = QVector() << "Header 1" << "Header 2" << "Header 3" << "Header 4"; 116 | uglyPainter.setPen(QPen(Qt::yellow)); 117 | uglyPainter.drawText(uglyPainter.viewport().width()/2 - 40, 40, "TABLE NAME"); 118 | uglyPainter.translate(0, 60); // start print point 119 | uglyTablePrinter.setCellMargin(10, 5, 5, 5); 120 | uglyTablePrinter.setPageMargin(100, 40, 40, 40); 121 | if(!uglyTablePrinter.printTable(ui->tableView->model(), colStretch, headers)) { 122 | qDebug() << uglyTablePrinter.lastError(); 123 | } 124 | uglyPainter.end(); 125 | delete printB; 126 | } 127 | 128 | // ----------------------- create and populate the table ------------ 129 | void Widget::initDb() { 130 | QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); 131 | db.setDatabaseName("exampleDb"); 132 | if(!db.open()) { 133 | qWarning() << "can't open db" << db.lastError().text(); 134 | } 135 | QSqlQuery query; 136 | query.exec("CREATE TABLE IF NOT EXISTS exampleTable(Column_0 INT, Column_1 TEXT, Column_2 TEXT, Column_3 TEXT);"); 137 | query.exec("DELETE FROM exampleTable;"); 138 | QSqlDatabase::database().transaction(); 139 | for(int i = 1; i < 20; i++) { 140 | query.exec(QString("INSERT INTO exampleTable VALUES (%1, '%2', '%3', '%4');") 141 | .arg(i).arg("text in column 1").arg("text in column 2").arg("text in column 3")); 142 | } 143 | query.exec(QString("INSERT INTO exampleTable VALUES(%1, '%2', '%3', '%4');") 144 | .arg(20).arg("long text results in column with big height one two three four five six seven eigth nine ten") 145 | .arg("text in column 2").arg("text in column 3")); 146 | query.exec(QString("INSERT INTO exampleTable VALUES(%1, '%2', '%3', '%4');") 147 | .arg(21).arg("text in column 1") 148 | .arg("text in column 2") 149 | .arg("long text results in column with big height one two three four five six seven eigth nine ten")); 150 | for(int i = 22; i < 31; i++) { 151 | query.exec(QString("INSERT INTO exampleTable VALUES(%1, '%2', '%3', '%4');") 152 | .arg(i).arg("text in column 1").arg("text in column 2").arg("text in column 3")); 153 | } 154 | QSqlDatabase::database().commit(); 155 | } 156 | 157 | void Widget::on_pushButton_2_clicked() { 158 | QPrintPreviewDialog dialog; 159 | connect(&dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(uglyPrint(QPrinter*))); 160 | dialog.exec(); 161 | } 162 | 163 | void Widget::on_pushButton_clicked() { 164 | QPrintPreviewDialog dialog; 165 | connect(&dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*))); 166 | dialog.exec(); 167 | } 168 | 169 | void Widget::on_pushButton_3_clicked() { 170 | QPrintPreviewDialog dialog; 171 | connect(&dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print_two_tables(QPrinter*))); 172 | dialog.exec(); 173 | } 174 | -------------------------------------------------------------------------------- /tableprinter.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (c) 2016, Anton Onishchenko 4 | ** All rights reserved. 5 | ** 6 | ** Redistribution and use in source and binary forms, with or without modification, 7 | ** are permitted provided that the following conditions are met: 8 | ** 9 | ** 1. Redistributions of source code must retain the above copyright notice, this 10 | ** list of conditions and the following disclaimer. 11 | ** 12 | ** 2. Redistributions in binary form must reproduce the above copyright notice, this 13 | ** list of conditions and the following disclaimer in the documentation and/or other 14 | ** materials provided with the distribution. 15 | ** 16 | ** 3. Neither the name of the copyright holder nor the names of its contributors may 17 | ** be used to endorse or promote products derived from this software without 18 | ** specific prior written permission. 19 | ** 20 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | ** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 24 | ** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ** 31 | ****************************************************************************/ 32 | 33 | #include "tableprinter.h" 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | TablePrinter::TablePrinter(QPainter* painter, QPrinter* printer) : 40 | painter(painter), 41 | printer(printer) { 42 | topMargin = 5; 43 | bottomMargin = 5; 44 | leftMargin = 10; 45 | rightMargin = 5; 46 | headerHeight = 0; 47 | bottomHeight = 0; 48 | leftBlank = 0; 49 | rightBlank = 0; 50 | maxRowHeight = 1000; 51 | pen = painter->pen(); 52 | headersFont = painter->font(); 53 | contentFont = painter->font(); 54 | headerColor = painter->pen().color(); 55 | contentColor = painter->pen().color(); 56 | prepare = NULL; 57 | error = "No error"; 58 | } 59 | 60 | bool TablePrinter::printTable(const QAbstractItemModel* model, const QVector columnStretch, 61 | const QVector headers) { 62 | 63 | //--------------------------------- error checking ------------------------------------- 64 | 65 | int columnCount = model->columnCount(); 66 | int count = columnStretch.count(); 67 | if(count != columnCount) { 68 | error = "Different columns count in model and in columnStretch"; 69 | return false; 70 | } 71 | count = headers.count(); 72 | if(count != columnCount && count != 0) { 73 | error = "Different columns count in model and in headers"; 74 | return false; 75 | } 76 | if(!printer->isValid()) { 77 | error = "printer.isValid() == false"; 78 | return false; 79 | } 80 | if(!painter->isActive()) { 81 | error = "painter.isActive() == false"; 82 | return false; 83 | } 84 | double tableWidth = painter->viewport().width() - leftBlank - rightBlank; 85 | if(tableWidth <= 0) { 86 | error = "wrong table width"; 87 | return false; 88 | } 89 | int totalStretch = 0; 90 | for (int i = 0; i < columnStretch.count(); i++) { 91 | if(columnStretch[i] < 0) { 92 | error = QString("wrong column stretch, columnt: %1 stretch: %2").arg(i).arg(columnStretch[i]); 93 | return false; 94 | } 95 | totalStretch += columnStretch[i]; 96 | } 97 | if(totalStretch <= 0) { 98 | error = QString("wrong stretch"); 99 | return false; 100 | } 101 | QVector columnWidth; 102 | for (int i = 0; i < columnStretch.count(); i++) { 103 | columnWidth.append(tableWidth / totalStretch * columnStretch[i]); 104 | } 105 | int initValue; 106 | headers.isEmpty() ? initValue = 0 : initValue = -1; 107 | 108 | //---------------------------------------------------------------------------- 109 | 110 | painter->save(); // before table print 111 | 112 | // to know row height before printing 113 | // at first print to test image 114 | QPainter testSize; 115 | QImage* image = new QImage(10, 10, QImage::Format_RGB32); 116 | image->setDotsPerMeterX(printer->logicalDpiX() * 100 / 2.54); // 2.54 cm = 1 inch 117 | image->setDotsPerMeterY(printer->logicalDpiY() * 100 / 2.54); 118 | testSize.begin(image); 119 | 120 | if(prepare) { 121 | painter->save(); 122 | painter->translate(-painter->transform().dx(), -painter->transform().dy()); 123 | prepare->preparePage(painter); 124 | painter->restore(); 125 | } 126 | 127 | painter->setPen(pen); 128 | painter->setFont(contentFont); 129 | testSize.setFont(contentFont); 130 | painter->translate(-painter->transform().dx() + leftBlank, 0); 131 | painter->save(); 132 | painter->setFont(headersFont); 133 | testSize.setFont(headersFont); 134 | painter->drawLine(0, 0, tableWidth, 0); // first horizontal line 135 | 136 | float max_y; 137 | 138 | for(int j = initValue; j < model->rowCount(); j++) { // for each row 139 | if(j == 0) { 140 | painter->setFont(contentFont); 141 | testSize.setFont(contentFont); 142 | } 143 | 144 | // --------------------------- row height counting ---------------------------- 145 | 146 | int maxHeight = 0; // max row Height 147 | for(int i = 0; i < columnCount; i++) { // for each column 148 | QString str; 149 | if(j >= 0) { 150 | str = model->data(model->index(j,i), Qt::DisplayRole).toString(); 151 | } else { 152 | str = headers.at(i); 153 | } 154 | QRect rect(0, 0, columnWidth[i] - rightMargin - leftMargin, maxRowHeight); 155 | QRect realRect; 156 | testSize.drawText(rect, Qt::AlignLeft | Qt::TextWordWrap, str, &realRect); 157 | if (realRect.height() > maxHeight && columnStretch[i] != 0) { 158 | realRect.height() > maxRowHeight ? maxHeight = maxRowHeight : maxHeight = realRect.height(); 159 | } 160 | } 161 | 162 | if(painter->transform().dy() + maxHeight + topMargin + bottomMargin > painter->viewport().height() - 163 | bottomHeight) { // begin from new page 164 | int y = painter->transform().dy(); 165 | painter->restore(); 166 | painter->save(); 167 | for(int i = 0; i < columnCount; i++) { // vertical lines 168 | painter->drawLine(0, 0, 0, 169 | - painter->transform().dy() + y); 170 | painter->translate(columnWidth[i], 0); 171 | } 172 | painter->drawLine(0, 0, 0, - painter->transform().dy() + y); // last vertical line 173 | painter->restore(); 174 | printer->newPage(); 175 | if(prepare) { 176 | painter->save(); 177 | painter->translate(-painter->transform().dx(), -painter->transform().dy()); 178 | prepare->preparePage(painter); 179 | painter->restore(); 180 | } 181 | painter->translate(-painter->transform().dx() + leftBlank, -painter->transform().dy() + headerHeight); 182 | painter->save(); 183 | painter->drawLine(0, 0, tableWidth, 184 | 0); // first horizontal line 185 | } 186 | 187 | //------------------------------ content printing ------------------------------------------- 188 | 189 | painter->save(); 190 | j >= 0 ? painter->setPen(QPen(contentColor)) : painter->setPen(QPen(headerColor)); 191 | for(int i = 0; i < columnCount; i++) { // for each column 192 | QString str; 193 | if(j >= 0) { 194 | str = model->data(model->index(j,i), Qt::DisplayRole).toString(); 195 | } else { 196 | str = headers.at(i); 197 | } 198 | QRect rec(leftMargin, topMargin, columnWidth[i] - rightMargin - leftMargin, maxHeight); 199 | painter->drawText(rec, Qt::AlignLeft | Qt::TextWordWrap, str); 200 | painter->translate(columnWidth[i], 0); 201 | } 202 | painter->restore(); 203 | 204 | painter->drawLine(0, maxHeight + topMargin + bottomMargin, tableWidth, 205 | maxHeight + topMargin + bottomMargin); // last horizontal line 206 | painter->translate(0, maxHeight + topMargin + bottomMargin); 207 | max_y = painter->transform().dy(); 208 | } 209 | int y = painter->transform().dy(); 210 | painter->restore(); 211 | painter->save(); 212 | for(int i = 0; i < columnCount; i++) { // vertical lines 213 | painter->drawLine(0, 0, 0, 214 | - painter->transform().dy() + y); 215 | painter->translate(columnWidth[i], 0); 216 | } 217 | painter->drawLine(0, 0, 0, - painter->transform().dy() + y); // last vertical line 218 | painter->restore(); 219 | 220 | testSize.end(); 221 | delete image; 222 | 223 | painter->restore(); // before table print 224 | 225 | painter->translate(0, max_y); 226 | 227 | return true; 228 | } 229 | 230 | QString TablePrinter::lastError() { 231 | return error; 232 | } 233 | 234 | void TablePrinter::setCellMargin(int left, int right, int top, int bottom) { 235 | topMargin = top; 236 | bottomMargin = bottom; 237 | leftMargin = left; 238 | rightMargin = right; 239 | } 240 | 241 | void TablePrinter::setPageMargin(int left, int right, int top, int bottom) { 242 | headerHeight = top; 243 | bottomHeight = bottom; 244 | leftBlank = left; 245 | rightBlank = right; 246 | } 247 | 248 | void TablePrinter::setPagePrepare(PagePrepare *prep) { 249 | prepare = prep; 250 | } 251 | 252 | void TablePrinter::setPen(QPen p) { 253 | pen = p; 254 | } 255 | 256 | void TablePrinter::setHeadersFont(QFont f) { 257 | headersFont = f; 258 | } 259 | 260 | void TablePrinter::setContentFont(QFont f) { 261 | contentFont = f; 262 | } 263 | 264 | void TablePrinter::setHeaderColor(QColor color) { 265 | headerColor = color; 266 | } 267 | 268 | void TablePrinter::setContentColor(QColor color) { 269 | contentColor = color; 270 | } 271 | 272 | void TablePrinter::setMaxRowHeight(int height) { 273 | maxRowHeight = height; 274 | } 275 | --------------------------------------------------------------------------------