Not able to render a tableview to pdf.
-
hello,
I am a newbie in qt, and i was trying to render a table view to a pdf using printers. Below is the reduced version of the code and i am not able to achieve it. can someone help me with this. Thanks for any help in advance.ui->setupUi(this); QStandardItemModel *indexPageModel=new QStandardItemModel; QTableView *indexPageTableView=new QTableView(); indexPageTableView->setModel(indexPageModel); indexPageTableView->verticalHeader()->setVisible(false); indexPageTableView->horizontalHeader()->setVisible(false); //populate tableview //row1 QStandardItem *item00 = new QStandardItem(" Title "); item00->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 0, item00); QStandardItem *item01 = new QStandardItem(" X-axis "); item01->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 1, item01); QStandardItem *item02 = new QStandardItem(" Y-axis "); item02->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 2, item02); QStandardItem *item03 = new QStandardItem(" Page# "); item03->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 3, item03); QStandardItem *item04 = new QStandardItem(" Trend# "); item04->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 4, item04); QStandardItem *item05 = new QStandardItem("Trend Relationship"); item05->setTextAlignment(Qt::AlignCenter); indexPageModel->setItem(0, 5, item05); indexPageTableView->resizeColumnsToContents(); QGraphicsScene *scene=new QGraphicsScene(this); QGraphicsProxyWidget *proxy = scene->addWidget(indexPageTableView); ui->graphicsView->setScene(scene); ui->graphicsView->setAlignment(Qt::AlignTop | Qt::AlignLeft); int width = (indexPageModel->columnCount() - 1) + indexPageTableView->verticalHeader()->width(); for (int column = 0; column < indexPageModel->columnCount(); column++) width = width + indexPageTableView->columnWidth(column); indexPageTableView->setMinimumWidth(width); //tableview populated //render tablview to a pdf QFileDialog dialog(this); dialog.setDefaultSuffix("pdf"); QString pdffileName = dialog.getSaveFileName(this, tr("Save File"), "doc.pdf", tr("file(.pdf)")); QPixmap pixIndexPage(indexPageTableView->size()); pixIndexPage.fill(Qt::transparent); QPainter painterIndexPage(&pixIndexPage); painterIndexPage.setRenderHints(QPainter::LosslessImageRendering,QPainter::HighQualityAntialiasing); indexPageTableView->render(&painterIndexPage); QPrinter printer; printer.setOutputFileName(pdffileName); printer.setFullPage(true); printer.setPageSize(QPageSize(QPageSize::A4)); printer.newPage(); QPainter painter( &printer); const QRectF textRect(0, 0, printer.pageRect().width() ,printer.pageRect().height() ); painter.setClipRect(textRect); painter.drawPixmap(textRect,pixIndexPage,QRect(0,0,pixIndexPage.size().width(),pixIndexPage.size().height()));```
-
@sachinrd
That is really .. not so pretty :)
can you try this ?void MainWindow::PrintWidget(QWidget* widget) { QPixmap pix(widget->size()); QPainter painter(&pix); widget->render(&painter); painter.end(); QPrinter printer(QPrinter::HighResolution); printer.setPageOrientation(QPageLayout::Orientation::Landscape); printer.setOutputFormat(QPrinter::PdfFormat); printer.setPaperSize(QPrinter::A4); printer.setOutputFileName("test.pdf"); // will be in build folder painter.begin(&printer); double xscale = printer.pageRect().width() / double(pix.width()); double yscale = printer.pageRect().height() / double(pix.height()); double scale = qMin(xscale, yscale); painter.translate(printer.paperRect().x() + printer.pageRect().width() / 2, printer.paperRect().y() + printer.pageRect().height() / 2); painter.scale(scale, scale); painter.translate(-widget->width() / 2, -widget->height() / 2); painter.drawPixmap(0, 0, pix); painter.end(); }
PrintWidget(ui->tableView);
and see if that looks better ?
-
Managing paging manually is painful, you can use
QTextDocument
to do it for you:QFileDialog dialog(this); dialog.setDefaultSuffix("pdf"); const QString pdffileName = dialog.getSaveFileName(this, tr("Save File"), tr("doc.pdf"), tr("file(.pdf)")); if(pdffileName.isEmpty()) return; QTextDocument doc; QTextCursor cursor(doc); const int rowC = indexPageModel->rowCount(); const int colC = indexPageModel->columnCount(); cursor.insertTable(rowC ,colC); for(int i=0;i<rowC ;++i){ for(int j=0;j<colC ;++j){ cursor.insertText(indexPageModel->index(i,j).data().toString()); cursor.movePosition(QTextCursor::NextCell); } } QPrinter printer; printer.setOutputFileName(pdffileName); printer.setOutputFormat(QPrinter::PdfFormat); printer.setPageSize(QPageSize(QPageSize::A4)); doc.print(&printer);
P.S.
I think you are leaking the model. change it toQStandardItemModel *indexPageModel=new QStandardItemModel(this);
-
@sachinrd
@VRonin's suggestion of going viaQTextDocument
is much easier/more robust. But be aware this will produce a table in PDF with the textual content from the model; it will not necessarily look like what you see in theQTableView
(e.g. column widths, coloring, style, etc.). So long as that is acceptable to you. -
@VRonin said in Not able to render a tableview to pdf.:
QFileDialog dialog(this);
dialog.setDefaultSuffix("pdf");
const QString pdffileName = dialog.getSaveFileName(this, tr("Save File"), tr("doc.pdf"), tr("file(.pdf)"));
if(pdffileName.isEmpty())
return;
QTextDocument doc;
QTextCursor cursor(doc);
const int rowC = indexPageModel->rowCount();
const int colC = indexPageModel->columnCount();
cursor.insertTable(rowC ,colC);
for(int i=0;i<rowC ;++i){
for(int j=0;j<colC ;++j){
cursor.insertText(indexPageModel->index(i,j).data().toString());
cursor.movePosition(QTextCursor::NextCell);
}
}
QPrinter printer;
printer.setOutputFileName(pdffileName);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageSize(QPageSize(QPageSize::A4));
doc.print(&printer);Thanks for the reply @VRonin . I tried this solution.. But i want to add a header and footer to the page.. Finding it tough to add it with this approach. And i also have one column with a checkbox widget. rendering that with this approach would be tough right..
-
@JonB yes, i do want to render it as it looks in the QTableView. Is there an easy way to do this. I am able to render it to a pixmap and then paint it to printer object using a painter.
Something like this:
painter->drawPixmap(textRect,pix,QRect(0,0,pix.size().width(),pix.size().height()));
But The content is appearing a bit bigger . -
@sachinrd
That is really .. not so pretty :)
can you try this ?void MainWindow::PrintWidget(QWidget* widget) { QPixmap pix(widget->size()); QPainter painter(&pix); widget->render(&painter); painter.end(); QPrinter printer(QPrinter::HighResolution); printer.setPageOrientation(QPageLayout::Orientation::Landscape); printer.setOutputFormat(QPrinter::PdfFormat); printer.setPaperSize(QPrinter::A4); printer.setOutputFileName("test.pdf"); // will be in build folder painter.begin(&printer); double xscale = printer.pageRect().width() / double(pix.width()); double yscale = printer.pageRect().height() / double(pix.height()); double scale = qMin(xscale, yscale); painter.translate(printer.paperRect().x() + printer.pageRect().width() / 2, printer.paperRect().y() + printer.pageRect().height() / 2); painter.scale(scale, scale); painter.translate(-widget->width() / 2, -widget->height() / 2); painter.drawPixmap(0, 0, pix); painter.end(); }
PrintWidget(ui->tableView);
and see if that looks better ?