本文概述
- 要求
- 1)安装和配置SnappyBundle
- 2)例子
- 结论
服务器端生成图表的一种替代方法是使用Javascript(客户端)生成图表。有许多Javascript库可以创建精美的图表, 你可以检索其SVG(或base64图像)并将其返回到服务器, 以将它们作为图像包含在PDF中。听起来不错且功能强大, 但是此解决方案有一个缺点。 SVG会更改, 并会根据用户显示器的分辨率或浏览器窗口的尺寸, 在稍后的PDF中引起尺寸问题。
作为解决方案, 某些Web应用程序将生成一个html视图作为对浏览器的响应(它将呈现你的花式图表), 并且用户将需要使用(并知道如何)浏览器将内容保存(或打印)为PDF 。但是, 作为用户, 你可能只想单击一个按钮即可下载PDF, 选择保存位置, 仅此而已。你不认为对像TCPDF之类的库做一件容易的事吗?
到处都是问题, 但这正是wkhtmltopdf派上用场的地方, 因为你将能够以与在网站中一样的方式编写css, html和javascript(显然有一些最小的限制), 并且PDF看起来很棒。
在本文中, 你将学习如何在symfony 3项目中实现SnappyBundle, 以及如何生成不同方式的PDF。
要求 你需要wkhtmltopdf在系统中可用并且在命令提示符下可访问。 wkhtmltopdf是一个命令行工具, 可使用Qt WebKit渲染引擎将HTML渲染为PDF和各种图像格式。它们完全” 无头运行” , 不需要显示或显示服务。
- Windows:你可以在安装区域中下载每种体系结构(x86和x64)的安装程序。尽管稍后你可以在config.yml文件中更改wkhtmltopdf可执行文件的路径, 但是建议将wkhtmltopdf用作系统上的环境变量(如果你不想为wkhtmltopdf创建环境变量, 则可以提供可执行文件的完整路径)。你可以在本文中阅读如何在Windows中创建环境变量。
- Debian / Ubuntu:你可以使用以下命令直接在控制台中从wkhtmltopdf安装发行版:
$ sudo apt-get install wkhtmltopdf
在此处访问wkhtmltopdf的主页以获取更多信息。
1)安装和配置SnappyBundle Snappy本身就是wkhtmltopdf转换实用程序的PHP(5.3+)包装器。它允许你使用Webkit引擎从html文档生成pdf或图像文件。 KnpSnappyBundle为你的Symfony项目提供了简单的集成。
要在你的项目中安装SnappyBundle, 请执行以下composer命令:
composer require knplabs/knp-snappy-bundle
或手动添加将软件包名称添加到你的composer.json文件中, 然后执行composer install:
{
"require": {
"knplabs/knp-snappy-bundle": "~1.4"
}
}
下载完成后, 启用捆绑软件, 将以下行添加到你的内核中:
$bundles = [
//..//
new Knp\Bundle\SnappyBundle\KnpSnappyBundle(), ];
最后, 你只需要在config.yml文件中添加基本配置, 即可提供并启用wkhtmltopdf的二进制路径。
请注意, 如前所述, SnappyBundle需要wkhtmltopdf才能运行, 因此在使用config.yml的二进制选项之前, 我们需要提供wkhtmltopdf可执行文件的完整路径, 否则你将面临最常见的错误之一:
退出状态代码” 1″ 表示出了点问题:stderr:” ” stdout:” ”
Windows中的二进制路径
使用wkhtmltopdf的默认安装程序(和默认安装设置), 主分区的程序文件中应该有一个文件夹wkhtmltopdf / bin, 其中包含wkhtmltopdf的可执行文件, 因此你只需要提供以下示例的路径即可。
【如何在Symfony 3中使用SnappyBundle(wkhtmltopdf)从HTML创建PDF】但是, 如果你使用的是自定义安装, 则只需使用二进制属性中包含wkhtmltopdf可执行文件的新安装更改路径。
# Windows configuration
knp_snappy:
pdf:
enabled:true
# If you have wkhtmltopdf as an environment variable you don't need to provide the
# full path to the executable, use it in the same way as you use in the console
#binary:"wkhtmltopdf"
binary:"\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\""
options:[]
image:
enabled:true
binary:"\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltoimage.exe\""
options:[]
Linux / Unix中的二进制路径, 例如
如果使用apt-get方法安装了wkhtmltopdf, 则路径可能是:
# app/config/config.yml
knp_snappy:
pdf:
enabled:true
binary:/usr/local/bin/wkhtmltopdf
options:[]
image:
enabled:true
binary:/usr/local/bin/wkhtmltoimage
options:[]
如何更改PDF生成设置
你可以在config.yml文件中默认更改设置:
# config.yml
knp_snappy:
pdf:
enabled:true
binary:"wkhtmltopdf"
options:
no-outline: true
page-size: LETTER
# Recommended to set UTF-8 as default encoding :)
encoding: UTF-8
或者使用PHP和snappy的setOption方法在控制器(或服务等)中进行动态分析:
$snappy = $this->
get('knp_snappy.pdf');
$snappy->
setOption('no-outline', true);
$snappy->
setOption('page-size', 'LETTER');
$snappy->
setOption('encoding', 'UTF-8');
你可以在本文档中看到可用于wkhtmltopdf的所有选项的完整列表。
更改生成PDF的缓存路径
Snappy默认情况下使用sys_get_temp_dir()方法来获取系统的临时文件文件夹以保存PDF, 但是你可以使用secondary_folder属性更改要更改的路径:
# app/config/config.yml
knp_snappy:
temporary_folder: %kernel.cache_dir%/snappy
上一个示例将目标放在SF3项目的缓存文件夹中的文件夹(var / cache / snappy)。
2)例子 从Web网址渲染PDF
以下示例将以PDF格式显示我们的代码世界首页:
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$filename = 'myFirstSnappyPDF';
$url = 'http://ourcodeworld.com';
return new Response(
$snappy->
getOutput($url), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'inline;
filename="'.$filename.'.pdf"'
)
);
}
}
从项目URL渲染PDF(symfony路由)
在此示例中有2条路线:
sandbox_homepage:
path:/
defaults: { _controller: sandboxBundle:Default:index }sandbox_pdfexample:
path:/pdf-example
defaults: { _controller: sandboxBundle:Default:pdf }
和控制器:
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class DefaultController extends Controller
{
public function indexAction()
{
return $this->
render('sandboxBundle:Default:index.html.twig', []);
}/**
*Render in a PDF the sandbox_homepage URL
* @return Response
*/
public function pdfAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$filename = 'myFirstSnappyPDF';
// use absolute path !
$pageUrl = $this->
generateUrl('sandbox_homepage', array(), UrlGeneratorInterface::ABSOLUTE_URL);
return new Response(
$snappy->
getOutput($pageUrl), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'inline;
filename="'.$filename.'.pdf"'
)
);
}
}
注意:使用当前的Request对象自动检测生成绝对URL时使用的主机。从Web上下文外部(例如在控制台命令中)生成绝对URL时, 此操作无效。请参阅如何从控制台生成URL, 以了解如何解决此问题。
从twig视图的HTML渲染PDF
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$html = $this->
renderView('sandboxBundle:Default:template.html.twig', array(
//..Send some data to your view if you need to //
));
$filename = 'myFirstSnappyPDF';
return new Response(
$snappy->
getOutputFromHtml($html), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'inline;
filename="'.$filename.'.pdf"'
)
);
}
}
返回PDF响应以便在浏览器中查看
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$html = '<
h1>
Hello<
/h1>
';
$filename = 'myFirstSnappyPDF';
return new Response(
$snappy->
getOutputFromHtml($html), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'inline;
filename="'.$filename.'.pdf"'
)
);
}
}
以附件形式返回PDF响应(下载响应)
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$html = '<
h1>
Hello<
/h1>
';
$filename = 'myFirstSnappyPDF';
return new Response(
$snappy->
getOutputFromHtml($html), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'attachment;
filename="'.$filename.'.pdf"'
)
);
}
}
wkhtmltopdf主要功能(和优点)的基本示例
只需按照你在浏览器中的方式工作, wkhtmltopdf将负责将其转换为pdf。在此示例中, 我们将生成具有一些基本功能的PDF, 例如javascript, svg等的用法。
<
h1>
{{title}}<
/h1>
<
p>
This is my awesome first PDF generated using Snappy in my Symfony 3 project.<
/p>
<
p>
UTF-8 Test : κ?σμε<
/p>
<
p>
Image : <
/p>
<
br>
<
img height="200" src="http://ourcodeworld.com/resources/img/ocw-empty.png"/>
<
p>
SVG Example : <
/p>
<
br>
<
div>
<
!-- Do not forget to give width and height to your svg
use PLAIN SVG directly (<
svg>
content<
/svg>
)
Tiger SVG EXAMPLE : https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg
-->
<
/div>
<
p>
Canvas Example with Javascript: <
/p>
<
br>
<
div>
<
canvas id="myCanvas" width="300" height="200"/>
<
/div>
<
hr>
<
span id="dinamic-content">
<
/span>
<
script>
document.getElementById("dinamic-content").innerHTML = 'This string has been appended using javascript';
// Draw circle on canvas
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2*Math.PI);
ctx.stroke();
<
/script>
我们将使用一个简单的控制器将生成的PDF返回到浏览器:
<
?phpnamespace sandboxBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
$snappy = $this->
get('knp_snappy.pdf');
$html = $this->
renderView('sandboxBundle:Default:template.html.twig', array(
'title' =>
'Hello World !'
));
$filename = 'myFirstSnappyPDF';
return new Response(
$snappy->
getOutputFromHtml($html), 200, array(
'Content-Type'=>
'application/pdf', 'Content-Disposition'=>
'inline;
filename="'.$filename.'.pdf"'
)
);
}
}
PDF输出应如下所示:
文章图片
结论
- 你需要在计算机上安装wkhtmltopdf。 Snappy只是一个包装器, 使用几行PH??P即可使你轻松轻松地生成PDF。如果你不是安装设置的朋友, 则可以在项目中使用wkhtmltopdf作为作曲者依赖项的” 便携式” 版本。
- wkhtmltopdf允许你从Web url(或纯html)创建图像(屏幕快照), 并且SnappyBundle附带了包装器, 请在文档中详细了解此功能。
- 多亏了wkhtmltopdf, 你可以使用Javascript修改HTML内容以生成PDF, 这非常方便, 可以使用客户端代码(如Highcharts, D3.js等库)在PDF中显示图表或图形。
推荐阅读
- 无法添加窗口 - 令牌android.os.BinderProxy@42824无效;你的活动在运行吗()
- PHPMyAdmin MySQL错误(列”mycolumnname”不能为FULLTEXT索引的一部分)
- 如何自动在PHP中轻松生成带有logo的QR代码
- 使用Symfony 3中的套接字使用PHP创建不可知的实时聊天
- 如何在Windows中编辑和添加环境变量以方便命令行访问
- 如何在Symfony 3中创建和执行自定义控制台命令
- 如何使用C#Winforms和XAMPP连接到MySQL
- 在Symfony 3中使用FormType创建一个简单的联系表单
- 已解决–A project with an Output type of Class Library cannot be started directly