52

我见过多个与这个问题非常相似的问题,所以一开始我很犹豫是否要发布它。但是没有任何建议可以解决我的问题,而且我自己似乎无法弄清楚出了什么问题。

对于我为一位客户制作的项目,他们希望能够将客户的报价(使用在线表格生成)转换为 PDF。很简单。由于整个项目是在 PHP 中,我使用了以下简单的过程:

  1. 将报价另存为临时 HTML 文件
  2. 使用 WkHTMLtoPDF 将 HTML 文件转换为 PDF
  3. 输出此 PDF 文件
  4. 清理(​​删除临时文件)

这一直有效,直到他们更换服务器。新服务器有防火墙。

起初,PDF 转换步骤返回一个防火墙页面,说明服务器无法建立出站连接。为了解决这个问题,我直接提供了 HTML 文件而不是链接到它(/var/www/mysite/temp/18382.html 而不是 www.example.com/temp/18382.html)。这转换了 HTML,但防火墙阻止了 CSS 和图像的加载

我可以通过简单地将 CSS 直接嵌入网站而不是链接到它(使用<style>标签)来克服 CSS,但这不适用于图像

我首先尝试使用相对链接。我<img src="http://www.example.com/temp/image.jpg" />改为<img src="./image.jpg" />. 这没有用。

接下来我尝试<img src="file:///var/www/mysite/temp/image.jpg" />了,但这也不起作用

我四处阅读并查看了 WkHTMLtoPDF 手册,并尝试了几个不同的命令行参数,例如--enable-local-file-access, --enable /var/www/mysite/temp/--images但似乎没有任何解决方法

4

16 回答 16

47

在我的情况下 - wkhtmltopdf 版本 0.12.2.1(带有修补的 qt) - 使用绝对路径将基本标签添加到 head 部分,确保图像和 css 确实被加载。

<html>
<head>
...
<base href="http://www.example.com/">
<link href="/assets/css/style.css" rel="stylesheet">
...
</head>
于 2016-04-18T13:45:27.483 回答
30

如果您在 linux 上,请检查图像的所有权。对于 Windows,您可以在http://code.google.com/p/wkhtmltopdf/wiki/Usage上找到一些信息。

我尝试了不同类型的图像路径:

  1. <img src="file:///var/www/testpdf/flowers.jpg"><br>
  2. <img src="./flowers.jpg"><br>
  3. <img src="flowers.jpg"><br>
  4. <img src="/var/www/testpdf/flowers.jpg"><br>

所有图像都显示正确。我没有使用任何命令行参数(仅wkhtmltopdf /var/www/testpdf/makepdf.html makepdf.pdf

于 2013-05-20T13:30:44.463 回答
18

对于 Windows,您需要在标记中使用绝对文件系统路径。例如:

<link href='C:\Projects\Hello\Hello.Web\Content\custom\home.css' rel='stylesheet' type='text/css' />

!不是http://localhost/Hello.Web/Content/custom/home.css

于 2013-12-03T17:28:52.380 回答
17

为了嵌入它们,您可以插入 base64 编码的图像,例如:

<img src="data:image/png;base64,someBase64content"/>
于 2018-04-05T14:32:24.167 回答
9

当浏览器呈现您的 HTML 时,它会使用这样的相对路径(有时以 URL 开头):

<img src="/static/images/some_picture.png">
<img src="http://www.example.com/static/images/some_picture.png">

但是当 WkHTMLtoPDF 在您的服务器上运行时,它直接通过文件系统与您的本地文件交互,而不是通过 Web 服务器。因此,对于本地文件,与浏览器不同,WkHTMLtoPDF 需要实际的文件路径:

<img src="/var/www/myapplication/static/images/some_picture.png">

(这对我使用 Python Flask 有效)

于 2018-02-28T01:10:45.203 回答
5

在 Windows 上使用路径:(file:///C:/some/dir/some/file.img注意三重 /)

于 2014-10-14T16:18:22.800 回答
3

在从这里和网络上接受了每个人的善意帮助之后,我发现了一些对我有用的东西 - 在 asp.net (c#) 中编码。

我需要通过 url(不是文件路径)访问图像,因为仍然需要访问原始源 html。通过排查,我发现了这几点。

  1. 这些标志必须传递到命令行进程:“-q -n --disable-smart-shrinking --images --page-size A4”

  2. URL 仍然必须是绝对的。

  3. 图片必须是jpg!我最初试图做一个gif,但无济于事。

  4. 我发现添加“--enable-local-file-access”没有帮助,因为它需要在图像路径中使用 '\' 斜杠而不是 '/' 斜杠,如果您也希望使用源代码,这也无济于事html(在某些浏览器中)。此外,如果您需要访问本地文件系统,则需要提供绝对路径,因为它直接从根目录读取并从那里开始。

希望这对其他人有帮助。

干杯

-y

于 2014-05-19T00:49:51.167 回答
3

为我解决的问题是删除对我的 CSS 文件的引用。原来我设置img { max-height: 100%; }了一个空的 div,所以它被解释为 max-height: 0。

因此,请检查您的 CSS,那里可能存在问题。这有效:

<div><img src="image.png"/></div>

并在带有 image.png 的目录中运行命令行:

wkhtmltopdf example.html example.pdf

但这不会:

<div><img src="image.png" style = "max-height: 100%; "/></div>

因为图像被压缩到 0 高度。Firefox 似乎纠正了这一点,所以它并不明显。

于 2019-11-20T21:15:01.980 回答
3

我知道这是一个很老的话题,但我刚刚遇到了同样的问题,也许它会对某人有所帮助。
我尝试了不同的方法,例如 css 背景图像和使用字符串作为 base64 编码数据图像。有时它有帮助,有时没有——我找不到特别的规则。
原来升级库 wkhtmltopdf 解决了这个问题。我使用的是 0.12.0 版本并升级到 0.12.3

于 2016-02-18T12:57:32.010 回答
2

可能为时已晚:)

顺便说一句,只需将此配置添加到最后的选项中。

options = {'enable-local-file-access': None}
pdfkit.from_string(html, 'filename.pdf', options=options)
于 2021-08-17T06:35:50.617 回答
1

图片的 URL 必须是绝对的而不是相对的。在树枝模板中检查这个工作示例:

<img src="{{ absolute_url(asset('images/example.png')) }}"/>
于 2019-07-10T09:54:16.980 回答
1

确保你有最新版本的wkhtmltopdf补丁 qt。
您可以实现一个助手,flask jinja 使用它来区分模板是用于渲染还是仅生成 pdf,或者两者兼而有之。
假设这tmpl_bind是要在模板中绑定的数据对象,添加一个新键tmpl_bind["pdf"]设置它TrueFalse.
使用wkhtmltopdfor时pdfkit,添加enable-local-file-access到选项对象。
现在创建一个名为的辅助函数static_file

def static_file(filename, pdf=False):
    # wkhtmltopdf only read absolute path
    if pdf:
        basedir = os.path.abspath(app.root_path)
        return "".join([basedir, "/static/", filename])
    else:
        return url_for('static', filename = filename)  

正如我们所说,wkhtmltopdf对于某些操作系统,仅当您包含它们的绝对路径时才读取文件。请注意,您可以app.root_path根据您的应用程序结构从 中添加或删除部分,但这在大多数情况下都有效。

static_file在应用程序配置中,如果它在另一个文件中,则在导入函数后添加此行

app.jinja_env.globals['static'] = static_file

最后,在模板导入文件中,通过调用static_file辅助函数来导入图片

<link href="{{ static('css/style.css', pdf) }}" rel="stylesheet" />
<img src="{{ static('assets/images/logo.svg', pdf) }}" class="logo"> 
于 2020-12-17T10:30:13.387 回答
1

刚刚花了几天时间让 wkhtmltopdf 读取 Flask/ Blueprint /static file/ css,所以我想我会分享我学到的东西。Win 7,Flask 0.12 on Python 3.4.4,使用 Pycharm pro,最新的 pdfkit 和 wkhtmltopdf。

  1. 在此处下载 wkhtmltopdf

  2. 安装它 -mine 安装在:

    C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe

  3. 在您将 pdfkit 导入到您的烧瓶 routes.py 脚本后,立即插入以下行:

    path_wkthmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'

    config = pdfkit.configuration(wkhtmltopdf=path_wkthmltopdf)

(注意这里第一行的“r”!!)

  1. 当您在路由中使用 pdfkit 时,添加 ",configuration = config" 作为参数,例如:

    pdfkit.from_string(html_text, output_filename, configuration = config)

这告诉 pdfkit 在哪里寻找 wkhtmltopdf。是的,你需要这样做。

  1. 现在在您的烧瓶 BASE TEMPLATE 添加, _external = True到您的 css 路线,例如:

(这将使 wkhtmltopdf 不会抛出错误找不到 css)

  1. 现在(严重的引导模板 juju 警告):进入您的烧瓶 /external 库 /site-packages /flask_bootstrap /templates /base.html 模板并:

一个。修复 CSS 链接:

<link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet" media="screen">

添加“http:”所以它看起来像:

<link href="http:{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet" media="screen">

湾。修复 JS 链接:

添加“http:”,使 JS 链接看起来像:

<script src="http:{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>

<script src="http:{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>

和所有这一切

你的烧瓶 html 到 pdf 的转换

使用 pdfkit 和 wkhtmltopdf

应该运行没有错误。

注意:我从 PHP 转到了烧瓶,如果您是烧瓶爱好者,请在此处发布您的解决方案。flask 社区比 PHP 社区小得多,所以我们都必须参与进来。

于 2017-03-05T20:04:29.727 回答
1

这可能是由于 SE Linux 或防火墙规则阻止您上网并返回您自己的服务器。您可以更新您的主机文件,以将对您的域的调用指向您机器的家庭地址。

于 2018-01-24T00:02:10.630 回答
1
对我来说,问题是通过做两件事来解决的: 1:在你的 app/config/config.yml
- 在 knp_snappy 下
- 对于选项temporary_folder write ./
-即: temporary_folder:./
2:现在在你的html.twig页面中删除资产并写入:
来自:
<link rel="stylesheet" type="text/css" href="{{asset('css/default_template.css') }}">
至:
<link rel="stylesheet" type="text/css" href="css/default_template.css">

在那之后,它对我有用。

希望我帮助了某人。谢谢 !

于 2017-08-17T08:21:22.100 回答
1

要使用图像或样式生成 pdf,您需要提供服务器路径,如下所示:

<img src="https://upload.wikimedia.org/wikipedia/...image.png" />

<link href="http://localhost:8080/css/file.css" media="all" rel="stylesheet" type="text/css" />

请注意第二个链接,它是样式表的本地地址,或者可能是第一个链接一样的远程地址。文件路径对我不起作用,只有资源的服务器路径。

Ps:在我的情况下,我在 Intellij IDE 中使用 spring boot,我需要使 IDE 的缓存无效并且不能在调试模式下运行才能工作,否则可能无法更新。

于 2019-04-08T20:23:29.293 回答