How to convert a local html file to pdf using PyQt5?

Viewed 1706

I have tried using wkhtml and weasyprint libraries but all of these render a blank pdf page. The only option that worked was pdfcrowd but this is a paid library. I found several options using PyQt for converting a web-page:

import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets

app = QtWidgets.QApplication(sys.argv)
loader = QtWebEngineWidgets.QWebEngineView()
loader.setZoomFactor(1)
loader.page().pdfPrintingFinished.connect(
    lambda *args: print('finished:', args))
loader.load(QtCore.QUrl('https://en.wikipedia.org/wiki/Main_Page'))

def emit_pdf(finished):
    loader.show()
    loader.page().printToPdf("test.pdf")

loader.loadFinished.connect(emit_pdf)

app.exec()

However, I am not too sure how to adapt this to a locally saved html file.

1 Answers

You have to pass the file path as a url using QUrl.fromLocalFile(), also it is not necessary to create a QWebEngineView but just use QWebEnginePage:

import os
import sys

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets


def html_to_pdf(html, pdf):
    app = QtWidgets.QApplication(sys.argv)

    page = QtWebEngineWidgets.QWebEnginePage()

    def handle_print_finished(filename, status):
        print("finished", filename, status)
        QtWidgets.QApplication.quit()

    def handle_load_finished(status):
        if status:
            page.printToPdf(pdf)
        else:
            print("Failed")
            QtWidgets.QApplication.quit()

    page.pdfPrintingFinished.connect(handle_print_finished)
    page.loadFinished.connect(handle_load_finished)
    page.load(QtCore.QUrl.fromLocalFile(html))
    app.exec_()


if __name__ == "__main__":

    CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
    filename = os.path.join(CURRENT_DIR, "index.html")
    print(filename)

    html_to_pdf(filename, "test.pdf")
Related