php将html转换为pdf并下载

时间:2018-07-16 08:55:54

标签: php wkhtmltopdf

请仔细阅读,我有一份工作,该工作是将html转换为pdf,然后让用户下载。我知道有很多选择可以这样做。但是最后我选择了wkhtmltopdf。要使用它,我需要使用php execute Linux命令。这是我在做什么:

  1. 首先,我使用redis队列接收转换作业。当用户单击下载按钮时,我将作业添加到队列中。还有另一个脚本从队列中读取并处理转换作业。

  2. 在请求文件中,我写了一些代码来确保转换操作完成后,我们会将文件发送给浏览器。

    if (file_exists($newFile)) {
        return $this->output($fileName, $output, $newFile);
    }
    
    self::addJob([
        'file' => $tmpFile,
        'type' => Ap_Service_Data_ProcessPdf::html_to_pdf
    ]);
    
    $try_times = 0;
    
    //waiting for convert, try 10 times 
    while (true) {
        if ($try_times >= 10) {
            break;
        }
        clearstatcache();
        if (is_file($newFile)) {
            sleep(1);
            return $this->output($fileName, $output, $newFile);
            break;
        }
        $try_times++;
        sleep(1);
    }
    -----------------------------------------------------------------
    // the output function is something like this:
    if (!file_exists($filePath)) {
        header('HTTP/1.1 404 NOT FOUND');
    } else {
        $file = fopen($filePath, "rb");
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length: " . filesize($filePath));
        Header("Content-Disposition: attachment; filename=" . $fileName);
        echo fread($file, filesize($filePath));
        fclose($file);
        exit ();
    }
    
  3. 在大多数情况下,这都很好。最大的问题是有时浏览器永远不会获取文件并失败(10秒超时)。似乎文件存在,但是php脚本无法检测到,所以它将尝试10次并等待10s,然后返回false。

我希望有人能理解我的意思,如果有更好的解决方案,请告诉我!

1 个答案:

答案 0 :(得分:1)

您可以将this project用作wkhtmltopdf的PHP包装器。为了执行相同类型的Job,我提供了一个单独的项目here。 要使用 toPDF ,您必须获取页面的HTML代码,并将其与POST请求一起发送给 toPDF

这里是您如何获取HTML的一瞥(首先,用<pdf>标记绑定html代码):

var x = document.querySelectorAll("pdf")[0].innerHTML;
var y = x.replace(/\n\s+|\n/g, "");
var styleSheetList = document.styleSheets;
var link = '';
for (var i = 0; i < styleSheetList.length; i++) {
    if (styleSheetList[i].href != null) {
    link += '<link rel="stylesheet" href="' + styleSheetList[i].href + '"/>';
    }
}
var html = '<html><head><title>' + type + '</title><base href="">' + link + '</head><body>' + y + '</body></html>';
var data = {
    html: html,
    number: sr,
    type: type,
};

//this path must be change to the host path
var path = 'api/generatePdf'; //path to your curl request to toPDF.
post(path, data, 'POST');

function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for (var key in params) {
        if (params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);
            form.appendChild(hiddenField);
        }
    }

    document.body.appendChild(form);
    form.submit();
}