使用自定义字体与wkhtmltopdf

40

我正在尝试在使用wkhtmltopdf生成的PDF中使用自定义字体。 我读到说你不能使用Google WebFonts,而且wkhtmltopdf使用TrueType .ttf文件。有人能确认一下吗? 所以我从Google WebFont下载了一个.ttf文件并放在我的服务器上,然后使用了字体样式:

    @font-face {
        font-family: Jolly;
        src: url('../fonts/JollyLodger-Regular.ttf') format('truetype');
    }

并且字体族:

    <style type = "text/css">
        p { font-family: 'Jolly', cursive; }
    </style>

现在应该使用Jolly Lodger字体呈现的文本根本没有出现,页面是空白的。

我做错了什么?

附注:我尝试使用不同的.ttf文件。


我测试过了,能够成功使用TTF字体,没有任何问题。你确定src URL是正确的吗?你确定TTF字体可用(你在自己的系统上试过了吗)?如果你在服务器上安装字体并通过常规CSS调用它,可能会更好运。 - Chords
http://g33kinfo.com/info/archives/1806 - Chords
1
当使用<link href='http://fonts.googleapis.com/css?family=Jolly+Lodger' rel='stylesheet' type='text/css'>与谷歌网络字体一起使用时,它可以正常工作。也许最终我的.ttf文件确实存在问题... - fkoessler
嗨Marronsuisse,你能再解释一下你用了什么吗?我遇到了同样的问题,但是它还是不起作用。 - Gustavo
12个回答

31

既然这是一个Google Web字体,你不需要在样式表中编写@font-face,只需在源代码中使用以下链接标签:

<link href='http://fonts.googleapis.com/css?family=Jolly+Lodger' rel='stylesheet' type='text/css'>

并且

 <style type = "text/css">
    p { font-family: 'Jolly Lodger', cursive; }
</style>

会起作用。

顺便提一下,在您的代码中,您将@font-face系列定义为font-family: Jolly;并将其用作p { font-family: 'Jolly Lodger', cursive; },这是错误的,因为它不匹配字体家族名称。


4
我故意不使用链接标签,因为我读到了 wkhtmltopdf 直接从 Google Web Fonts 检索字体时可能无法正常工作的信息。这就是为什么我要下载该字体并将其包含在我的项目中。但是,当我在 HTML 页面中使用该字体时,使用标签就可以正常工作。你说得对,我的代码有错误,我会进行编辑,但即使名称匹配,该字体仍然不会出现在 PDF 文件中。我尝试过 ttf 文件和 otf 文件。 - fkoessler
我使用了这个答案中的代码,并且它很好地工作了(使用wkhtmltoimage)。也许当前版本的wkhtmltox工具已经更新以支持此功能? - Lessan Vaezi
2
在 Linux 0.12.2.1 (或 MacOS) 上,对于 wkhtmltopdf 我无法使用。 - Wilfred Springer

22

我猜你是在使用IIS的网络封装器调用wkhtmltopdf。这就是为什么有些人说它对他们有效的原因。他们可能是从命令行调用wkhtmltopdf,这种情况下它可以解析CSS URL()中的相对链接,但如果你是从snappy或类似的地方调用它,你可以通过指定一个URL来绕过这个问题,比如说 URL('http://localhost/myfolder/fonts/JollyLodger-Regular.ttf')

在wkhtmltopdf 0.11.0_rc1中,无法正确解析CSS URL()标签中的相对链接,但某些早期版本可能可以正常工作。同样的问题也会发生在其他CSS URL()标签中,比如调用背景图像时,文件位置的解析被破坏了。有趣的是,在图像的情况下,如果使用<IMG SRC=>,0.11.0_rc1能够找到文件,即使提供了相对路径。问题似乎仅限于CSS内部的URL()标签。

编辑:我发现如果你在路径中使用所有正斜杠并使用file:///,那么它就可以工作了。换句话说URL('file:///D:/InetPub/wwwroot/myfolder/fonts/JollyLodger-Regular.ttf')应该可以工作。


2
谢谢。file:// URL 似乎是本地字体和字体面的事情。例如,在 Linux 上,可以使用 url(file:///my/dir/font.ttf)。我错误地尝试了 local(),但我认为那是用于引用没有路径(在安装的字体目录之外)的字体。 - Henrik N
在*nix上,使用0.12.*包装器解决相对链接仍然存在问题。 - Kristen Waite
使用 src: url(file://myFont.ttf); 对我正在使用的一种字体有效(注意有两个斜杠)。对于另一种字体,没有办法在本地包含它,所以我不得不保留对 googleFonts 的引用 @import url('https://fonts.googleapis.com/css?family=myFont&display=swap'); 否则 wkhtmltopdf 根本无法呈现内容。奇怪的是,它不会回退到其他定义的字体。 - nhaggen
我对这个主题有两个问题。 首先,我如何在 SSL 项目上应用这个解决方案。 然后,在 URL 调用之后可以添加格式吗? - LucasLaurens

18

如上所述Yardboy,我们发现在CSS中对TrueType字体进行base64编码效果很好。但我想分享一些额外的见解。

我们使用4种自定义字体,都有独特的名称'Light''Medium'等。

我使用openssl工具包进行base64编码,结果不错。但你也可以选择使用fontsquirrel。只需确保删除所有其他字体类型('woff''otf'..)。我们发现仅使用truetype神奇地起作用。

编码文件,裁剪输出并添加到剪贴板

openssl base64 -in bold.ttf | tr -d '\n' | pbcopy

在Windows系统中,您需要安装OpenSSL并将其添加到路径中,然后执行以下操作:

openssl base64 -in bold.ttf | tr -d '\n' | clip

或者简单地使用这类网站

将其添加到css字体src属性中。

   @font-face {
      font-family: 'Bold';
      font-style: normal;
      font-weight: normal;
      src: url(data:font/truetype;charset=utf-8;base64,BASE64...) format("truetype");
    }

渲染输出将取决于您的wkhtmltopdf版本和类型。因为我们的服务器运行Debian,我在OSX上开发,所以我在本地的虚拟机上进行了测试。


1
你的意思是这将在生成的PDF文档中嵌入字体吗? - LowLevel
你编码了整个URL(包括基本的http:// ...),还是只编码了字体的路径(/ fonts / ...)? - LucasLaurens
这个能帮到你吗?https://dev59.com/GZPfa4cB1Zd3GeqPFZo8#35120327 这不是一个URL,字符串本身就是以base64编码的字体文件。 - tgk
成功了!我建议使用 https://www.fontsquirrel.com/tools/webfont-generator 的“专家”选项,上传您的字体并将它们转换为Base64,正如 https://dev59.com/oWw15IYBdhLWcg3wSJk3#16204485 中所提到的。 - equivalent8

9
如果您有.ttf文件或.woff文件,则使用以下语法。
@font-face {
   font-family: 'Sample Name';
   src: url(/PathToFolderWhereContained/fontName.ttf) format('truetype');
   }

不要使用ttf,因为它不起作用,而是使用全名'truetype',如果你有.woff文件,则使用格式'woff'。对于我的情况,这个方法有效。
然而,最好的做法是使用链接到Google字体API,如果没有符合您的标准,则使用上述技术即可实现。

4

3
我会在这里添加我的答案,以防有人需要它。
我一直在使用基于wkhtmltopdf的Rotativa,最终我使用了以下内容:
@font-face {
    font-family: "testfont";
    src: url("/UI/Fonts/609beecf-8d23-4a8c-bbf5-d22ee8db2fc9.woff") format("woff"),
         url("/UI/Fonts/1cd9ef2f-b358-4d39-8628-6481d9e1c8ce.svg#1cd9ef2f-b358-4d39-8628-6481d9e1c8ce") format("svg");
}

看起来 Rotativa 正在选择 SVG 版本。如果我重新排序,它仍然可以工作,但如果我删除 SVG 版本,它就停止工作了。

也许值得一试。然而,我找不到任何关于为什么会这样的好文档。


1

我个人不得不在一个 div 上设置字体族(最初我想要一个 span

<style>
@font-face {
    font-family: 'CenturyGothic';
    src: url("fonts/century-gothic.ttf") format('truetype');
}

.title {
    font-family: 'CenturyGothic', sans-serif;
    font-size: 22pt;
}
</style>

...

<div class="title">This is Century Gothic</div>

1

在尝试了所有建议的解决方法(其中一些实际上起作用了),我发现有一种更简单的解决方案:

<style>
@import 'https://fonts.googleapis.com/css?family=Montserrat';
</style>

您可以使用@import符号来引入字体。

1
在我的wkhtmltopdf 0.12.3.2(带有补丁的qt) - win 8.1上无法工作。 - xtian
@xtian,我使用django-wkhtmltopdf==2.0.3时成功了。 - gdvalderrama
进一步调查发现,在我的测试中无法正常工作的是导入和使用具有不同字重的字体:无论CSS设置如何,文档中仅使用了一个字重。显然,这在v0.13 alpha中已经得到修复。 - xtian
@xtian 很高兴知道这一点,那么字体的重量不能被指定吗?您介意提供一下错误链接吗? - gdvalderrama
当我发现 alpha 版本正常工作时,我关闭了这个错误报告。我没有得到任何官方确认,但你可以进行我在报告中详细描述的测试,看看它是否影响到你:https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3151 - xtian

1

针对基于unix系统的选项

我是在服务器端生成这些pdf文件的。我发现以以上方式获取字体会使我的pdf文件变得非常大,例如24KB1MB之间的巨大差异。我在https://sanjay.cc/ubuntu-font-install上找到了很有帮助的信息。

基本上,wkhtmltopdf/usr/share/fonts/truetype中查找系统字体。因此,您只需要将所需字体添加到该文件夹并进行访问即可。然后,您可以引用该字体。例如,如果我想使用Calibri,则可以执行以下操作:

  1. 添加字体文件
cp -r calibri /usr/share/fonts/truetype/
  1. 缓存字体
fc-cache -f -v
  1. 使用字体
html {
    font-family: Calibri;
}

注意:为了获得最佳效果,请添加所有字体变体。

calibri
├── calibri-bold-italic.ttf
├── calibri-bold.ttf
├── calibri-italic.ttf
└── calibri-regular.ttf

0

使用@import而不是获取字体,您需要将.ttf文件添加到项目中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接