11

我使用wicked_pdf和 rails 3.2.11 和 ruby​​ 1.9.3 从 HTML 生成 PDF 并部署到 Heroku。

我的 pdf.css.scss.erb:

<% app_fullhost = Constants["app_fullhost"] %>

@font-face {
  font-family:'DosisMedium'; font-style:normal; font-weight:500;
  src: url(<%=app_fullhost%>/app/font/dosis/Dosis-Medium.ttf) format('woff');
}

*, body {
  font-family: "DosisLight", 'Times New Roman', 'Arial', sans-serif;
} 

确切的主机在哪里app_fullhost,在开发或生产中。

我的 pdf 布局包括:

%html{:lang => I18n.locale}
  %head
    %meta{:charset => "utf-8"}
    %title= content_for?(:title) ? yield(:title) : Settings.app_name
    = wicked_pdf_stylesheet_link_tag "pdf"

在 production.rb 我有

config.assets.precompile +=%w(pdf.css)

这在开发中没有问题,但在 Heroku 上,pdf 文件没有加载所需的字体。我还尝试了不同的解决方案,例如在 production.rb 中添加这些:

config.assets.paths << "#{Rails.root}/app/assets/fonts"
config.assets.precompile += %w(*.svg *.eot *.woff *.ttf) 
config.assets.precompile += %w(.svg .eot .woff .ttf) 

我也尝试改变(在 pdf.css.scss.erb 中):

@font-face {
  font-family:'Dosis'; font-style:normal; font-weight:500;
  src: url('Dosis-Medium.ttf') format('woff');
}

或者

@font-face {
  font-family:'Dosis'; font-style:normal; font-weight:500;
  src: url(<%= asset_path('Dosis-Medium.ttf')%>) format('woff');
}

Heroku 上的字体 inassets/fonts和 inpublic/app/font/dosis和 url 正确响应:

..//myapp/app/font/dosis/Dosis-Medium.ttf" and 
..//myapp/assets/Dosis-Medium.ttf 

如何让字体加载到 Heroku?

4

3 回答 3

9

wkhtmltopdf,底层程序wicked_pdf,在通过 CSS 加载字体时是出了名的时髦。在某些系统上,它使用绝对路径,有时它需要相对路径。即使您正确获取了路径,它也可能会因不准确的 CSS 减速等而被抛出。仅在 SO 上就有很多关于此的问题。

我发现的最好、最灵活和最便携的解决方案是对您尝试使用的字体进行 Base64 编码,并将其直接包含到 CSS 文件中:

@font-face {
    font-family: 'OpenSans';
    src: url(data:font/truetype;charset=utf-8;base64,AAEAAAATAQA...
}
于 2013-07-18T00:33:18.727 回答
3

我遇到了这个问题并遵循了 Arman H 概述的建议 - 我将字体转换为 base 64 并直接在 CSS/SCSS 文件中引用它。我遵循的其余步骤与原始问题中概述的步骤非常相似。

我在这里汇总了完整的描述(带有指向源代码的 github 链接):http: //apleroy.com/posts/custom-pdf-fonts-with-wicked_pdf-and-heroku

首先,我在字体目录中引用了字体。

<%# /fonts/custom_fonts.css.scss.erb %>
@font-face {
    font-family: "SourceSansPro-Light";
    src: url('<%= asset_path("SourceSansPro-Light.otf") %>');
}

然后,为了对字体进行 base 64 编码,我使用了这个网站(已经在上面的评论中提到):http ://www.opinionatedgeek.com/dotnet/tools/base64encode/ 。base-64 编码输出是一个随机字符串,由数百行字母数字字符组成。我将此输出复制到新的 pdf.css.scss 文件中:

<%# /stylesheets/pdf.css.scss %>
@font-face {
  font-family: 'Source Sans Pro Light';
  src: url(data:font/truetype;charset=utf-8;base64,T1RUTw-----THIS IS HUNDREDS OF LINES LONG -------sGAnBSvO7nBqXQ==)
}

在实际的 html 页面(转换为 PDF)中,我使用 wicked_pdf 样式表标签进行了引用 - 如原始问题中所述:

<%# views/pdf_pages/show.html.erb %>
<meta charset='utf-8' />
<%= wicked_pdf_stylesheet_link_tag "pdf" %>

最后,我预编译了 pdf 样式表,以便将其包含在资产管道中,以便在 Heroku 上部署:

#application.rb
config.assets.precompile += ['pdf.css']
于 2015-06-18T18:45:49.883 回答
1

让我看看我是否有这个权利:

服务器 1:构建 PDF,需要字体,然后从 URL 中提取它们这在 dev 本地工作,但在 heroku 上不工作。

日志中有什么东西吗?(你看到字体的 http 请求了吗?)

你说它没有加载正确的字体。它会爆炸,还是只是渲染好像它从未加载过字体(例如,字体获取上的 404)。

如果您不从heroku 中提取字体文件,这是否有效?(例如使用 aws 或来自另一个 URL 的其他字体作为测试)

您是否从当前正在运行的同一服务器进程中提取?您是否有多个 dyno 或多个 unicorn 进程可以处理当前进程(构建 pdf)和传入请求(提供字体文件)

我见过人们只运行一个测功机,但尝试运行两个 http 事件并遇到问题。如果您只有一个测功机(您没有另外提及),请添加另一个并查看会发生什么,或者添加另一个独角兽进程。

于 2013-05-08T20:22:21.007 回答