【问题标题】:How do I get WKHTMLTOPDF to execute via PHP?如何让 WKHTMLTOPDF 通过 PHP 执行?
【发布时间】:2011-04-14 13:14:54
【问题描述】:

这在某种程度上已经被问过,但没有解决方案或可接受的答案,我想尝试更全面地回答我的问题,所以:

我正在尝试通过 PHP 在共享服务器(在本例中为 MediaTemple (gs))上启动并运行 WKHTMLTOPDF。根据主机的说法,这没有理由不起作用,实际上它是通过 SSH 工作的。所以...

我尝试了各种各样的东西,最基本的什么都不做,只是默默地失败:

exec("/path/to/binary/wkhtmltopdf http://www.google.com pdf1.pdf");

- Source: Question on Stack Overflow

完整的 PHP 绑定以及以下内容给了我错误,尽管我用谷歌搜索过,但我无法弄清楚:

呼叫:

$html = file_get_contents("http://www.google.com");
$pdf = new WKPDF();
$pdf->set_html($html);
$pdf->render();
$pdf->output(WKPDF::$PDF_EMBEDDED,'sample.pdf');

- Source: WKHTMLTOPDF on Google Code

错误:

Fatal error: Uncaught exception 'Exception' with message 'WKPDF didn't return
any data. <pre>Loading pages (1/6) [> ] 0% [======> ] 10% terminate called
after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc </pre>'
in /path/to/wkhtmltopdf.php:206 Stack trace: #0 /path/to/index.php(8):
WKPDF->render() #1 {main} thrown in /path/to/wkhtmltopdf.php on line 206

一旦我得到了这个(下面是一个摘录,因为我现在无法复制它):

Qt Concurrent has caught an exception thrown from a worker thread. This is not
supported, exceptions thrown in worker threads must be caught before
control returns to Qt Concurrent.

我还尝试了其他一些选项,但结果相同;没有PDF。那么我现在该怎么办,我该如何找出问题所在?我的 PHP 水平处于基础水平,但我会尽力而为。

【问题讨论】:

  • 可以直接用终端创建pdf吗?
  • 其实我应该更新这个但是项目被搁置了。我已经完成了这项工作,但并不完全令人满意。首先,我必须将 all HTML 源文件和依赖项放在与可执行文件相同的目录中(根本没有子目录,即使对于图像也是如此)。其次,我将 CSS 和 JS 放入 HTML 标头中。最后我在 WKHTMLTOPDF 函数中放了一个memory_get_usage();,这显然会触发垃圾收集。前两点减少了错误的数量,第三点一起阻止了它们,现在它甚至可以完美地工作,即使 @font-face 被报告为损坏。
  • 我知道这是旧的,可​​能不再需要你了,但你是如何在 MediaTemple (gs) 上安装 wkhtmltopdf 的?您有使用最新版本安装的经验吗?
  • 我只是将它作为静态二进制文件运行——将 wkhtmltopdf 上传到服务器并通过上面的 exec 命令运行它。我仍在使用 wkhtmltopdf,包括最新版本,这些版本很好,但已经从 Media Temple 转移到实际安装了 wkhtmltopdf 的虚拟服务器设置。我发现这样更可靠。

标签: php wkhtmltopdf


【解决方案1】:

你也可以在这里试试我的项目。它为命令行实用程序提供了一个干净的 OO 界面:

https://github.com/mikehaertl/phpwkhtmltopdf

用法很简单:

<?php
use mikehaertl\wkhtmlto\Pdf; 

$pdf = new Pdf;

// Add a HTML file, a HTML string or a page from a URL
$pdf->addPage('/home/joe/page.html');
$pdf->addPage('<html>....</html>');
$pdf->addPage('http://google.com');

// Add a cover (same sources as above are possible)
$pdf->addCover('mycover.html');

// Add a Table of contents
$pdf->addToc();

// Save the PDF
$pdf->saveAs('/tmp/new.pdf');

// ... or send to client for inline display
$pdf->send();

【讨论】:

  • 一个“真正的”教程可能会非常好,就像在 Windows 系统上安装一样,在没有 composer 的情况下安装(有些人不使用它),列出所有可用的选项......
  • 使用 mikehaertl\wkhtmlto\Pdf;我在哪里可以得到这些文件...请帮助我,我是 PDF 生成的新手@Core972
  • @Anudeep 请查看上面的 URL,您会在那里找到文档。更多问题请在 github 上打开一个问题。
  • 没有作曲家如何安装?我无权访问服务器!我尝试包含所有三个文件并“使用 mikehaertl\wkhtmlto\Pdf;”,但它返回一个错误:“找不到类 'mikehaertl\shellcommand\Command'”。你能帮帮我吗?
  • @RafaelMoni 您可以从安装了composer 的盒子中复制它:将包安装到某个临时位置,然后将vendor/ 目录复制到您的项目中。
【解决方案2】:

查看snappy,这是一个 PHP5 库,允许从 url 或 html 页面生成缩略图、快照或 PDF。它是 wkhtmltopdf/wkhtmltoimage 的包装器。

【讨论】:

    【解决方案3】:

    您可能想要设置正确的标题并将其设置为 application/pdf 以及将其设置为内联,以便人们可以在他们的浏览器中看到它(几乎每个最近的浏览器都支持这一点)并在需要时保存它。这是我正在使用的代码:

    exec("/usr/local/bin/wkhtmltopdf ../uploads/test.pdf");
    $file = "../uploads/test.pdf";
    $pdf = file_get_contents("../uploads/test.pdf");
    
    header('Content-Type: application/pdf');
    header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
    header('Pragma: public');
    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
    header('Content-Length: '.strlen($pdf));
    header('Content-Disposition: inline; filename="'.basename($file).'";');
    ob_clean(); 
    flush(); 
    echo $pdf;
    ?>
    

    【讨论】:

    • 谢谢,看我上面的评论。
    【解决方案4】:

    对于 Linux:

    exec('wkhtmltopdf http://somesite.com /home/user/file.pdf 2>&1');
    

    对于 Windows:

    <?php
    exec('C://abc//wkhtmltopdf http://google.html form1.pdf');
    
    echo "PDF Created Successfully";
    ?>
    

    【讨论】:

    • abc 是包含 wkhtmltopdf 的文件夹名称
    【解决方案5】:

    要从 php(在 linux 上)创建 pdf,您必须使用包装器。

    $cmd = '/usr/bin/xvfb-run --server-args="-screen 0, 1920x1080x24" /usr/bin/wkhtmltopdf http://google.com /tmp/google.pdf';
    
    exec($cmd);
    

    【讨论】:

    • 原因是wkhtmltopdf 需要X 服务器支持字体和图像,而xvfb-run 可以提供这种支持。
    • 这很棒 - 我认为这是唯一真正回答问题的回应。大量的工作和建议的替代方法,但你的解决了真正的问题。
    • 在我将撇号添加到 url 和目标文件的路径后工作
    【解决方案6】:

    当你运行时会发生什么:

    $out = array();
    exec("/path/to/binary/wkhtmltopdf http://www.google.com pdf1.pdf", $out);
    print_r($out);
    

    我的猜测是,由于您没有为文件指定任何文件夹,它会尝试将其写入当前工作目录。可能(很可能就是这种情况)网络用户对该文件夹没有写权限。因此,您应该能够通过提供网络用户可写的文件夹的完整路径来解决此问题。

    即。

    exec("/path/to/binary/wkhtmltopdf http://www.google.com /path/to/pdf1.pdf");
    

    除此之外,我不太确定 wkhtmltopdf 是否可以无头工作,可能是它需要一个正在运行的 X 服务器(在不运行 X 的服务器上,您可以通过安装 Xvfb 并使用 xvfb-run 来解决这个问题 运行 wkhtmltopdf)。

    【讨论】:

    • 好吧,实际上我确实想到了这一点,并且我已经尝试了您在第二个示例中提到的内容,结果相同,但什么也没有。您的第一个 sn-p 返回 Array()。至于您的第二点,来自更改日志:“不再需要运行 XServer(但是必须安装 X11 客户端库)”。从我四处寻找这些东西似乎安装在我的服务器上。谢谢。
    • 另外也许值得一提的是,我可以获得帮助信息或版本信息,所以有些东西可以工作,例如。 $out = shell_exec("/path/to/wkhtmlto­pdf --version -"); echo($out); 工作正常。
    【解决方案7】:

    这对我来说是一种预先生成 PDF 报告然后使用唯一会话 ID 从(同一会话的)请求页面获取它的方法。

    $cmd = "/usr/local/bin/wkhtmltopdf 'http://127.0.0.1/myApp/pdfReport.php?key=something' tmp_reports/report_".$_POST['sessionid'].".pdf";
    exec($cmd);
    

    【讨论】:

      猜你喜欢
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 2017-03-05
      • 2012-10-03
      • 2012-02-28
      • 2011-09-10
      相关资源
      最近更新 更多