Qt打印数据库中的表格

实现方法

连接数据库,用QTableModel显示数据库的表格,然后将表格转为html,然后再进行打印,打印的方法是参考以下链接完成的:
Qt中(HTML)实现数据表格打印功能

输出

主界面

在这里插入图片描述

打印结果

在这里插入图片描述

代码

PrintTest.pro

QT       += core gui sql printsupport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    qprintermanager.cpp \
    widget.cpp

HEADERS += \
    qprintermanager.h \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

qprintermanager.h

#ifndef QPRINTERMANAGER_H
#define QPRINTERMANAGER_H

#include <QObject>
#include <QAbstractItemModel>
#include <QTextStream>
#include <QPrinter>

class QPrinterManager : public QObject
{
    Q_OBJECT
public:
    explicit QPrinterManager(QObject *parent = nullptr);
    ~QPrinterManager(){}
    void setCharSet(const QString &set = QString("utf-8")){ m_charSet = set; }
    void dataBegin();
    void dataEnd(){ out << QString("</html>"); }
    // 添加主标题(两行:第一行居中显示文字,第二行居右显示时间)
    void insertTitle(const QString &title);
    // 添加次级标题
    void insertTitle2(const QString &title2);
    // 空出一行
    void insertSeperator(){ out << QString("<br>\n"); }
    // 不支持嵌套TABLE
    void tableBegin(const QStringList &head);
    void tableEnd(){ out << QString("</table></div>\n"); }
    void insert2TableRow(const QStringList &rowData);
    void printWithPreview();// 带预览
    void printDirect();     // 直接打印,不带预览

private:
    void resetState();

private slots:
    void getPreviewData(QPrinter *printer);

private:
    QString m_charSet;
    QString m_data;
    QTextStream out;
};

#endif // QPRINTERMANAGER_H

qprintermanager.cpp

#include "qprintermanager.h"
#include <QTextEdit>
#include <QPrintPreviewDialog>
#include <QPrintDialog>
#include <QTextDocument>
#include <QPrinter>
#include <QDateTime>

QPrinterManager::QPrinterManager(QObject *parent) : QObject(parent), m_charSet("utf-8")
{
    out.setString(&m_data);
}

void QPrinterManager::dataBegin()
{
    out << QString("<html>")
        << QString("<head>")
        << QString("<meta content=\"text/html; charset=%1\">").arg(m_charSet)
        << QString("<meta name=Generator content=\"Microsoft Word 12 (filtered)\">")
        << QString("</head>");
}

void QPrinterManager::insertTitle(const QString &title)
{
    out << QString("<p style='text-align:center'><span style='font-size:20.0pt;font-family:宋体'>%1</span></p>\n")
           .arg(title)
        << QString("<p style='text-align:right'><span style='font-size:18.0pt;font-family:宋体'>打印时间:%1</span></p>\n")
           .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
}

void QPrinterManager::insertTitle2(const QString &title2)
{
    out << QString("<p style='text-align:left'><span style='font-size:16.0pt;font-family:宋体'><b>-%1</b></span></p>\n")
           .arg(title2);
}
void QPrinterManager::tableBegin(const QStringList &head)
{
    out << QString("<div align='center' style='width:650px;margin-left:-70px;margin-top:-100px'>")
        << QString("<table class=print width='100%' border=1 cellspacing=0 cellpadding=4 style=border-collapse:collapse>\n")
        << QString("<thead><tr>\n");
    for (int i = 0; i < head.count(); ++i)
    {
        out << QString("<td nowrap='nowarp' style='border:solid windowtext 2.0pt'><p align='center'><span align='center' style='font-size:16.0pt;font-family:宋体'><b>%1</b></span></p></td>\n")
               .arg(head.at(i));
    }
    out << "</tr></thead>\n";
}

void QPrinterManager::insert2TableRow(const QStringList &rowData)
{
    out << QString("<tr>\n");
    for (int i = 0; i < rowData.count(); ++i)
    {
        out << QString("<td><p><span style='font-size:16.0pt;font-family:宋体'>%1</span></p></td>\n")
               .arg(rowData.at(i));
    }
    out << QString("</tr>\n");
}

void QPrinterManager::printWithPreview()
{
    QPrinter printer(QPrinter::ScreenResolution);
    //由于一列的数据项数过多,将打印预览页面设置为水平
    printer.setOrientation(QPrinter::Landscape);
    //设置页边距
    printer.setPageMargins(2, 2, 6, 6, QPrinter::Millimeter);
    printer.setPageSize(QPrinter::A4);
    QPrintPreviewDialog preview(&printer);
    connect(&preview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(getPreviewData(QPrinter*)));
    preview.setWindowState(Qt::WindowMaximized);
    preview.exec();
    resetState();
}

void QPrinterManager::printDirect()
{
    QPrinter printer(QPrinter::ScreenResolution);
    printer.setPageSize(QPrinter::A4);
    QPrintDialog printDialog(&printer);
    if (printDialog.exec() == QDialog::Accepted)
    {
        getPreviewData(&printer);
    }
    resetState();
}

void QPrinterManager::resetState()
{
    m_data.clear();
    m_charSet = "utf-8";
}

void QPrinterManager::getPreviewData(QPrinter *printer)
{
    QTextDocument document;
    document.setHtml(m_data);
    document.print(printer);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "qprintermanager.h"
#include <QSqlTableModel>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_buttonPrint_clicked();

private:
    Ui::Widget *ui;
    QSqlTableModel *model;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlError>
#include <QStringList>
#include <QSqlRecord>
#include <vector>

using namespace std;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("Print Test");
    //SQLite数据库连接
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("../test.db");
    if(!db.open())
    {
        QMessageBox::warning(this, "error", db.lastError().text());
        qDebug()<<QString("fail!!!!!!!!!");
        //return;
    }
    else
    {
        QMessageBox::information(this, "数据库", "数据库连接成功!");
        qDebug()<<QString("success!!!!!!!!!");
    }
    model = new QSqlTableModel(ui->tableView);
    model->setTable("StuInfo");//选择表
    //把model放在view里面
    ui->tableView->setModel(model);
    model->select();
    //设置model1编辑模式为手动提交修改
    //model1->setEditStrategy(QSqlTableModel::OnManualSubmit);
    //只读
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //表格宽度随内容调整
    ui->tableView->horizontalHeader()
        ->setSectionResizeMode(QHeaderView::ResizeToContents);

}

Widget::~Widget()
{
    delete ui;
}
//按下打印按钮
void Widget::on_buttonPrint_clicked()
{
    int rowNum=model->rowCount();
    QString title1=QString("Student Information");//打印表格的标题
    QStringList columnList;//columnList为各列名
    vector<QStringList> dataLists;//dataLists为各行数据
    columnList<<"name"<<"age"<<"ID";
    for(int i=0;i<rowNum;i++)
    {
        QStringList data;
        for(int j=0;j<3;j++)
        {
            data<<model->record(i).value(j).toString();
        }
        dataLists.push_back(data);
    }
    QPrinterManager PM;
    PM.dataBegin();
    PM.insertTitle(title1);
    PM.insertTitle2("blank_shen");
    PM.tableBegin(columnList);
    for(int row=0;row<rowNum;row++)
    {
        PM.insert2TableRow(dataLists[row]);
    }

    PM.tableEnd();
    PM.dataEnd();
    PM.printWithPreview();
}

参考链接:
Qt中(HTML)实现数据表格打印功能

  • 11
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值