请仔细阅读,我有一份工作,该工作是将html转换为pdf,然后让用户下载。我知道有很多选择可以这样做。但是最后我选择了wkhtmltopdf。要使用它,我需要使用php execute Linux命令。这是我在做什么:
首先,我使用redis队列接收转换作业。当用户单击下载按钮时,我将作业添加到队列中。还有另一个脚本从队列中读取并处理转换作业。
在请求文件中,我写了一些代码来确保转换操作完成后,我们会将文件发送给浏览器。
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 ();
}
在大多数情况下,这都很好。最大的问题是有时浏览器永远不会获取文件并失败(10秒超时)。似乎文件存在,但是php脚本无法检测到,所以它将尝试10次并等待10s,然后返回false。
我希望有人能理解我的意思,如果有更好的解决方案,请告诉我!
答案 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();
}