QT5 界面截图保存到本地+输出PDF/WORD格式文档+QT界面中文乱码及输出PDF中文乱码的解决(亲身实践并且成功)

最近做了一个和QT5有关的项目,遇到很多问题也学习到不少,特意写下来希望帮到更多的人。(我的版本VS2017+QT5.12.0)
一、QT5截图并保存到本地
在头文件添加必须项

#include <QScreen>
#include <QPixmap>

截图功能的代码

    QScreen *screen=QGuiApplication::primaryScreen();
    QPixmap pixmap=screen->grabWindow(ui->qvtkWidget->winId());
    //qvtkWidget->winId()这是你要截图的控件的winID,主窗口0(全屏截图的意思)winId(0)
	pixmap.save("E:/screen.jpg","jpg"); //保存地址可以改成你自己的

二、QT5输出PDF/WORD文档(类似于打印报表)
添加头文件

#include <QPrinter>

输出带有文字的PDF

QPainter text_painter;
QPrinter text_printer; 
text_printer.setOutputFormat(QPrinter::PdfFormat);
text_printer.setOutputFileName("test_text.pdf"); 
text_painter.begin(&text_printer);
for (int i = 0; i < 5; i++)
    text_painter.drawText(10, i * 30, "hello world");
text_painter.end();

输出带有图片的PDF

    QPrinter printer_pixmap(QPrinter::HighResolution);
    printer_pixmap.setPageSize(QPrinter::A4);  //设置纸张大小为A4
    printer_pixmap.setOutputFormat(QPrinter::PdfFormat);  //设置输出格式为pdf
    printer_pixmap.setOutputFileName(sFilePdf1);   //设置输出路径
    QPainter painter_pixmap;
    //myImg是自定义的照片
    QPixmap pixmap(myImg);
    painter_pixmap.begin(&printer_pixmap);
    QRect rect = painter_pixmap.viewport();
    int multiple = rect.width()/pixmap.width();
    painter_pixmap.scale(multiple, multiple); //将图像(所有要画的东西)在pdf上放大multiple-1倍
    painter_pixmap.drawPixmap(0, 0, pixmap);  //画图
    painter_pixmap.end();

但我用这种方法始终无法生成带有图片的pdf文档,不知道哪里出了问题。就换了另一种方法,就可以生成文字图片都有的pdf文档。
核心思想就是以html语言为核心对pdf/word格式编写,再用QTextDocument输出。

头文件(我直接把我所有的都写出来了,你们可以根据自己的需求修改):

#include <QTextDocument>
#include <QtPrintSupport/QPrinter>
#include <QPainter>
#include <QPen>
#include <QTextBrowser>
#include <QPixmap>
#include <QDateTime>
#include <QDesktopWidget>
#include <QPdfWriter>
#include <QScreen>
#include <QFile>
#include <QTextBlock>

代码大致分为两部分:
第一部分:对文档格式编写(注意:格式可以根据自己需求改,书写格式遵循H5语言即可)

QString saveHtmlToPDF()
{
	QString html = "";
	html += "<html>";
	html += "<head>";
	html += "<title>qt生成pdf报表</title>";
	html += "<head>";
	html += "<body style=\"bgcolor:yellow\">";
	html += "<h1 align=\"center\">xxx报表</h1>";
	html += "<h2 align=\"left\">一.一级标题</h2>";
	html += "<h3 align=\"left\">1.二级标题</h3>";
	html += "<hr>";
	QString text;
	text = ui->textBrowser->document()->toHtml();
	//这里是将qt的文本控件内容直接输入给pdf文档
	html += text;
	html += "<hr>";
	html += "<h3 align=\"left\">2.图像数据</h3>";
	html += "<p align=\"left\">(1)图像名称1</p>";
	html += "<p align=\"center\"><img src=\"F:\\tabWidget_screen1.jpg\" alt=\"picture\" width=\"582\" height=\"400\"></p>";
	html += "<p align=\"left\">(2)图像名称2</p>";
	html += "<p align=\"center\"><img src=\"F:\\tabWidget_screen2.jpg\" alt=\"picture\" width=\"582\" height=\"400\"></p>";
	html += "<p align=\"left\">(3)图像名称3</p>";
	html += "<p align=\"center\"><img src=\"F:\\tabWidget_screen3.jpg\" alt=\"picture\" width=\"582\" height=\"400\"></p>";
	html += "<h2 align=\"left\">二.缺陷检测</h2>";
	html += "<h3 align=\"left\">1.总缺陷点云</h3>";
	html += "<p align=\"left\">(1)数量信息</p>";
	html += "<hr>"; //生成一条横线
	text = ui->lineEdit->text(); //获取控件的文本内容
	html += text;
	//文档结尾可以加上生成时间,看你自己选择。若要加上功能头文件还需添加 #include <QDateTime>
	html += "<p align=\"left\">报表生成时间:</p>";
	QDateTime current_date_time = QDateTime::currentDateTime();
	QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss");
	html += current_date;
	html += "</body>";
	html += "</html>";
	return html;
}

第二部分:将以上html转化成QT的文件输出文档

void picture2Pdf()
{

	QPrinter printer_pixmap(QPrinter::HighResolution);
	printer_pixmap.setPageSize(QPrinter::A4);  //设置纸张大小为A4
	printer_pixmap.setOutputFormat(QPrinter::PdfFormat);  //设置输出格式为pdf
	QString file_path = QFileDialog::getSaveFileName(this, "保存报表", QString(), "*.pdf");  //用文件对话框设置输出路径
	if (!file_path.isEmpty())
	{
		//如果没有写后缀就自动加上
		if (QFileInfo(file_path).suffix().isEmpty())
		{
			file_path.append(".pdf");  //或者 file_path+=".pdf"
		}
	}
	//若你pdf文档里插入的图片是截图qt界面,这部分代码则需要。若你pdf文档要插入的图片是本地自带的,则不需要这部分截图代码
	QScreen *screenNew = QGuiApplication::primaryScreen();
	QPixmap pixmapNew = screenNew->grabWindow(ui->qvtkWidget_2->winId());
	pixmap.save("E:/screen.jpg","jpg");
	//截图代码完毕,若你需要多次截图,更换grabWindow(ui->qvtkWidget_2->winId())中的内容即可
	QTextDocument document;
	QString html = saveHtmlToPDF();
	document.setHtml(html);
	document.print(&printer_pixmap);
	document.end();
}

若要生成word文档,只需要将第二部分函数中的

    QTextDocument document;
	QString html = saveHtmlToPDF();
	document.setHtml(html);
	document.print(&printer_pixmap);
	document.end();

更换为

    QString docname = "E:/testhtmlword.doc"; //文件保存地址也可更改为自定义位置,参考我上面的代码
    QString html = saveHtmlToWord(); //pdf中的函数名是saveHtmlToPDF()
    QFile outFile(docname);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append );
    QTextStream ts(&outFile);
    ts<<html<<endl;

三、QT5输出PDF/WORD文档容易出现的问题
问题1:error LNK2019: 无法解析的外部符号 “_declspec(dllimport) public: __thiscall QPrintDialog::QPrintDialog(class QPrinter *,class QWidget *)” (__imp??0QPrintDialog@@QAE@PAVQPrinter@@PAVQWidget@@@Z),该符号在函数 “protected: void __thiscall EasyEditor::showPrintText(void)” (?showPrintText@EasyEditor@@IAEXXZ) 中被引用 F:\QtSourceCode\Easy Editor\Easy Editor\EasyEditor.objEasy Editor

解决方式:右击项目,选择“属性”–>“链接器”–>“输入”–>”附加依赖项”–>”编辑”
在最后添加上“Qt5PrintSupport.lib”即可。

问题2:使用QPrinter和QprintDialog类时的附加处理

解决方式:①若是在QT Creator中,需要在 (.pro)工程文件中加入 “QT+= printsupport ”,否则会编译报错
②若是在VS环境下,只需在相应头文件中添加以下两条语句(我上文分开提到过,这里集中说一下)

#include <QtPrintSupport/QPrintDialog>
#include <QtPrintSupport/QPrinter>

四、QT5中文乱码
1.QT5软件界面中文乱码(改变编码格式为utf-8,在cpp文件中设置编码字符集,只在VS编译器下生效)
解决:

#if _MSC_VER >= 1600  
#pragma execution_character_set("utf-8")  
#endif  

2.QString中文乱码
解决:

QString str = QString::fromUtf8("中文");     // 源码是UTF-8 编码
QString str = QString::fromLocal8Bit("中文");    // 源码是GBK 编码(记事本中的 ANSI 编码)

这样两种方法也可以解决QT5输出的PDF/WORD中文乱码问题,总结一句中文乱码就是编码格式问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值