qt 打印html 分页打印,关于解决QTableView分页打印实现方法(仿Excel)

通过Qt开发电子报表软件,在打印问题上遇到难题,参考网上的方法,很少,几乎没有相关的解决方法!只有自力更生了,结合QT自带实例spreadsheet, 打印只能实现当前页的打印,并不能实现分页,分区域打印。

void PrintView::print(QPrinter *printer)

{

#ifndef QT_NO_PRINTER

resize(printer->width(), printer->height());

render(printer);

}

例子上的函数如上, 看到render函数,是把当前tableview内容绘制到打印机上。灵感即来于此!整体思路是把tableview根据打印机尺寸划分打印区域,把打印区域分块绘制到打印机上,每个区域作为一页。

具体看代码:

1. 计算行页数,及每页起始行号及区域高度

void PrintView::CalcultPrintAreaRow(int h, int &pageCount, QVector &printAreaStartRow, QVector &printAreaHeight)

{

int pix_height = 0;

QAbstractItemModel *item_model = this->model();

if (item_model == NULL) return;

QHeaderView *headerView = this->horizontalHeader ();

if (headerView != NULL)    pix_height = headerView->height();

pageCount = 0;

int i;

printAreaStartRow.push_back(0);

for (i = 0; i < item_model->rowCount(); ) {

if ((pix_height + rowHeight(i)) > h) {

printAreaStartRow.push_back(i);

printAreaHeight.push_back(pix_height);

pix_height = headerView->height();

pageCount ++;

continue;

}

pix_height += rowHeight(i);

i++;

}

if (pix_height <= h) {

printAreaStartRow.push_back(i);

printAreaHeight.push_back(pix_height);

pageCount ++;

}

}

2.计算列页数及每页起始列号及打印区域宽度

void PrintView::CalcultPrintAreaCol(int w, int &pageCount, QVector &printAreaStartCol, QVector &printAreaWidth)

{

int pix_width = 0;

QAbstractItemModel *item_model = this->model();

if (item_model == NULL) return;

QHeaderView *headerView = this->verticalHeader ();

if (headerView != NULL)    pix_width = headerView->width();

pageCount = 0;

int i;

printAreaStartCol.push_back(0);

for (i = 0; i < item_model->columnCount(); ) {

if ((pix_width + columnWidth(i)) > w) {

printAreaStartCol.push_back(i);

printAreaWidth.push_back(pix_width);

pix_width = headerView->width();

pageCount ++;

continue;

}

pix_width += columnWidth(i);

i++;

}

if (pix_width <= w) {

printAreaStartCol.push_back(i);

printAreaWidth.push_back(pix_width);

pageCount ++;

}

}

3.计算整个页面宽度

int PrintView::CalcultTableViewWidth()

{

int pix_width = 0;

QAbstractItemModel *item_model = this->model();

if (item_model == NULL) return 0;

QHeaderView *headerView = this->verticalHeader ();

if (headerView != NULL)    pix_width = headerView->width();

for (int i = 0; i < item_model->columnCount(); i++) {

pix_width += columnWidth(i);

}

return pix_width;

}

4.计算整个页面高度

int PrintView::CalcultTableViewHeight()

{

int pix_height = 0;

QAbstractItemModel *item_model = this->model();

if (item_model == NULL) return 0;

QHeaderView *headerView = this->horizontalHeader ();

if (headerView != NULL)    pix_height = headerView->height();

for (int i = 0; i < item_model->rowCount(); i++) {

pix_height += rowHeight(i);

}

return pix_height;

}

void PrintView::print(QPrinter *printer)

{

#ifndef QT_NO_PRINTER

resize(printer->width(), printer->height());

int marginLeft = 20, marginTop = 20, marginRight = 20, marginBottom = 20;

QRect paperRect = printer->paperRect();

paperRect.adjust(0, 0, - marginLeft - marginRight, - marginTop - marginBottom);

int i,j,k;

int row_pageCount = 1, col_pageCount = 1;

QVector printAreaStartRow, printAreaHeight;

QVector printAreaStartCol, printAreaWidth;

CalcultPrintAreaRow(paperRect.height(), row_pageCount, printAreaStartRow, printAreaHeight);

CalcultPrintAreaCol(paperRect.width(),  col_pageCount, printAreaStartCol, printAreaWidth);

//限制打印页数, 处理实际打印页(根据需要自己处理,判断有效打印区域)

CalcultTableViewPage(printAreaStartRow, printAreaStartCol, row_pageCount, col_pageCount);

QPainter painter(printer);

painter.begin(printer);

//隐藏行列很重要,慢慢体会吧

for (i = 0; i < row_pageCount; i ++) {

for (k = 0; k < this->model()->columnCount(); k++) setColumnHidden(k, false);     //重新把列显示出来

for (j = 0; j < col_pageCount; j++) {

resize(printAreaWidth[j], printAreaHeight[i]);

render(&painter, QPoint(marginLeft, marginTop), QRegion(0, 0, printAreaWidth[j], printAreaHeight[i]), QWidget::DrawChildren);            //绘制到指定区域

//隐藏列

for (k =  printAreaStartCol[j]; k < printAreaStartCol[j + 1]; k++) setColumnHidden(k, true);

if (i != (row_pageCount - 1) ||

j != (col_pageCount - 1)) printer->newPage();  //创建新页

}

//隐藏行

for (k = printAreaStartRow[i]; k < printAreaStartRow[i + 1]; k++) setRowHidden(k, true);

}

painter.end();

#endif

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值