在Qt中创建HTML页面并将页面保存为PDF文件

问题描述 投票:0回答:1

我正在尝试使用 Qt C++ 创建 HTML 文件,然后将其保存为 PDF 文件。到目前为止,我已经成功创建了一个 HTML 文件,但是当我尝试将其保存为 PDF 文件时,我在控制台中收到警告 D3D11 Live Object,并且不会创建 PDF 文件。 我看了很多论坛解决方案,我都尝试过,但似乎不起作用,也许我监督了什么?

编辑:我正在调试模式下运行我的代码!在发布模式下它实际上可以工作......为什么?!!!

这是我的代码:

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebEngineSettings>
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    createHtmlFile(); // Create the HTML file

    view = new QWebEngineView(this);
    connect(view, &QWebEngineView::loadFinished, this, &MainWindow::onLoadFinished);

    QString htmlFilePath = QCoreApplication::applicationDirPath() + "/index.html"; //Returns the directory that contains the application executable
    qDebug() << "Loading HTML file from: " << htmlFilePath;
    view->setUrl(QUrl::fromLocalFile(htmlFilePath));
    setCentralWidget(view);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createHtmlFile()
{
    QString htmlFilePath = QCoreApplication::applicationDirPath() + "/index.html"; //Returns the directory that contains the application executable
    QFile file(htmlFilePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file for writing: " << file.errorString();
        QMessageBox::warning(this, "File Error", "Failed to create HTML file: " + file.errorString());
        return;
    }

    QTextStream out(&file);
    out << "<!DOCTYPE html>\n";
    out << "<html lang=\"en\">\n";
    out << "<head>\n";
    out << "<meta charset=\"UTF-8\">\n";
    out << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
    out << "<title>QWebEngine Example</title>\n";
    out << "</head>\n";
    out << "<body>\n";
    out << "<h1>Hello from QWebEngine!</h1>\n";
    out << "<p>This is a simple HTML page loaded using Qt's QWebEngine.</p>\n";
    out << "</body>\n";
    out << "</html>\n";
    file.close();
    qDebug() << "HTML file created successfully at: " << htmlFilePath;
}

void MainWindow::onLoadFinished(bool ok)
{
    if (ok)
    {
        qDebug() << "HTML file loaded successfully.";
        generatePdf(); // Generate the PDF once the HTML is loaded
    }
    else
    {
        qDebug() << "Failed to load HTML file.";
        QMessageBox::warning(this, "Load Error", "Failed to load the HTML file.");
    }
}


void MainWindow::generatePdf() //Does not work
{
    QString pdfFilePath = QFileDialog::getSaveFileName(this, tr("Save PDF"),
                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                    tr("PDF Files (*.pdf)"));
    if (pdfFilePath.isEmpty())
        return;

    view->page()->printToPdf(pdfFilePath);
}

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWebEngineView>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void generatePdf();

private slots:
    void onLoadFinished(bool);

private:
    Ui::MainWindow *ui;
    QWebEngineView *view;
    void createHtmlFile();
};

#endif // MAINWINDOW_H

main.cpp

#include "MainWindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

不会创建 PDF 文件。这是我运行程序后控制台的样子:

> HTML file created successfully at: 
> "C:/Users/melika.javadi/Documents/build-HTMLtoPDF-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug/debug/index.html"
> Loading HTML file from: 
> "C:/Users/melika.javadi/Documents/build-HTMLtoPDF-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug/debug/index.html"
> doh set to ""  --  SystemOnly HTML file loaded successfully. D3D11
> WARNING: ID3D11Device::CreateInputLayout: The provided input signature
> expects to read an element with SemanticName/Index: 'TEXCOORD'/2 and
> component(s) of the type 'int32'.  However, the matching entry in the
> Input Layout declaration, element[2], specifies mismatched format:
> 'R16G16_UINT'.  This is not an error, since behavior is well defined:
> The element format determines what data conversion algorithm gets
> applied before it shows up in a shader register. Independently, the
> shader input signature defines how the shader will interpret the data
> that has been placed in its input registers, with no change in the
> bits stored.  It is valid for the application to reinterpret data as a
> different type once it is in the vertex shader, so this warning is
> issued just in case reinterpretation was not intended by the author. [
> STATE_CREATION WARNING #391: CREATEINPUTLAYOUT_TYPE_MISMATCH] Received
> fatal exception EXCEPTION_BREAKPOINT Backtrace:
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74F19CE8+276867377]    invalid_parameter
> [0x00007FFBBB30AF0F+207]  QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B758B88+386176977]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B7584FD+386175302]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B75855D+386175398]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B758431+386175098]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B75874A+386175891]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7B74A113+386116956]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E226B7+477180672]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E22A6B+477181620]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E28B1C+477206373]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E14C7B+477124804]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E1561C+477127269]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E169B0+477132281]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2FAE6+477234991]
>   QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64F6E615+8778334]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2067E+477172423]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2232C+477179765]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2942B+477208692]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E2CAB2+477222651]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74B63F9F+272976872]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB80E1CEF5+477158206]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7677ACDA+302430499]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB76778993+302421468]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB767BB198+302693857]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7677A0A8+302427377]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77252F2F+313801592]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77246F0B+313752404]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77247625+313754222]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77247A60+313755305]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB77258336+313823103]
>   QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64F6E615+8778334]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74D1D637+274784896]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74EC31F7+276512320]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74ED6B35+276592510]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74ED5A3F+276588168]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74C64226+274026095]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74EE1438+276635777]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB74E714AD+276177142]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7BABB1FD+389725766]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7328538C+246898645]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB73283F90+246893529]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB7327D0D1+246865178]
>   QWebEnginePage::setUrlRequestInterceptor
> [0x00007FFB73277D3D+246843782]
>   QWebEnginePage::setUrlRequestInterceptor [0x00007FFB64FEF25E+9305767]
>   TargetGetStockObject [0x00007FF6E9FA49A3+287028]
>   TargetGetStockObject [0x00007FF6EA726CE7+8160376]
>   TargetGetStockObject [0x00007FF6EA726AEE+8159871]
>   TargetGetStockObject [0x00007FF6EA71E492+8125475]
>   TargetGetStockObject [0x00007FF6EA71E33E+8125135]
>   TargetGetStockObject [0x00007FF6EA71E1FE+8124815]
>   TargetGetStockObject [0x00007FF6EA71E52E+8125631]
>   BaseThreadInitThunk [0x00007FFC305A7344+20]     RtlUserThreadStart
> [0x00007FFC31B226B1+33]
> [25992:22332:0514/155233.091:INFO:web_contents_delegate_qt.cpp(279)]
> ProcessGone: 3 (-2147483645)
> [25992:22332:0514/155233.091:INFO:web_contents_delegate_qt.cpp(279)]
> ProcessGone: 3 (-2147483645)

我感谢您提前提供的任何帮助。

html c++ pdf c++17 qt6
1个回答
0
投票

实际上,为什么要使用 QWebEngine 将 html 转换为 pdf。你不需要这个巨大的图书馆来做到这一点。

这里是代码示例的快速改编,无需使用 QWebEngine 即可将 html 内容打印到 pdf 文件。它在调试和发布中工作得很好。

主窗口.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void generatePdf( const QString& htmlFilePath );

private:
    QString createHtmlFile();
};

#endif // MAINWINDOW_H

主窗口.cpp:

#include "mainwindow.h"
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QTextDocument>
#include <QPrinter>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    auto htmlFile = createHtmlFile();
    if ( !htmlFile.isEmpty() )
        generatePdf( htmlFile ); // Create the HTML file and print pdf
}

MainWindow::~MainWindow()
{
    
}

QString MainWindow::createHtmlFile()
{
    QString htmlFilePath = QCoreApplication::applicationDirPath() + "/index.html"; //Returns the directory that contains the application executable
    QFile file(htmlFilePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file for writing: " << file.errorString();
        QMessageBox::warning(this, "File Error", "Failed to create HTML file: " + file.errorString());
        return "";
    }

    QTextStream out(&file);
    out << "<!DOCTYPE html>\n";
    out << "<html lang=\"en\">\n";
    out << "<head>\n";
    out << "<meta charset=\"UTF-8\">\n";
    out << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
    out << "<title>QWebEngine Example</title>\n";
    out << "</head>\n";
    out << "<body>\n";
    out << "<h1>Hello from QWebEngine!</h1>\n";
    out << "<p>This is a simple HTML page loaded using Qt's QWebEngine.</p>\n";
    out << "</body>\n";
    out << "</html>\n";
    file.close();
    qDebug() << "HTML file created successfully at: " << htmlFilePath;

    return htmlFilePath;
}

void MainWindow::generatePdf( const QString& htmlFilePath ) //Does not work
{
    QFile f(htmlFilePath);
    if (!f.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::warning(this, "File Error", "Cannot open html file");
        return;
    }

    QTextStream in(&f);
    QString htmlContent = in.readAll();

    QString pdfFilePath = QFileDialog::getSaveFileName(this, tr("Save PDF"),
                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
                                    tr("PDF Files (*.pdf)"));
    if (pdfFilePath.isEmpty())
    {
        QMessageBox::warning(this, "File Error", "Cannot create pdf file");
        return;
    }

    QTextDocument qtdoc;  // start with a QTextDocument
    
    qtdoc.setHtml(htmlContent);
    
    QPrinter printer( QPrinter::PrinterResolution );
    
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setPageOrientation(QPageLayout::Portrait);
    printer.setPageSize(QPageSize::A4);
    printer.setPageMargins(QMarginsF(15,15,15,15),QPageLayout::Millimeter);
    printer.setFullPage(true);
    printer.setOutputFileName(pdfFilePath);

    qtdoc.print(&printer);
}
© www.soinside.com 2019 - 2024. All rights reserved.