关于解决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<int> &printAreaStartRow, QVector<int> &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<int> &printAreaStartCol, QVector<int> &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<int> printAreaStartRow, printAreaHeight;
    QVector<int> 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

}

你可能感兴趣的:(qt,打印预览,QTableView,分页打印)