1.WKHTMLTOPDF
wkhtmltopdf重点说一下,算是我用得最好的解决方案,基本上可以原样输出html页面中的内容,包括:图片/代码高亮部分css/页头/页尾等。有php和命令行方式,个人两种方式都试用了一下,wiki.eoe.cn最后采用的思路是:
1) 先获取所有的远程html,然后生成wkhtmltopdf的shell脚本
2) 在php中执行此shell脚本文件批量生成pdf(当然是采用定时任务)
3) 前端页面中检查当前页面是否存在此pdf,如果存在则显示下载链接
先贴上wiki.eoe.cn的部分实现代码:
<?php
$domain = "http://wiki.eoe.cn";
$htmlUrl = $domain . "/show/html/slug/$slug";
$_binpath = '/usr/local/bin/';
$_binname = 'wkhtmltopdf';
$savePath = "/User/Xia/eoecn/pdf/";
if (!is_dir($savePath)) {
//需要自己编写mkdirs函数
@mkdirs($savePath);
}
//由于生成中文目录会乱码,这里过滤掉
if (preg_match("/[x7f-xff]/", $slug)) {
$filename = "wiki-slug-$id";
}else {
$filename = $slug;
}
$saveFile = $savePath . $filename . '.pdf';
//判断是否已经存在
if (file_exists($saveFile)) {
die($saveFile);
}
$header = $domain . "/pdf/header";
$command = $_binpath . $_binname
. ' -T 15mm --header-spacing 5 --header-html ' . $header
. ' --footer-right "[page]/[toPage]" ' . $htmlUrl . ' '
. $saveFile;
if ($exec) {
exec($command, $output, $var);
}
?>
shell终端命令使用方法,以wiki.eoe.cn为例:
/usr/local/bin/wkhtmltopdf -T 15mm --header-spacing 5 --header-html header.html --footer-right "[page]/[toPage]" --outline cover cover.html http://wiki.eoe.cn/show/html/id/23 eoe-wiki-slug-23.pdf
生成效果: http://a1.eoe.cn/pdf/eoe-wiki-slug-23.pdf
代码托管在:https://code.google.com/p/wkhtmltopdf/
在linux和mac os等其它平台安装文档:http://www.tecmint.com/install-wkhtmltopdf-html-page-to-pdf-converter-in-rhel-centos-fedora/
要想完好支持html中的url和其它,参考:http://www.cnblogs.com/timelyxyz/archive/2012/12/24/2831523.html
说明文档: http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html
php使用方法: http://mikehaertl.github.com/phpwkhtmltopdf/
例子:
<?php
require_once('WkHtmlToPdf.php');
$pdf = new WkHtmlToPdf;
// Add a HTML file, a HTML string or a page from a URL
$pdf->addPage('/home/eoe/page.html');
$pdf->addPage('<html>....</html>');
$pdf->addPage('http://google.com');
// Add a cover (same sources as above are possible)
$pdf->addCover('mycover.pdf');
// Add a Table of contents
$pdf->addToc();
// Save the PDF
$pdf->saveAs('/tmp/new.pdf');
// ... or send to client for inline display
$pdf->send();
// ... or send to client as file download
$pdf->send('test.pdf');