Php 将 html 转换为 pdf 并下载
Php convert html to pdf and download
请仔细阅读,我有一份工作,工作是将 html 转换为 pdf,并让用户下载 it.I 知道最终有很多选择 this.But我选择了wkhtmltopdf。为了使用它,我需要使用php执行Linux command.Here是我做的:
首先,我使用一个redis队列来接收转换job.When用户点击下载按钮,我添加一个作业到queue.There是另一个读取的脚本队列并处理转换作业。
在请求文件中,我写了一些代码来确保转换操作完成后我们会将文件发送到浏览器。
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 ();
}
大多数时候,这个工作 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();
}
请仔细阅读,我有一份工作,工作是将 html 转换为 pdf,并让用户下载 it.I 知道最终有很多选择 this.But我选择了wkhtmltopdf。为了使用它,我需要使用php执行Linux command.Here是我做的:
首先,我使用一个redis队列来接收转换job.When用户点击下载按钮,我添加一个作业到queue.There是另一个读取的脚本队列并处理转换作业。
在请求文件中,我写了一些代码来确保转换操作完成后我们会将文件发送到浏览器。
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 (); }
大多数时候,这个工作 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();
}