使用QPrinter和Jinja2生成包含图像的pdf

时间:2017-06-29 03:07:43

标签: python python-2.7 pyqt4 jinja2

我一直在尝试生成包含图片的PDF,但图片无法显示。我已按照此guide

指南下方有一条评论说我应该使用app.processEvents()来包含其他资源。

我还发现loadFinished.connect在我打印之前等待html加载,但我似乎无法使其正常工作。

这是我的代码:

class Window(QtGui.QMainWindow):
    ........
    btn1.clicked.connect(self.tohtml)
    def tohtml(self):
        # Random 2D list
        table = [[random.randint(0, 100) for j in range(10)] for i in range(10)]

        # Some Lorem Ipsum text
        paragraphs = [p[2] for p in generate_paragraphs(3)]

        self.html = render_template("test.html", table=table, paragraphs=paragraphs)
        self.topdf(self.html, "file.pdf")

    def topdf(self, html, destination):
        self.web = QWebView()
        self.web.setHtml(html)
        self.printer = QPrinter(QPrinterInfo.defaultPrinter(),QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.A4)
        self.printer.setOutputFormat(QPrinter.PdfFormat)
        self.printer.setOutputFileName(destination)  
        self.web.loadFinished.connect(self.print_pdf)

    def print_pdf (self):
        self.web.print_(self.printer)

这是我的测试html:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <style>
        .centered {
            text-align: center;
        }

        .underlined {
             text-decoration: underline;
        }

        .datatable {
            width: 100%;
            border-collapse: collapse;
        }

        .datatable td {
            margin: 0px;
            border: 1px solid #000;
            text-align: right;
    }
</style>

</head>
    <body>
         <img src="IDSLOGO.jpg"/>
    </body>
</html>

非常感谢任何帮助或指南。

1 个答案:

答案 0 :(得分:0)

首先在github adewes获得学分,这是他的代码毕竟

这就是我所理解的,至少解决了我的问题(借助code_byter

我的模板没有任何问题,原因是缺乏详细信息告诉QWebView我的图片在哪里添加

url = QUrl.fromLocalFile(media_path)然后

web.setHtml(html,baseUrl = url)

现在QWebview为我看到了图像,并准备与jinja2的html字符串一起渲染 最后app.processEvents()遍历事件(呈现和获取资源)等待QWebview或事件在继续之前完成,因为QWebView立即返回而不等待呈现的所有内容。

以下是代码:

jinja_env  = Environment(loader=FileSystemLoader("templates"))
def generate_pdf(template, filename, media_path=None, template_context=None):
    global app

    if template_context is None:
        template_context = {}                   #this is a dictionary
    template_context['media_path'] = media_path 
    #adds your os.path.abspath('your_absolute_dir_to_images') to the context dict, in the examples's case it's media

    template_path = '{0}.html'.format(template) #adds .html extension to a string ('your_template_name' + '.html')
    template = jinja_env.get_template(template_path) #gets and loads the template (your_template_name.html)
    html = template.render(**template_context)       #this executes the {{}} and {%%} inside your template
    app = QApplication.instance()
    if app is None:                                  #prevents a crash
        app = QApplication(['--platform','minimal'])
    web = QWebView()                                  #next step after setting up the jinja part is passing the generated html to WebView
    url = QUrl.fromLocalFile(media_path)              #this stores a command telling webview that this is the dir where the picture is or resources
    web.setHtml(html,baseUrl = url)                   #sets your template or html to be read and the resource location
    app.processEvents()                               #this loops through the events in QApplication and waits for webview to be finished rendering the html
    printer = QPrinter()                              #after webview renders the html this part will now execute. It's pretty straightforward
    printer.setPageSize(QPrinter.A4)
    printer.setOutputFormat(QPrinter.PdfFormat)
    printer.setOutputFileName(filename)
    web.print_(printer)                               #now prints a pdf with image yay

你可能不需要这里的一些代码将它集成到你自己的代码中,但我会使用它,因为你基本上可以复制并粘贴它,它可以工作(如果你有依赖关系)don&#39 ; t。如果您觉得有用,请忘记感谢adewes,如果我理解错误,请随时编辑。

编辑: 忘了提一下我的html标签看起来像<img src="{{media_path}}/my_pic.png" /> 它也可能看起来像<img src="file://{{media_path}}/my_pic.png" />,但后者对我不起作用。