【问题标题】:QPrinter unable to style HTML page properly to render image in PDF documentQPrinter 无法正确设置 HTML 页面样式以在 PDF 文档中呈现图像
【发布时间】:2016-05-10 08:54:53
【问题描述】:

我想创建一个带有正确样式 HTML 的 PDF 文档。这就是我正在尝试的:

QTextDocument *doc = new QTextDocument();
const char* s1 = "<html><head><style>body { font-family: sans-serif;}.note-atomic { background: rgb(242,242,242); width: 1000px; margin: 5px auto; border: 1px solid grey; border-radius: 8px;padding: 5px;}</style></head><body><div class = 'note-atomic'>Hi</div><img src = '/Users/attitude/Desktop/RnSghvV.png' width='400' height='300' /></body></html>";
doc->setHtml(QString::fromStdString(s1));

QPrinter *printer = new QPrinter();
printer->setOutputFileName("/Users/attitude/Desktop/fool.pdf");
printer->setOutputFormat(QPrinter::PdfFormat);

QPainter *painter = new QPainter();
painter->begin( printer );
doc->drawContents(painter, printer->pageRect().translated( -printer->pageRect().x(), -    printer->pageRect().y() ));
doc->print(printer);

const char* s2 = "<html><body><div>Bye</div></body></html>";
doc->setHtml(QString::fromStdString(s2));

printer->newPage();
doc->drawContents(painter, printer->pageRect().translated( -printer->pageRect().x(), - printer->pageRect().y() ));

doc->print(printer);
painter->end();

我希望 PDF 有 2 页 - 第一个带有文本 Hi,下一个和最后一个带有文本 Bye。第一个页面的样式就像它出现在具有相同标记的 HTML 页面中一样:

但是,PDF 的第一页内容完全混乱:

如何让它看起来像预期的那样?

我在 HTML 文档中尝试的图像:http://imgur.com/RnSghvV

平台 - Qt 5.3.1,32 位。 OS X 优胜美地。

【问题讨论】:

  • 这是为了奖励@timocov 的答案承诺的赏金。不需要新的答案!

标签: c++ qt pdf qtextdocument qprinter


【解决方案1】:

这是QTextDocument。它呈现富文本(不是 HTML + CSS)。

您可以在 http://doc.qt.io/qt-5/richtext-html-subset.html 上检查的可用属性和元素(例如,pdiv 没有 css 属性 border)。

如果您将 html 代码放入 QTextEdit,您还可以在 Qt Designer 中查看它的外观。

对于呈现 HTML,您可以使用 QWebView (http://doc.qt.io/qt-5/qwebframe.html#print)

webview-&gt;mainFrame()-&gt;print(printer);

【讨论】:

  • 我按照你说的试过了。我得到一个空白的pdf。顺便说一句,应该是webview-&gt;page()-&gt;mainFrame()-&gt;print(printer);...
  • 嗯,这行得通,内容是异步加载的,因此我必须等待loadFinished 信号并在插槽中进行打印。我还有一个小问题,无论我尝试什么,Qprinter 都会破坏页面。如何确保只有一个长页面转储所有内容,而不是在每个 A4 大小间隔后中断页面?
  • 没关系,我把它修好了。抱歉,这个答案应该得到赏金。我目前身无分文,因此无法提供更多赏金。当我再次变得富有时,我会慷慨地提供这个答案.. :)
【解决方案2】:

QTextDocument 不是网络浏览器。它不会为您获取联网 URL。您需要将QVariant QTextDocument::loadResource(int type, const QUrl &amp; name) 方法添加到您的QObjectQWidget is-a QObject!),并使QTextDocument 成为该对象的子对象。文档实例将调用您的 loadResource 实现,您可以在其中利用 QNetworkAccessManager 进行提取。

为了让用户友好,您不能阻止网络请求。这是通过进行两次处理来完成的。首先简单地记下要加载的 URL 并启动它们的获取,返回一个空的QVariant。一旦所有网络请求都成功完成并将它们存储在缓存中,您可以重新运行相同的代码,它会正确呈现页面并且不会阻止网络访问。

所有这些都必须异步完成。

【讨论】:

  • 嗯,不,不。在代码中,我只从磁盘加载图像。我给它只是为了让任何人都可以立即看到该 URL。更改代码。当前代码是我实际尝试并得到上述结果的代码。谢谢。
  • @AttitudeMonger 您的 html 现在没有使用有效的 URL。此外,一旦您修复它以使用有效的文件 URL,请确保它们是绝对路径。
  • 哦,好吧。它们与可执行文件位于同一位置。我什至尝试像新编辑的问题一样给出绝对路径。结果相同。
  • 图片的路径确实不正确。现在图像很好,但布局仍然混乱。已编辑的问题。
猜你喜欢
  • 2018-04-02
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 2021-06-25
  • 2017-10-16
相关资源
最近更新 更多