It's mostly generic.
CMakeLists:
cmake_minimum_required(VERSION 3.5)
project(qpdWriterTest VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(qpdWriterTest
MANUAL_FINALIZATION
${PROJECT_SOURCES}
res.qrc
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET qpdWriterTest APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(qpdWriterTest SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(qpdWriterTest
${PROJECT_SOURCES}
)
endif()
endif()
target_link_libraries(qpdWriterTest PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.qpdWriterTest)
endif()
set_target_properties(qpdWriterTest PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS qpdWriterTest
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(qpdWriterTest)
endif()
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextDocument>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QTextDocument txt;
private slots:
void render();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFile>
#include <QPdfWriter>
#include <QPainter>
#include <QStandardPaths>
#include <QTextCursor>
#include <QTextTable>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QFile f(":/test.html");
f.open(QIODevice::ReadOnly);
txt.setHtml(f.readAll());
f.close();
connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::render);
txt.setPageSize(QPageSize(QPageSize::A4).sizePoints());
txt.setDocumentMargin(0);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::render() {
QString filePath = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
QPdfWriter pdfWriter(filePath+"/test.pdf");
QImage img(":/Logo.png");
txt.addResource(QTextDocument::ImageResource, QUrl("Logo.png"), img.scaled(QSize(286,56),Qt::KeepAspectRatio, Qt::SmoothTransformation));
QTextCursor crs(&txt);
crs.movePosition(QTextCursor::Start);
// Tabellenformat verwenden, um das Bild rechtsbündig zu platzieren
QTextTableFormat tableFormat;
tableFormat.setAlignment(Qt::AlignRight);
tableFormat.setBorder(0);
tableFormat.setWidth(QTextLength(QTextLength::PercentageLength, 100));
QTextCharFormat textformat;
textformat.setFontPointSize(16);
QTextTable *table = crs.insertTable(1, 2, tableFormat);
crs = table->cellAt(0, 0).firstCursorPosition(); // Erste Zelle der ersten Zeile auswählen
crs.insertText("Datenblatt xxx", textformat);
crs = table->cellAt(0, 1).firstCursorPosition(); // Zweite Zelle der ersten Zeile auswählen
QTextImageFormat imageFormat;
imageFormat.setName("Logo.jpg");
crs.insertImage(imageFormat);
pdfWriter.setPageSize(QPageSize(QPageSize::A4));
pdfWriter.setPageMargins(QMarginsF(10,10,10,10));
txt.setPageSize(QPageSize(QPageSize::A4).sizePoints());
txt.setDocumentMargin(0);
txt.print(&pdfWriter);
txt.print(&pdfWriter);
}
Mainwindow.ui consists of just a QPushButton named, surprise!, pushButton.
There is also, for convenience, resource file (as you'd probably gather from cmake conf) having a placeholder logo and your html.
res.qrc:
<RCC>
<qresource prefix="/">
<file>test.html</file>
<file>Logo.png</file>
</qresource>
</RCC>
Copy of your html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="RocketCake">
<title></title>
</head>
<body style="background-color:#FFFFFF; padding:0; margin: 0;">
<div style="text-align:left;">
<table id="table_798fb160" cellpadding="3" cellspacing="1" style="box-sizing: border-box; vertical-align: bottom; position:relative; display: inline-table; width:50%; height:30px; background:none; Border: none; table-layout: fixed; "> <tr>
<td width="100%" height="18px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_d0123cd">
<div style="text-align:left;">
<span style="font-size:12pt; font-family:Arial, Helvetica, sans-serif; color:#000000; "> </span>
</div>
</div>
</td>
</tr>
</table>
<table id="table_4bfff64d" cellpadding="3" cellspacing="1" style="box-sizing: border-box; vertical-align: bottom; position:relative; display: inline-table; width:100%; height:97px; background:none; border: 2px solid #000000; table-layout: fixed; "> <tr>
<td width="27%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_6a5612c4">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Projekt</span>
</div>
</div>
</td>
<td width="22%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_7a1f4a7c">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{projekt}</span>
</div>
</div>
</td>
<td width="24%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_365f079f">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Kundenposition</span>
</div>
</div>
</td>
<td width="25%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_798910f0">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{kundenposition}</span>
</div>
</div>
</td>
</tr>
<tr>
<td width="27%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_6fab104c">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Position / Revision</span>
</div>
</div>
</td>
<td width="22%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_3a151bc">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{position} / {revision}</span>
</div>
</div>
</td>
<td width="24%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_63851a2">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Aggregatnummer</span>
</div>
</div>
</td>
<td width="25%" height="15px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_30174d59">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{aggregatnummer}</span>
</div>
</div>
</td>
</tr>
<tr>
<td width="27%" height="16px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_382cbccc">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Datum</span>
</div>
</div>
</td>
<td width="22%" height="16px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_276db422">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{datum}</span>
</div>
</div>
</td>
<td width="24%" height="16px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_49ec4bae">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Artikelnummer</span>
</div>
</div>
</td>
<td width="25%" height="16px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_4c46cf44">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">{artikelnummer}</span>
</div>
</div>
</td>
</tr>
<tr>
<td width="27%" height="12px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_67c5a5c8">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; ">Bezeichnung</span>
</div>
</div>
</td>
<td width="22%" height="12px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_6530c995">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; "> </span>
</div>
</div>
</td>
<td width="24%" height="12px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_f645165">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; "> </span>
</div>
</div>
</td>
<td width="25%" height="12px" style="vertical-align: top; overflow:hidden; "> <div style="" id="cell_15ec8179">
<div style="text-align:left;">
<span style="font-size:8pt; font-family:Arial, Helvetica, sans-serif; color:#000000; "> </span>
</div>
</div>
</td>
</tr>
</table>