Qt:使用 HTML 在 QTextDocument 上设置背景图像以生成 pdf 文件

Qt: Set background image on QTextDocument using HTML to generate pdf file

我在这个问题上纠结了好几次。 我需要通过创建一个包含一些数据的 pdf 文件来创建报告。 所以我的计划是不使用 QTextCursor,而是使用 HTML + CSS 在我的 pdf 文件中创建内容。 不幸的是,我不能使用 QWebEngine 小部件解决方案,因为我正在编译到 MinGW 中并且设置 MVSC 2017 环境是一团糟。 遗憾的是,我必须使用 QTextDocument 及其 HTML 子集支持。

我的问题是我无法在我的 pdf 文件中放置背景图片。 我想把这张图片作为背景图片:

让我疯狂的是我使用 css 属性 在我的 pdf 文件中显示背景图像。

background-image: url(:/images/blue-gradient-background.jpg);

Qt 似乎考虑到了这一点,但它仍然不显示背景。

看看:

第一个 pdf 文件不包含 html 内容上的 css 属性 背景图像,但第二个包含并且您可以看到文件的大小更大所以它已经考虑了 css 属性。 但它没有显示背景: 左边是第一个文件,右边是第二个文件 css 属性.

我使用资源中的 html 文件生成报告:

<!DOCTYPE html>
<html>
  <style>

    body {
      background-image: url(:/images/blue-gradient-background.jpg);
    }

    h1 {
      color: blue;
    }
    
    #table-content {

    }
    
    #table-content table {
        margin: 1em    
    }
    
  </style>

  <body>
    <div align="center"><h1>[title-template]</h1></div>
    
    <div align="center" id="table-content">[table-template]</div>
    
  </body>
</html>

此 html 文件已在 class 的构造函数中打开并读取:

FileEditor::FileEditor()
{
    QFile htmlTemplate(":/html/report.html");
    if (htmlTemplate.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&htmlTemplate);
        m_reportPageHTMLTemplate = in.readAll();
    }

}

然后我使用自定义 class 和此功能,使用 QPrinterQPainter 写入数据:

void FileEditor::writeReportPdfFile(const QString &i_path, const S12xConf &i_s12xConf, const S12xData &i_s12xData, const BenchTestData &i_benchTestData)
{
    QDir directory(i_path); // we create a QDir with the path
    if (!directory.exists()) // if the directory does not exist then
    {
        directory.mkpath("."); // we create the path
    }

    QString fileName = getCurrentHourDate() + "_S12xNG_Test_Report.pdf";

    QPrinter pdfPrinter(QPrinter::HighResolution);
    pdfPrinter.setOutputFormat(QPrinter::PdfFormat);
    pdfPrinter.setPageSize(QPageSize(QPageSize::A4));
    pdfPrinter.setOutputFileName(i_path + "/" + fileName);
    pdfPrinter.setFullPage(true);
    QPainter painter(&pdfPrinter);
    painter.setBackgroundMode(Qt::OpaqueMode);

    QTextDocument measuresDoc;
    QTextDocument averagesDoc;
    QTextDocument inOutDoc;
    measuresDoc.documentLayout()->setPaintDevice(&pdfPrinter);
    measuresDoc.setPageSize(pdfPrinter.pageRect().size());
    averagesDoc.documentLayout()->setPaintDevice(&pdfPrinter);
    averagesDoc.setPageSize(pdfPrinter.pageRect().size());
    inOutDoc.documentLayout()->setPaintDevice(&pdfPrinter);
    inOutDoc.setPageSize(pdfPrinter.pageRect().size());
    setMeasuresTextDocument(&measuresDoc);
    setAveragesTextDocument(&averagesDoc);
    setInputsOutputsTextDocument(&inOutDoc);

    measuresDoc.drawContents(&painter); // We print TextDocument of the Measures into the document
    pdfPrinter.newPage(); // We inject the current page and continue printing on new page
    averagesDoc.drawContents(&painter); // We print the TextDocument of the Averages into the document
    pdfPrinter.newPage(); // We inject the current page and continue printing on new page
    inOutDoc.drawContents(&painter); // We print the TextDocument of the Inputs/Outputs into the document

    measuresDoc.undo();
    averagesDoc.undo();
    inOutDoc.undo();

}

这是将 html 数据添加到度量 QTextDocument 中的函数:

void FileEditor::setMeasuresTextDocument(QTextDocument *o_measuresDoc)
{
    QString htmlContent = m_reportPageHTMLTemplate;
    htmlContent.replace("[title-template]","I. Measures Data");
    o_measuresDoc->setHtml(htmlContent);
}

所以我做错了什么? 预先感谢您的回复。

我找到答案了!

是关于QTextDocument的drawContents方法。 为了在文档中看到背景图像,您需要添加第二个参数。 它是一个 QRectF 对象,代表背景图像将被裁剪到的矩形的大小。

void QTextDocument::drawContents(QPainter *p, const QRectF &rect = QRectF()) Draws the content of the document with painter p, clipped to rect. If rect is a null rectangle (default) then the document is painted unclipped.

所以我做的是:

easuresDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print TextDocument of the Measures into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
averagesDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print the TextDocument of the Averages into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
inOutDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print the TextDocument of the Inputs/Outputs into the document

pdfPrinter.paperRect是没有边距的页面矩形。

此外,如果您希望背景图像按比例打印而不重复,则需要将打印机设置为 QPrinter::PrinterResolution

QPrinter pdfPrinter(QPrinter::PrinterResolution);