Название: [РЕШЕНО]Большой размер документа PDF
Отправлено: Larry от Март 01, 2018, 10:19
Добрый день, форумчане. Реализовал печать таблицы в PDF, но размер документа выходит слишком большим и поэтому при открытии и работе с ним жутко тормозит. Вывод таблицы 2000 строк занимает 73 страницы, а размер этого файла 46 Мб. Как можно сделать размер поменьше? Н-р, reference manual на stm32f030 имеет размер 12 Мб и 779 страниц и работает без лагов...Подскажите, плиз, как можно сделать более приемлемый результат? Спасибо... void ConfiguratorWindow::exportToPDF(const CJournalWidget* widget, const QString& reportName, const QString& sn_device, const QString& filename) { QPrinter* printer = new QPrinter(QPrinter::ScreenResolution);
printer->setOutputFormat(QPrinter::PdfFormat); printer->setPaperSize(QPrinter::A4); printer->setPageMargins(15, 10, 10, 10, QPrinter::Millimeter); printer->setOutputFileName(filename);
QTextDocument* reportPDF = new QTextDocument; reportPDF->setPageSize(printer->pageRect().size());
QTextTableFormat tableFormat; QVector<QTextLength> columnLength;
columnLength << QTextLength(QTextLength::PercentageLength, 1); columnLength << QTextLength(QTextLength::PercentageLength, 1); columnLength << QTextLength(QTextLength::PercentageLength, 1); columnLength << QTextLength(QTextLength::VariableLength, 60); columnLength << QTextLength(QTextLength::PercentageLength, 20); columnLength << QTextLength(QTextLength::PercentageLength, 20);
tableFormat.setColumnWidthConstraints(columnLength); tableFormat.setCellPadding(5); tableFormat.setCellSpacing(0); tableFormat.setHeaderRowCount(1); tableFormat.setBorderBrush(Qt::SolidPattern); tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Ridge); tableFormat.setBorder(1); tableFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
QTextCursor cursor(reportPDF); QTextBlockFormat blockFormat; blockFormat.setPageBreakPolicy(QTextFormat::PageBreak_Auto);
cursor.insertBlock(blockFormat);
QTextBlockFormat blockHeaderFormat = cursor.blockFormat(); blockHeaderFormat.setAlignment(Qt::AlignCenter);
QTextCharFormat charHeaderFormat = cursor.charFormat(); charHeaderFormat.setFontPointSize(18); charHeaderFormat.setFontWeight(QFont::Bold);
QTextCharFormat charHeaderNextFormat = cursor.charFormat(); charHeaderNextFormat.setFontPointSize(16); charHeaderNextFormat.setFontWeight(QFont::Bold);
cursor.insertBlock(blockHeaderFormat, charHeaderFormat); cursor.insertText(reportName);
cursor.insertBlock(); cursor.setCharFormat(charHeaderNextFormat); cursor.insertText(sn_device);
cursor.insertBlock(blockFormat);
int columnCount = widget->table()->columnCount();
QPoint pos = QPoint(0, widget->table()->rowCount() - 1);
QString key = widget->property("TYPE").toString();
if(m_filter.find(key) != m_filter.end()) { CFilter filter = m_filter[key];
if(filter && filter.type() == CFilter::DATE) { pos = indexDateFilter(widget->table(), filter.date().begin, filter.date().end); } }
int rows = pos.y() - pos.x() + 1;
QTextTable* textTable = cursor.insertTable(rows + 1, columnCount, tableFormat);
QTextBlockFormat blockTableHeaderFormat; blockTableHeaderFormat.setAlignment(Qt::AlignHCenter);
for(int i = 0; i < columnCount; i++) { QTextTableCell cell = textTable->cellAt(0, i); Q_ASSERT(cell.isValid()); QTextCharFormat tableHeaderFormat = cell.format(); tableHeaderFormat.setFontWeight(QFont::Bold); tableHeaderFormat.setVerticalAlignment(QTextCharFormat::AlignBottom); cell.setFormat(tableHeaderFormat); QTextCursor cellCursor = cell.firstCursorPosition(); cellCursor.setBlockFormat(blockTableHeaderFormat); cellCursor.insertText(widget->table()->horizontalHeaderItem(i)->text()); }
for(int i = 0; i < rows; i++) { for(int j = 0; j < columnCount; j++) { QTextTableCell cell = textTable->cellAt(i + 1, j); Q_ASSERT(cell.isValid()); QTextCursor cellCursor = cell.firstCursorPosition(); cellCursor.insertText(widget->table()->item(pos.x() + i, j)->text()); } }
cursor.movePosition(QTextCursor::End);
QPainter painter(printer);
QSizeF pageSize = printer->pageRect().size();
const qreal footerHeight = painter.fontMetrics().height(); const QRectF textRect(0, 0, pageSize.width(), pageSize.height() - footerHeight);
reportPDF->setPageSize(textRect.size());
const int pageCount = reportPDF->pageCount();
emit m_progressbar->settingChanged(0, pageCount, tr("стр"));
bool firstPage = true; for (int pageIndex = 0; pageIndex < pageCount; ++pageIndex) { if(!firstPage) { printer->newPage(); }
painter.drawImage(textRect, QImage(":/images/resource/images/background_report.jpg"));
if(pageIndex == 0) { QRectF headerRect = textRect; headerRect.setBottom(textRect.top()); headerRect.setHeight(footerHeight);
painter.drawText(headerRect, Qt::AlignVCenter|Qt::AlignLeft, widget->table()->item(pos.x(), 1)->text() + " - " + widget->table()->item(pos.y(), 1)->text());
painter.drawText(headerRect, Qt::AlignVCenter|Qt::AlignRight, QObject::tr("Страниц: %1").arg(pageCount)); }
painter.save(); const QRectF textPageRect(0, pageIndex*reportPDF->pageSize().height(), reportPDF->pageSize().width(), reportPDF->pageSize().height()); painter.setClipRect(textRect); painter.translate(0, -textPageRect.top()); painter.translate(textRect.left(), textRect.top()); reportPDF->drawContents(&painter); painter.restore();
QRectF footerRect = textRect; footerRect.setTop(textRect.bottom()); footerRect.setHeight(footerHeight);
painter.drawText(footerRect, Qt::AlignVCenter|Qt::AlignLeft, QDate::currentDate().toString("dd.MM.yyyy"));
painter.drawText(footerRect, Qt::AlignVCenter|Qt::AlignRight, QObject::tr("Страница %1 из %2").arg(pageIndex +1 ).arg(pageCount));
emit m_progressbar->increment();
firstPage = false; } }
Название: Re: Большой размер документа PDF
Отправлено: qate от Март 01, 2018, 15:28
QString html; // Формирование html ... QTextDocument d; d.setHtml(html); QPrinter p; p.setOutputFormat(QPrinter::PdfFormat); p.setOutputFileName("fn"); d.print(&p);
1100 строк, 66 стр., 378 кб
Название: Re: Большой размер документа PDF
Отправлено: Larry от Март 01, 2018, 15:47
Можно конечно переделать под html, но как мне тогда вставлять хедер и футер - пока не понял, как это сделать...
Название: Re: Большой размер документа PDF
Отправлено: qate от Март 01, 2018, 16:10
Можно конечно переделать под html, но как мне тогда вставлять хедер и футер - пока не понял, как это сделать...
я переписал QTextDocument::print - он формирует footer в виде номера страницы, но там не настраиваемый отступ, я тупо убрал в 0 аналогично сделай header
Название: Re: Большой размер документа PDF
Отправлено: Larry от Март 01, 2018, 16:28
Спасибо. А можно кусок кода?
Название: Re: Большой размер документа PDF
Отправлено: Larry от Март 01, 2018, 22:04
Нашел переписку на форуме, точь в точь, как у меня проблема была...Ее решили с помощью обрезки прямоугольника, но так и не смог понять, куда именно его вставили...Может кто-то подсказать? https://forum.qt.io/topic/74643/qtextdocument-to-pdf-with-watermarks-and-header-footer-filesize-too-large/2 (https://forum.qt.io/topic/74643/qtextdocument-to-pdf-with-watermarks-and-header-footer-filesize-too-large/2)
Название: Re: Большой размер документа PDF
Отправлено: Larry от Март 01, 2018, 22:27
Нашел как исправить...Добавил при вызове метода drawContents ограничивающий прямогульник, т.е. reportPDF->drawContents(&painter, textPageRect); и получил размер в 10 раз меньше и время генерирование файла тоже где-то в 10 раз меньше. Всем спасибо. Это с учетом фона (водяной знак) в виде изображения....
|