Php 将 html 转换为 pdf 并下载

Php convert html to pdf and download

请仔细阅读,我有一份工作,工作是将 html 转换为 pdf,并让用户下载 it.I 知道最终有很多选择 this.But我选择了wkhtmltopdf。为了使用它,我需要使用php执行Linux command.Here是我做的:

  1. 首先,我使用一个redis队列来接收转换job.When用户点击下载按钮,我添加一个作业到queue.There是另一个读取的脚本队列并处理转换作业。

  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. 大多数时候,这个工作 good.The 最大的问题是有时浏览器从未获取文件并且失败(10 秒超时)。看起来文件已经存在但是 php 脚本没有检测到它,所以它会尝试 10 次并等待 10 秒,然后 return false.

希望有人明白我说的,如果有更好的解决办法,请告诉我!

您可以使用 this project as a PHP wrapper for wkhtmltopdf. For doing the same type of Job, I made a separate project available here。 要使用 toPDF,您必须获取页面的 HTML 代码并将其与 POST 对 toPDF[=19= 的请求一起发送].

下面简要介绍了如何获得 HTML(首先,将 html 代码与 <pdf> 标记绑定):

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();
}