phantomjs 根据其调用方式不一致
phantomjs is inconsistent based on how it's called
我在使用 PhantomJs 时遇到了奇怪且不一致的问题。从昨天开始我就被困在这个问题上了,我不能再想清楚了!
我搜索过,写过代码,但基本上暂时失败了...
一些上下文:
- 我正在开发的应用程序(Laravel 4)需要生成 PDF 报告。这些报告正在使用 phantomJS 进行转换。到目前为止,一切都按预期工作。
- 我被要求为此应用程序添加新的语言支持:简体中文。在浏览器上一切正常。
- 但是PhantomJS无法生成中文支持的PDF
如何生成报告:
- PDF 生成由 (Laravel) 控制器方法触发。
- 一个完整的 (Laravel) 视图被保存为临时 HTML 文件(即在这种情况下,PhantomJs 基本上将以 PDF 格式打印本地文件)。
- PHP 帮我生成 PhantomJS 命令行并执行它。
- (Laravel) 控制器响应获取 PDF 并将其下载。
问题出在哪里?
生成的报告中的文字是空白的,简体中文。但这只影响汉字,不影响数字。 Here is a PDF sample of what I'm trying to describe.
我可以验证其他可用语言(英语、法语、德语)的报告是否运行良好。
是什么造成了这种不一致?
在尝试调试时,我转储了 PHP 生成的命令行,并在我的 SSH 提示符下进行了尝试;它奏效了!所有字符均已打印,包括中文字符。
作为概念验证,我尝试通过 CLI "print in PDF" 外部页面,例如简体中文的随机维基百科页面,并且一切正常。
此外,在检查PDF文件时,我看到错误报告中嵌入的字体是服务器的默认字体(Nimbus Sans家族),不支持简体中文。
但是,在 "good" 报告中,使用的字体是支持简体中文的字体(SimSun,我在家里安装了它 - 例如 ~/.fonts/
- 并添加到 fontconfig
缓存fc-cache -vf
).
我试过的
- 在服务器上安装 CJK 字体(见上文)(SimSun、arphic-uming、Source Han Sans、...);
- 原始PHP代码使用了Symfony Process包,我也尝试用
exec
/shell_exec
; 编写10行代码
- 对本地字体文件使用
@font-face
(在 HTML 文件中,然后在外部 css 文件中)
- ...搜索 PhantomJS 问题跟踪器和邮件列表,google...
我可能遗漏了一些实验,请不要犹豫让我详细说明!我想没有开箱即用的解决方案,但我希望我至少能收集到一些关于这个问题的新想法。
编辑:命令行是什么样的:
如上所述,PHP 正在生成 PhantomJS 命令行并执行它;它总是使用绝对路径。当我从 SSH 提示测试 PDF 转换时,它总是基于 PHP 结果。
/home/lucio/my/app/path/Printer/PhantomJs/bin/phantomjs --ignore-ssl-errors=true --load-images=true --local-to-remote-url-access=true --web-security=false --ssl-protocol=tlsv1 --output-encoding=utf8 /home/lucio/my/app/path/Printer/PhantomJs/bin/generate-pdf.js /home/lucio/my/app/path/storage/tmp/1426973396.html /home/lucio/my/app/path/storage/tmp/1426973396.pdf
不一致表明这是一个路径问题。
如果安装了多个版本,请确保使用相同的 phantomjs 版本。您可以为此使用绝对路径或从命令行检查 which phantomjs
和 Laravel.
确保在两者中使用相同的路径。您可以在命令行中使用 echo $PATH
获取完整的 PATH。然后,您将复制此路径并将其添加到您在 Laravel 中的命令中:export PATH=<copied path>; phantomjs ...
.
所以,在尝试使用 phantomjs 和一些 CJK 字体后,我解决了我的问题。然而,这并不是一个完全的胜利,因为我完全不知道为什么这是固定的,首先是什么问题...
以下是似乎同时有助于解决此问题的列表:
- 我又给了
@font-face
一次机会。字体声明直接注入到视图中,在 <style></style>
内部,在外部样式表之后。
- 用
@font-face
导入的字体是Noto Sans CJK简体中文,OTF格式(亲切provided by google)。字体 未 安装在服务器端;它仅适用于其他资产。
<head>
部分中的 <base>
标记提供了所有资产调用的基础 URL。
- 不要删除静态 html 视图文件(没有明显的原因,我担心 html 视图文件加载和 PhantomJS 生成 PDF 之间的并发访问存在冲突... ).
例如
<!-- Directly after <head>: -->
<base href="https://lucio.domain.info">
<!-- other meta declarations & co -->
{{ HTML::style('/assets/css/reportcards/chinese.css') }}
<style>
@font-face {
font-family:"NotoSans";
src: url('/assets/fonts/Source_han_sans/NotoSansCJKsc-Regular.otf') format('opentype');
font-style: normal;
font-weight:300;
}
</style>
我在 Ubuntu 16.04 上遇到了类似的问题,我通过将 Noto 作为一个软件包安装解决了它
sudo apt-get install fonts-noto
我在使用 PhantomJs 时遇到了奇怪且不一致的问题。从昨天开始我就被困在这个问题上了,我不能再想清楚了! 我搜索过,写过代码,但基本上暂时失败了...
一些上下文:
- 我正在开发的应用程序(Laravel 4)需要生成 PDF 报告。这些报告正在使用 phantomJS 进行转换。到目前为止,一切都按预期工作。
- 我被要求为此应用程序添加新的语言支持:简体中文。在浏览器上一切正常。
- 但是PhantomJS无法生成中文支持的PDF
如何生成报告:
- PDF 生成由 (Laravel) 控制器方法触发。
- 一个完整的 (Laravel) 视图被保存为临时 HTML 文件(即在这种情况下,PhantomJs 基本上将以 PDF 格式打印本地文件)。
- PHP 帮我生成 PhantomJS 命令行并执行它。
- (Laravel) 控制器响应获取 PDF 并将其下载。
问题出在哪里?
生成的报告中的文字是空白的,简体中文。但这只影响汉字,不影响数字。 Here is a PDF sample of what I'm trying to describe.
我可以验证其他可用语言(英语、法语、德语)的报告是否运行良好。
是什么造成了这种不一致?
在尝试调试时,我转储了 PHP 生成的命令行,并在我的 SSH 提示符下进行了尝试;它奏效了!所有字符均已打印,包括中文字符。 作为概念验证,我尝试通过 CLI "print in PDF" 外部页面,例如简体中文的随机维基百科页面,并且一切正常。
此外,在检查PDF文件时,我看到错误报告中嵌入的字体是服务器的默认字体(Nimbus Sans家族),不支持简体中文。
但是,在 "good" 报告中,使用的字体是支持简体中文的字体(SimSun,我在家里安装了它 - 例如 ~/.fonts/
- 并添加到 fontconfig
缓存fc-cache -vf
).
我试过的
- 在服务器上安装 CJK 字体(见上文)(SimSun、arphic-uming、Source Han Sans、...);
- 原始PHP代码使用了Symfony Process包,我也尝试用
exec
/shell_exec
; 编写10行代码
- 对本地字体文件使用
@font-face
(在 HTML 文件中,然后在外部 css 文件中) - ...搜索 PhantomJS 问题跟踪器和邮件列表,google...
我可能遗漏了一些实验,请不要犹豫让我详细说明!我想没有开箱即用的解决方案,但我希望我至少能收集到一些关于这个问题的新想法。
编辑:命令行是什么样的:
如上所述,PHP 正在生成 PhantomJS 命令行并执行它;它总是使用绝对路径。当我从 SSH 提示测试 PDF 转换时,它总是基于 PHP 结果。
/home/lucio/my/app/path/Printer/PhantomJs/bin/phantomjs --ignore-ssl-errors=true --load-images=true --local-to-remote-url-access=true --web-security=false --ssl-protocol=tlsv1 --output-encoding=utf8 /home/lucio/my/app/path/Printer/PhantomJs/bin/generate-pdf.js /home/lucio/my/app/path/storage/tmp/1426973396.html /home/lucio/my/app/path/storage/tmp/1426973396.pdf
不一致表明这是一个路径问题。
如果安装了多个版本,请确保使用相同的 phantomjs 版本。您可以为此使用绝对路径或从命令行检查
which phantomjs
和 Laravel.确保在两者中使用相同的路径。您可以在命令行中使用
echo $PATH
获取完整的 PATH。然后,您将复制此路径并将其添加到您在 Laravel 中的命令中:export PATH=<copied path>; phantomjs ...
.
所以,在尝试使用 phantomjs 和一些 CJK 字体后,我解决了我的问题。然而,这并不是一个完全的胜利,因为我完全不知道为什么这是固定的,首先是什么问题...
以下是似乎同时有助于解决此问题的列表:
- 我又给了
@font-face
一次机会。字体声明直接注入到视图中,在<style></style>
内部,在外部样式表之后。 - 用
@font-face
导入的字体是Noto Sans CJK简体中文,OTF格式(亲切provided by google)。字体 未 安装在服务器端;它仅适用于其他资产。 <head>
部分中的<base>
标记提供了所有资产调用的基础 URL。- 不要删除静态 html 视图文件(没有明显的原因,我担心 html 视图文件加载和 PhantomJS 生成 PDF 之间的并发访问存在冲突... ).
例如
<!-- Directly after <head>: -->
<base href="https://lucio.domain.info">
<!-- other meta declarations & co -->
{{ HTML::style('/assets/css/reportcards/chinese.css') }}
<style>
@font-face {
font-family:"NotoSans";
src: url('/assets/fonts/Source_han_sans/NotoSansCJKsc-Regular.otf') format('opentype');
font-style: normal;
font-weight:300;
}
</style>
我在 Ubuntu 16.04 上遇到了类似的问题,我通过将 Noto 作为一个软件包安装解决了它
sudo apt-get install fonts-noto