QT 您所在的位置:网站首页 怎么画表格在纸上 QT

QT

2024-06-13 00:51| 来源: 网络整理| 查看: 265

文章目录 前言一、初始化创建文件位置二、绘制表格1.绘制表格函数(仅供参考,你们肯定写得更好)2.基于QTableWidget绘制表格函数 三、pdf换页逻辑器1.判断当前y值是否超出了某一界限,若超出了,则pdf翻页,y设定为10 否则y直接改为设定值(勉强可以用,希望各位大神有更好的解决办法) 四、第二类标题生成单元(可举一反三,我就不反了)1.一个指定位置,背景之类的标题生成器,勉强可用 五、根据路径创建pdf文件1.记录路径创建pdf生成器2.初始化字体样式3.绘制pdf内容(初始化)4.绘制页脚(仅供参考)5.绘制logo图(仅供参考)6.绘制大标题7.强制跳转到最后一页 六.导入曲线图1.QChart2.QCustomPlot 七.通过其它PDF阅读器来打开PDF总结

前言

因项目需要,需要自行手绘pdf报表,网上已经有一些相关的方案实现了,但是没有一条龙服务,包括表头,表格,页眉,页脚,曲线图等,在这里我实现了以后,记录一下。(因为项目保密需要,没有图,反正肯定是能用的) 另外,由于大家情况各不相同,我不可能把我代码一股脑弄上来,不合理,所以就挑一些功能项摘出来介绍,大家灵活应用参考。 内容有点乱,没有做优化整理,不喜勿喷,右上角有个x,对,浏览器右上角那个,可以点。 友好意见,欢迎交流

一、初始化创建文件位置

这一步先做个弹窗,用于存放我们的pdf

//通过dialog来保存PDF路径 QString MyDialog::pdfSaveAs(QString fileName) { QString file = QFileDialog::getSaveFileName( this, //父组件 "另存为", //标题 QCoreApplication::applicationDirPath() + QString::fromLocal8Bit("/data/Report/%1").arg(fileName + ".pdf"), //设置路径, .表示当前路径,./表示更目录 QString::fromLocal8Bit("PDF文件(*.pdf)"), //过滤器,保存的类型 Q_NULLPTR, QFileDialog::ShowDirsOnly); return file; }

调用办法

QString file_path = pdfSaveAs(QString::fromLocal8Bit("报告%1").arg(QDateTime::currentDateTime().toString("_yy_MM_dd_hh_mm")) + ".pdf")); 二、绘制表格 1.绘制表格函数(仅供参考,你们肯定写得更好) //y:表单的Y坐标 //horzBorder:水平外边距,写0表示没有边距 //row,column:行数和列数 //unitHeight:单元高度 //font:字体大小 //list:要写入的单元数据 void MyDialog::pdfDrawForm(QPainter* paint, int y, int horzBorder, int row, int column, int unitHeight, QFont& font, QStringList& list) { paint->setFont(font); paint->setPen(QPen(QBrush(QColor(0, 0, 0)), 2)); int Width = paint->viewport().width() - (horzBorder setFont(font); paint->setPen(QPen(QBrush(QColor(0, 0, 0)), lineweight)); const int Width = paint->viewport().width() - (horzBorder columnCount() + 1; const int unitWidth = Width / column; int x_head_up = horzBorder; font.setBold(true); paint->setFont(font); paint->drawText(QRect(x_head_up, y, unitWidth, unitHeight), Qt::AlignCenter, QString::fromLocal8Bit("你想要放在左上角的信息").arg(unit)); paint->drawRect(QRect(x_head_up, y, unitWidth, unitHeight)); x_head_up += unitWidth; for (int j = 1; j drawText(QRect(x_head_up, y, unitWidth, unitHeight), Qt::AlignCenter, table_get->horizontalHeaderItem(j - 1)->text()); paint->drawRect(QRect(x_head_up, y, unitWidth, unitHeight)); x_head_up += unitWidth; } y += unitHeight; for (int i = 1; i setFont(font); paint->drawText(QRect(x, y, unitWidth, unitHeight), Qt::AlignCenter, table_get->verticalHeaderItem(i - 1)->text()); paint->drawRect(QRect(x, y, unitWidth, unitHeight)); x += unitWidth; font.setBold(false); paint->setFont(font); for (int j = 1; j drawText(QRect(x, y, unitWidth, unitHeight), Qt::AlignVCenter | Qt::AlignRight, table_get->item(i - 1, j - 1)->text()); paint->drawRect(QRect(x, y, unitWidth, unitHeight)); x += unitWidth; } y += unitHeight; } return y; } 三、pdf换页逻辑器 1.判断当前y值是否超出了某一界限,若超出了,则pdf翻页,y设定为10 否则y直接改为设定值(勉强可以用,希望各位大神有更好的解决办法)

这个破函数是我自己造的,用来更新y的值,可以比较方便的判断是否需要换页,并更新y值

//写一个函数,判断当前y值是否超出了某一界限,若超出了,则pdf翻页,y设定为10 否则y直接改为设定值 void MyDialog::setYvalue_with_if(int& y_now, int y_target, int set_limit, int& page_now, QPdfWriter* get_writer, QPainter* paint, QImage get_logo_img_tmp, QString file_path, bool show_logo_flag) { if (y_target > set_limit) { get_writer->newPage(); page_now++; int nPDFWidth = paint->viewport().width(); int nPDFHeight = paint->viewport().height(); const int nPDFWidth_1_4 = nPDFWidth >> 2; const int top_gap = 140; const int bottom_gap = 25; //绘制页脚 paint->setPen(QPen(QBrush(QColor(0, 0, 0)), 5)); paint->drawLine(0, nPDFHeight - bottom_gap, nPDFWidth, nPDFHeight - bottom_gap); QFont font_tmp = QFont(QString::fromLocal8Bit("黑体"), 26, QFont::Normal); font_tmp.setPixelSize(25); paint->setFont(font_tmp); paint->drawText(QRect(0, nPDFHeight - bottom_gap, nPDFWidth, bottom_gap), Qt::AlignLeft, QString::fromLocal8Bit("文件名: %1").arg(file_path)); QImage show_logo = get_logo_img_tmp.scaled(QSize(top_gap * 2, top_gap), Qt::KeepAspectRatio, Qt::SmoothTransformation); if (show_logo_flag) { paint->drawImage(QPoint(0, 0), show_logo); } paint->drawText(QRect(nPDFWidth - 200, nPDFHeight - 25, bottom_gap, 25), Qt::AlignRight, QString::fromLocal8Bit("页码:%1").arg(QString::number(page_now))); y_now = top_gap; paint->setPen(QPen(QBrush(QColor(0, 0, 0)), 5)); paint->drawLine(0, y_now, nPDFWidth, y_now); y_now = top_gap + 5; } else { y_now = y_target; } } 四、第二类标题生成单元(可举一反三,我就不反了) 1.一个指定位置,背景之类的标题生成器,勉强可用 //第二类标题生成单元 void MyDialog::pdf_title_2_set(QString title_text, int title_width, int title_height, int first_background, QFont font_title, QPdfWriter* get_writer, QPainter* paint, int& y, int set_limit, int& page_now, QImage get_logo_img_tmp, QString file_path, bool show_logo_flag) { if (y + title_height > set_limit) { setYvalue_with_if(y, y + title_height, set_limit, page_now, get_writer, paint, get_logo_img_tmp, file_path); } paint->fillRect(QRect(0, y, title_width, title_height), QGradient::Preset(first_background)); paint->setFont(font_title); paint->drawText(QRect(10, y, title_width, title_height), Qt::AlignVCenter | Qt::AlignLeft, title_text); setYvalue_with_if(y, y + title_height, set_limit, page_now, get_writer, paint, get_logo_img_tmp, file_path); paint->setPen(QPen(QBrush(QColor(0, 0, 0)), 3)); paint->drawLine(0, y, title_width, y); setYvalue_with_if(y, y + 5, set_limit, page_now, get_writer, paint, get_logo_img_tmp, file_path); } 五、根据路径创建pdf文件 1.记录路径创建pdf生成器

其实到这一步,会的人就都会了,反正变成QPainter了,剩下的不是随便你们搞么,可发挥的地方就多了。 代码如下:

//判断路径是否为空 if (file_path.isEmpty()) return; //初始化pdf文件 QFile pdfFile(file_path); pdfFile.open(QIODevice::WriteOnly); //初始化pdf信息 QPdfWriter* pWriter = new QPdfWriter(&pdfFile); pWriter->setPageSize(QPagedPaintDevice::A4); pWriter->setResolution(300); //设置dpi 每个平方英寸像素为300 pWriter->setPageMargins(QMarginsF(30, 30, 30, 30));//上下左右间隔,这个就不废话了 //初始化绘制层 QPainter* pPainter = new QPainter(pWriter); //中间填写你要绘制的东西 //绘制完毕 delete pPainter; delete pWriter; pdfFile.close(); 2.初始化字体样式

代码如下:

//初始化字体样式 QFont font[6] = { QFont(QString::fromLocal8Bit("黑体"),26,QFont::Bold), QFont(QString::fromLocal8Bit("黑体"),26,QFont::Normal), QFont(QString::fromLocal8Bit("黑体"),26,QFont::Bold), QFont(QString::fromLocal8Bit("黑体"),26,QFont::Normal), QFont(QString::fromLocal8Bit("黑体"),26,QFont::Normal), QFont(QString::fromLocal8Bit("黑体"),26,QFont::Normal) }; font[0].setPixelSize(86); font[1].setPixelSize(55); font[2].setPixelSize(35); font[3].setPixelSize(42); font[4].setPixelSize(54); font[5].setPixelSize(25); 3.绘制pdf内容(初始化)

代码如下:

//Painter PDF qDebug() viewport().width(); int nPDFHeight = pPainter->viewport().height(); const int nPDFWidth_1_4 = nPDFWidth >> 2; const int nPDFWidth_1_8 = nPDFWidth >> 3; int page_now = 1; const int top_gap = 140; const int bottom_gap = 25; const int title_1_height = 100;//标题一高度 const int title_2_height = 65;//标题二高度 const int chart_height = 880; const int unitHeight = 39;//表格单行高度 const int line_head = 50;//文字缩进 int y = 0;//比较重要,贯穿始终,指向当前绘制的高度 4.绘制页脚(仅供参考)

代码如下:

//绘制页脚 pPainter->setPen(QPen(QBrush(QColor(0, 0, 0)), 5)); pPainter->drawLine(0, nPDFHeight - bottom_gap, nPDFWidth, nPDFHeight - bottom_gap); pPainter->setFont(font[5]); pPainter->drawText(QRect(0, nPDFHeight - bottom_gap, nPDFWidth, bottom_gap), Qt::AlignLeft, QString::fromLocal8Bit("文件名: %1").arg(file_path)); pPainter->drawText(QRect(nPDFWidth - 200, nPDFHeight - 25, bottom_gap, 25), Qt::AlignRight, QString::fromLocal8Bit("页码:%1").arg(QString::number(page_now))); 5.绘制logo图(仅供参考)

代码如下:

//左上角绘制logo图 QImage show_logo = get_logo_img_tmp.scaled(QSize(top_gap * 2, top_gap), Qt::KeepAspectRatio, Qt::SmoothTransformation); if (show_logo_flag) { pPainter->drawImage(QPoint(0, 0), show_logo); } 6.绘制大标题

代码如下:

//在10%的头部居中显示 //0.主标题信息展示 pPainter->fillRect(QRect(0, y, nPDFWidth, title_1_height), QGradient::Preset(title_background)); pPainter->setFont(font[0]); pPainter->drawText(QRect(0, y, nPDFWidth, title_1_height), Qt::AlignCenter, QString::fromLocal8Bit("什么什么检测报告")); y += 140; pPainter->setPen(QPen(QBrush(QColor(0, 0, 0)), 5)); pPainter->drawLine(0, y, nPDFWidth, y); pPainter->drawLine(0, y + 18, nPDFWidth, y + 18); setYvalue_with_if(y, y + 20, nPDFHeight - bottom_gap, page_now, pWriter, pPainter, get_logo_img_tmp, file_path, show_logo_flag); 7.强制跳转到最后一页

代码如下:

//强行跳转到最后一页 setYvalue_with_if(y, y + nPDFHeight, nPDFHeight - bottom_gap, page_now, pWriter, pPainter, get_logo_img_tmp, file_path, show_logo_flag); 六.导入曲线图 1.QChart

可以通过QChartView把已经画好的QChart拉出来,然后变个尺寸扔进去,然后记得把尺寸变回来,清空一下之前放QChartView的地方(清空方法友情赠送,不谢),再把这个扔回去就行。这个方法如果用opengl的话容易出问题,建议不要弄,如果弄的话,记得重新把opengl打开(如果可以的话)。 基本原理就是把窗体扣下来变成QPixmap然后画到pdf里。你们可以举一反三一下。 代码如下:

QChartView* chartView_tmp = new QChartView(&chart_A); chartView_tmp->setRenderHint(QPainter::Antialiasing); float old_w = chartView_tmp->width(); float old_h = chartView_tmp->height(); float show_w = nPDFWidth - (imageBorder rect()); chartView_tmp->resize(QSize(old_w, old_h)); if (y + show_h > nPDFHeight - bottom_gap) { setYvalue_with_if(y, y + show_h, nPDFHeight - bottom_gap, page_now, pWriter, pPainter, get_logo_img_tmp, file_path, show_logo_flag); } pPainter->drawPixmap(imageBorder, y, pixmap); //清空verticalLayout_widget布局内的所有元素 QLayoutItem* child; while ((child = ui.verticalLayout_widget->takeAt(0)) != 0) { //setParent为NULL,防止删除之后界面不消失 if (child->widget()) { child->widget()->setParent(NULL); } delete child; } ui.verticalLayout_widget->addWidget(chartView_tmp); 2.QCustomPlot

代码如下:

QCustomPlot* show_plot = ui.mycustomplot; float show_w = nPDFWidth - (imageBorder


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有