53.Qt-QPdfWriter绘制PDF,支持表单输出
程序员文章站
2022-03-04 08:58:44
之前打印PDF都是通过html形式来实现的,但是这次要做的东西,需要打印界面控件,所以需要使用QPdfWriter. 通过QPdfWriter来获取QPainter对象,就能实现在PDF上来画画啦. 代码生成的PDF如下所示: 代码效果如下所示: 代码如下所示: //通过dialog来保存PDF路径 ......
之前打印pdf都是通过html形式来实现的,但是这次要做的东西,需要打印界面控件,所以需要使用qpdfwriter.
通过qpdfwriter来获取qpainter对象,就能实现在pdf上来画画啦.
代码生成的pdf如下所示:
代码效果如下所示:
代码如下所示:
//通过dialog来保存pdf路径
qstring mainwindow::pdfsaveas(qstring filename) { qstring file=""; file = qfiledialog::getsavefilename ( this, //父组件 "另存为", //标题 qstring("%1/%2").arg(qstandardpaths::writablelocation(qstandardpaths::desktoplocation)).arg(""+filename+".pdf"), //设置路径, .表示当前路径,./表示更目录 "pdf文件", //过滤器,保存的类型 q_nullptr, qfiledialog::showdirsonly); return file; } //y:表单的y坐标 //horzborder:水平外边距,写0表示没有边距 //row,column:行数和列数 //unitheight:单元高度 //font:字体大小 //list:要写入的单元数据 void mainwindow::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*2; int unitwidth = width/column; for(int i=0;i<row;i++) { int x= horzborder; for(int j=0;j<column;j++) { paint->drawtext(qrect(x,y, unitwidth, unitheight), qt::aligncenter,list[i*column+j]); paint->drawrect(qrect(x,y, unitwidth, unitheight)); x+=unitwidth; } y += unitheight; } } void mainwindow::pdfcreate(checkinfo &info) { // //设置pdf保存的路径 // qstring file_path = pdfsaveas(qstring("表单%1").arg(qdatetime::currentdatetime().tostring("mmdd-hh-mm"))); // if(file_path.isempty()) // return; qstring file_path =qapplication::applicationdirpath()+"/test.pdf"; qfile pdffile(file_path); pdffile.open(qiodevice::writeonly); qpdfwriter* pwriter = new qpdfwriter(&pdffile); //init page pwriter->setpagesize(qpagedpaintdevice::a4); pwriter->setresolution(300); //设置dpi 每个平方英寸像素为300 pwriter->setpagemargins(qmarginsf(30, 30, 30, 30)); qpainter* ppainter = new qpainter(pwriter); //init font qfont font[5]={qfont("宋体",26,60),qfont("宋体",26,61),qfont("宋体",26,qfont::normal),qfont("宋体",26,qfont::normal),qfont("宋体",26,qfont::normal)}; font[0].setpixelsize(86); font[1].setpixelsize(61); font[2].setpixelsize(61); font[3].setpixelsize(42); font[4].setpixelsize(54); //painter pdf qdebug()<<ppainter->viewport(); int npdfwidth = ppainter->viewport().width(); int npdfheight = ppainter->viewport().height(); //在10%的头部居中显示 int y=10; ppainter->setfont(font[0]); ppainter->drawtext(qrect(0,y, npdfwidth, 100), qt::aligncenter, m_arg.printtitle); 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); y+=60; ppainter->setfont(font[2]); ppainter->drawtext(qrect(100,y, npdfwidth/2, 70), qt::alignvcenter | qt::alignleft, qstring("器件型号: %1").arg(info.dev.name)); ppainter->setfont(font[2]); ppainter->drawtext(qrect(npdfwidth/2+100,y, npdfwidth/2-100, 70), qt::alignvcenter | qt::alignleft, qstring("器件编号: %1").arg(info.devnum)); y+=90; ppainter->setfont(font[2]); ppainter->drawtext(qrect(100,y, npdfwidth/2, 70), qt::alignvcenter | qt::alignleft, qstring("装车车号: %1").arg(info.devcar)); ppainter->setfont(font[2]); ppainter->drawtext(qrect(npdfwidth/2+100,y, npdfwidth/2-100, 70), qt::alignvcenter | qt::alignleft, qstring("试验日期: %1").arg(info.checkdate)); y+=110; ppainter->setfont(font[1]); ppainter->drawtext(qrect(0,y, npdfwidth, 80), qt::alignvcenter | qt::alignleft, "减 振 器 标 准 参 数"); y+=120; qstringlist list; list<<"速度"<<"压力"<<"拉力"<<"阻尼系数"<<"不对称率"<<"正允差"<<"负允差"; list<<info.dev.speed+"m/s"<<info.dev.yali+"kn"<<info.dev.lali+"kn"<<\ info.dev.zhuni+"kns/m"<<info.dev.buduic+"%"<<info.dev.zyuncha+"%"<<info.dev.fyuncha+"%"; pdfdrawform(ppainter,y,0,2,7,100,font[3],list); y+=260; ppainter->setfont(font[1]); ppainter->drawtext(qrect(0,y, npdfwidth, 80), qt::alignvcenter | qt::alignleft, "示 功 图"); y+=100; //获取界面图片 int imageborder=150; //设置图片水平边距为150 qpixmap pixmap = qpixmap::grabwidget(m_checkchart, m_checkchart->rect()); float x = (float)(npdfwidth-imageborder*2)/(float)pixmap.width(); pixmap= pixmap.scaled(npdfwidth-imageborder*2, x*pixmap.height(),qt::ignoreaspectratio); //根据大小比例,来放大缩小图片 ppainter->drawpixmap(imageborder, y, pixmap); y+=pixmap.height()+90; ppainter->setfont(font[1]); ppainter->drawtext(qrect(0,y, npdfwidth, 80), qt::alignvcenter | qt::alignleft, "减 振 器 测 试 结 果"); y+=120; list.clear(); list<<"拉伸行程:"<<qstring::asprintf("%.2fmm",info.lasheng)<<"压缩行程:"<<qstring::asprintf("%.2fmm",info.yasuo)<<"最大速度:"<<qstring::asprintf("%.3fm/s",info.speed)<<"阻尼系数:"<<qstring::asprintf("%.2fkns/m",info.speed) <<"最大压力:"<<qstring::asprintf("%.2fkn",info.max)<<"压力偏差:"<<qstring::asprintf("%.2f%",info.maxbaifengb)<<"最大拉力:"<<qstring::asprintf("%.2fkn",info.min)<<"拉力偏差:"<<qstring::asprintf("%.2f%",info.minbaifengb) <<"不对称率:"<<qstring::asprintf("%.2f%",info.buduic)<<"运行时间:"<<qstring::asprintf("%ds",info.rundate)<<"试验结果:"<<info.result<<"曲线结论:"<<info.chartresult; pdfdrawform(ppainter,y,0,3,8,100,font[3],list); y+=400; ppainter->setfont(font[4]); ppainter->drawtext(qrect(50,y, npdfwidth/3, 80), qt::alignvcenter | qt::alignleft, qstring( "试验员: %1").arg(m_userlogininfo->name)); ppainter->drawtext(qrect(npdfwidth/3+50,y, npdfwidth/3, 80), qt::alignvcenter | qt::alignleft, qstring( "检查员签字: ")); ppainter->drawtext(qrect(npdfwidth/3*2,y, npdfwidth/3, 80), qt::alignvcenter | qt::alignleft, qstring( "签字日期: ")); // pwriter->newpage(); //写下一页 //绘制完毕 delete ppainter; delete pwriter; pdffile.close(); //通过其它pdf阅读器来打开pdf qdesktopservices::openurl(qurl::fromlocalfile(file_path)); }