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); } ?>
/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
wkhtmltopdf安装包
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');