How to reduce output file size and printing time?
-
wrote on 25 Nov 2021, 10:12 last edited by deleted385
Tried to follow this thread for page footer and it draws page footer correctly:
BUT takes much longer time and produces much larger file size than necessary. Also, not sure whether I've screwed up the actual process anywhere in code! Here's the code:
Window::Window(QWidget *parent) : QWidget(parent){ document = new QTextDocument(); document->setUndoRedoEnabled(false); printer = new QPrinter(); printer->setPageSize(QPageSize::A4); printer->setPageMargins(QMarginsF(72,72,72,72), QPageLayout::Point); printer->setResolution(fontMetrics().fontDpi()); auto pageRect = printer->pageRect(QPrinter::DevicePixel).size(); document->setPageSize(QSizeF(pageRect.width(), pageRect.height())); createDocument(); auto lay = new QVBoxLayout(this); auto button = new QPushButton("Pint PDF", this); lay->addWidget(button); connect(button, &QPushButton::clicked, [=]{ QElapsedTimer timer; timer.start(); printer->setOutputFormat(QPrinter::PdfFormat); printer->setOutputFileName("test.pdf"); //document->print(printer); bool firstPage = true; int pageCount = document->pageCount(); QRectF textRect(0, 0, pageRect.width(), pageRect.height()); QPainter painter(printer); for (int pageNo = 0; pageNo < pageCount; pageNo++) { if (!firstPage) printer->newPage(); const QRectF textPageRect(0, pageNo * document->pageSize().height(), document->pageSize().width(), document->pageSize().height()); painter.save(); painter.setClipRect(textRect); painter.translate(0, -textPageRect.top()); document->drawContents(&painter); painter.restore(); QRectF footerRect(0, textRect.height(), textRect.width(), fontMetrics().height()); painter.drawLine(footerRect.left(),footerRect.top(),footerRect.right(),footerRect.top()); painter.drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1/%2").arg(pageNo+1).arg(pageCount)); firstPage = false; } qDebug() << timer.elapsed(); }); } void Window::addHeader(QTextCursor& cursor){ QTextTableCellFormat cellFormat; cellFormat.setTopBorder(1); cellFormat.setBottomBorder(1); cellFormat.setBorderBrush(Qt::black); cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid); cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid); QTextCharFormat textFormat; textFormat.setFontWeight(QFont::Bold); for (int i = 0; i < 4; i++) { auto cell = cursor.currentTable()->cellAt(0, i); cell.setFormat(cellFormat); cursor.insertText("Column " + QString::number(i + 1), textFormat); cursor.movePosition(QTextCursor::NextCell); } } QTextTableFormat Window::format(){ QTextTableFormat tableFormat; tableFormat.setBorder(0); tableFormat.setCellSpacing(0); tableFormat.setCellPadding(0); tableFormat.setHeaderRowCount(1); QVector<QTextLength> columnLengths; columnLengths.append(QTextLength(QTextLength::PercentageLength, 40)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); tableFormat.setColumnWidthConstraints(columnLengths); return tableFormat; } void Window::createDocument(){ int row = 2500, column = 4; QTextCursor cursor(document); cursor.insertTable(1, 4, format()); addHeader(cursor); for (int r = 1; r < row; r++) { cursor.currentTable()->appendRows(1); cursor = cursor.currentTable()->rowStart(cursor); cursor.movePosition(QTextCursor::NextCell); for (int c = 0; c < column; c++) { cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c)); cursor.movePosition(QTextCursor::NextCell); } } }
It produces 2.4MB pdf and takes ~35/40sec to print. If I uncomment
//document->print(printer);
in the lambda in constructor and comment out rest of the code up toqDebug() << timer.elapsed();
it takes ~5/6sec to print and produces 107KB pdf. -
wrote on 25 Nov 2021, 10:43 last edited by
@Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.
-
Tried to follow this thread for page footer and it draws page footer correctly:
BUT takes much longer time and produces much larger file size than necessary. Also, not sure whether I've screwed up the actual process anywhere in code! Here's the code:
Window::Window(QWidget *parent) : QWidget(parent){ document = new QTextDocument(); document->setUndoRedoEnabled(false); printer = new QPrinter(); printer->setPageSize(QPageSize::A4); printer->setPageMargins(QMarginsF(72,72,72,72), QPageLayout::Point); printer->setResolution(fontMetrics().fontDpi()); auto pageRect = printer->pageRect(QPrinter::DevicePixel).size(); document->setPageSize(QSizeF(pageRect.width(), pageRect.height())); createDocument(); auto lay = new QVBoxLayout(this); auto button = new QPushButton("Pint PDF", this); lay->addWidget(button); connect(button, &QPushButton::clicked, [=]{ QElapsedTimer timer; timer.start(); printer->setOutputFormat(QPrinter::PdfFormat); printer->setOutputFileName("test.pdf"); //document->print(printer); bool firstPage = true; int pageCount = document->pageCount(); QRectF textRect(0, 0, pageRect.width(), pageRect.height()); QPainter painter(printer); for (int pageNo = 0; pageNo < pageCount; pageNo++) { if (!firstPage) printer->newPage(); const QRectF textPageRect(0, pageNo * document->pageSize().height(), document->pageSize().width(), document->pageSize().height()); painter.save(); painter.setClipRect(textRect); painter.translate(0, -textPageRect.top()); document->drawContents(&painter); painter.restore(); QRectF footerRect(0, textRect.height(), textRect.width(), fontMetrics().height()); painter.drawLine(footerRect.left(),footerRect.top(),footerRect.right(),footerRect.top()); painter.drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1/%2").arg(pageNo+1).arg(pageCount)); firstPage = false; } qDebug() << timer.elapsed(); }); } void Window::addHeader(QTextCursor& cursor){ QTextTableCellFormat cellFormat; cellFormat.setTopBorder(1); cellFormat.setBottomBorder(1); cellFormat.setBorderBrush(Qt::black); cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid); cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid); QTextCharFormat textFormat; textFormat.setFontWeight(QFont::Bold); for (int i = 0; i < 4; i++) { auto cell = cursor.currentTable()->cellAt(0, i); cell.setFormat(cellFormat); cursor.insertText("Column " + QString::number(i + 1), textFormat); cursor.movePosition(QTextCursor::NextCell); } } QTextTableFormat Window::format(){ QTextTableFormat tableFormat; tableFormat.setBorder(0); tableFormat.setCellSpacing(0); tableFormat.setCellPadding(0); tableFormat.setHeaderRowCount(1); QVector<QTextLength> columnLengths; columnLengths.append(QTextLength(QTextLength::PercentageLength, 40)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); columnLengths.append(QTextLength(QTextLength::PercentageLength, 20)); tableFormat.setColumnWidthConstraints(columnLengths); return tableFormat; } void Window::createDocument(){ int row = 2500, column = 4; QTextCursor cursor(document); cursor.insertTable(1, 4, format()); addHeader(cursor); for (int r = 1; r < row; r++) { cursor.currentTable()->appendRows(1); cursor = cursor.currentTable()->rowStart(cursor); cursor.movePosition(QTextCursor::NextCell); for (int c = 0; c < column; c++) { cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c)); cursor.movePosition(QTextCursor::NextCell); } } }
It produces 2.4MB pdf and takes ~35/40sec to print. If I uncomment
//document->print(printer);
in the lambda in constructor and comment out rest of the code up toqDebug() << timer.elapsed();
it takes ~5/6sec to print and produces 107KB pdf.wrote on 25 Nov 2021, 10:33 last edited by@Emon-Haque said in How to reduce output file size and printing time?:
this thread
In the same thread OP gives a hint: https://forum.qt.io/post/366382
-
@Emon-Haque said in How to reduce output file size and printing time?:
this thread
In the same thread OP gives a hint: https://forum.qt.io/post/366382
wrote on 25 Nov 2021, 10:34 last edited by deleted385 -
wrote on 25 Nov 2021, 10:43 last edited by
@Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.
-
@Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.
wrote on 25 Nov 2021, 10:44 last edited by@artwaw, now it's ok. See the edited part.
1/5