Search code examples
pythonpython-3.xpopupwkhtmltopdfpdfkit

How to stop wkhtmltopdf.exe popping up?


I created a GUI Program in python to create pdfs.I am using pdfkit library to create pdfs :

options = {
      'page-size': 'A4',
      'margin-top': '0.3in',
      'margin-bottom': '0.3in',
      'margin-left': '0.5in',  
      'margin-right': '0.4in',
      'quiet': '',
      'orientation' : 'Landscape'                   
      }
    toc = {
    'xsl-style-sheet': 'toc.xsl'
    } 

    path_wkhtmltopdf = r'wkhtmltopdf\bin\wkhtmltopdf.exe'
    config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf)
    pdfkit.from_string(htmlString, reportPath, configuration=config, toc=toc, options = options)

To make an executable of my GUI program, I used pyinstaller. When I use this .exe file , it pops-up a cmd window of wkhtmltopdf.exe during creation of pdf . How can I stop from popping up? After research on internet I did not find any solution.


Solution

  • Although not straight forward, but the popup window is from a command called by the module subprocess that is defaulted to creating a window when the executable from wkhtmltopdf is called.

    subprocess.CREATE_NEW_CONSOLE

    The new process has a new console, instead of inheriting its parent’s console (the default).
    

    Since there is no way to pass that argument through pdfkit, you can locate the module to make the change before building from pyinstaller. The method describes below works for me on Windows and Python 3.X.


    Locate and change the subprocess setting that creates the window

    import pdfkit
    
    pdfkit.pdfkit
    #THIS LOCATES THE FILE YOU NEED TO CHANGE
    
    Output:
    <module 'pdfkit.pdfkit' from '\\lib\\site-packages\\pdfkit\\pdfkit.py'>
    

    Edit the file from the link you have in the following part, the added paramters are with comments;

    def to_pdf(self, path=None):
    
            #CREATE AN ADDITIONAL PARAMTER
            CREATE_NO_WINDOW = 0x08000000
    
            args = self.command(path)
    
            result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
    
                                      #PASS YOUR PARAMETER HERE
                                      creationflags = CREATE_NO_WINDOW )
    

    And save the file, this passes the required parameter that suppresses the creation of a window.

    Once you are done with that, you should be able to rebuild your program.

    Example program

    Save the following code with a .pyw extension that basically means a no-console script from Python, for example html2pdf.pyw. Make sure you replace the paths with yours.

    import pdfkit
    
    path_wkhtmltopdf = 'your wkhtmltopdf.exe path'
    out_path = 'the output file goes here'
    
    
    config = pdfkit.configuration(wkhtmltopdf = path_wkhtmltopdf)
    pdfkit.from_url('http://google.com', 
                    out_path, 
                    configuration = config)
    

    Locate the html2pdf.pyw folder and build with pyinstaller: pyinstaller html2pdf.

    Finally test your program with the executable located in the same folder under dist\html2pdf\html2pdf.exe.