javascript 从字节数组输出 PHP 中的 PDF
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9707604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Output a PDF in PHP from a byte array
提问by mdance
I am getting a byte array from a WCF service that generated the PDF and converted it to a byte array. I need to able to get the byte array and using either PHP or Javascript (or jQuery) take that byte array and convert it back to a downloadable PDF. I would prefer a solution in Javascript, but PHP would work fine too.
我从生成 PDF 的 WCF 服务获取字节数组并将其转换为字节数组。我需要能够获取字节数组并使用 PHP 或 Javascript(或 jQuery)获取该字节数组并将其转换回可下载的 PDF。我更喜欢 Javascript 中的解决方案,但 PHP 也可以正常工作。
The code I'm using to get the PDF is:
我用来获取 PDF 的代码是:
<?php
$userPDF = $_POST['username'];
$passPDF = $_POST['password'];
$idPDF = 'MO-N007175A';
//PDF Function
$data = array("id" => $idPDF, "username" => $userPDF, "password" => $passPDF);
$data_string = json_encode($data);
$ch = curl_init('http://********.com/******/v1/DealPdf');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
var_dump($result);
?>
The var_dump($result);
is
的var_dump($result);
是
string(1053285) "[37,80,68,70,45,49,46,54,10,37,211,244,204,225,
...
string(1053285) "[37,80,68,70,45,49,46,54,10,37,211,244,204,225,
...
The array goes on for a while... so I only provided a small portion for example purposes.
阵列持续了一段时间......所以我只提供了一小部分用于示例目的。
Where do I start on getting a PDF out of this array?
我从哪里开始从这个数组中获取 PDF?
EDITTo clarify - The WCF Service IS returning an actual PDF, just in a byte array. I need to save this byte array as a PDF on the clients machine. I have used fwrite and so forth, but I must be missing something because I dont see it working.
编辑澄清 - WCF 服务正在返回一个实际的 PDF,只是在一个字节数组中。我需要将此字节数组保存为客户端计算机上的 PDF。我使用过 fwrite 等等,但我一定遗漏了一些东西,因为我看不到它的工作原理。
Also - If I do use fwrite, where does it output the file? EDIT
另外 - 如果我确实使用 fwrite,它在哪里输出文件? 编辑
回答by Grinn
I had to do the same thing. For me, I was generating the PDF server-side, but wanted to send it down with a bunch of other data to the client in an AJAX response. Here's the JavaScript that I ended up with. The Bloband saveAsmethods are rather new technologies, so you might want to (as I did) get the polyfills for each of them, linked to above.
我不得不做同样的事情。对我来说,我正在生成 PDF 服务器端,但想在 AJAX 响应中将它与一堆其他数据一起发送到客户端。这是我最终得到的 JavaScript。该斑点和的saveAs方法是相当新的技术,所以你可能想(像我一样)得到polyfills为他们每个人,挂上面。
// Convert the Base64 string back to text.
var byteString = atob(data.reportBase64Bytes);
// Convert that text into a byte array.
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// Blob for saving.
var blob = new Blob([ia], { type: "application/pdf" });
// Tell the browser to save as report.pdf.
saveAs(blob, "report.pdf");
// Alternatively, you could redirect to the blob to open it in the browser.
//document.location.href = window.URL.createObjectURL(blob);
回答by scottheckel
At first, I thought this would be a great use of the JavaScript library PDF.js, but then I realized that you wanted to download the file. The best place to do this would be in PHPsetting all of the appropriate headers along the way.
起初,我认为这将是 JavaScript 库PDF.js 的一个很好的用途,但后来我意识到您想要下载该文件。在做到这一点最好的地方是在PHP中设置沿途所有适当的头。
However, there may be something that will work for you, but I have never tried it with PDFs. I have seen image saves done well with data url's in some browsers. A great example of this is Canvas2Image. The code would look something liket he following:
但是,可能有些东西对您有用,但我从未尝试过使用 PDF。我已经看到在某些浏览器中使用数据 url 可以很好地保存图像。一个很好的例子是Canvas2Image。代码看起来像下面这样:
document.location.href = "data:application/pdf;base64," + base64PDFdata;
Where base64PDFdata
would be your byte array converted to base 64 string representation. No guarantees on this working, but it may be worth a shot.
base64PDFdata
您的字节数组将在哪里转换为 base 64 字符串表示形式。不能保证这项工作,但它可能值得一试。
回答by Ben
As mention in my comment to your question, it looks like you're getting a string representation of an array of decimal representations of bytes. e.g. "[37,80,68,70]"
正如我在对您的问题的评论中所提到的,您似乎正在获得字节的十进制表示数组的字符串表示形式。例如"[37,80,68,70]"
You likely need to transform that.
你可能需要改变它。
Can be done like this:
可以这样做:
// with:
$data = "[50,20,36,34,65]";
// remove brackets
$data = trim($data,'[]');
// split into array on ',' character
$data = explode(',',$data);
// transform each decimal value to a byte representation. chr does just that
$data = array_map('chr',$data);
// turn the resulting array back into a string
$data = implode('',$data);
The comments about setting the headers to force download are also relevant so you should use that too.
有关设置标题以强制下载的注释也很重要,因此您也应该使用它。
Here's the final code:
这是最终的代码:
<?php
// This is good to keep
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="output.pdf"');
$userPDF = $_POST['username'];
$passPDF = $_POST['password'];
$idPDF = 'MO-N007175A';
//PDF Function
$result = array("id" => $idPDF, "username" => $userPDF, "password" => $passPDF);
$result_string = json_encode($result);
$ch = curl_init('http://********.com/******/v1/DealPdf');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $result_string);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
// remove brackets
$result = trim($result,'[]');
// split into array on ',' character
$result = explode(',',$result);
// transform each decimal value to a byte representation. chr does just that
$result = array_map('chr',$result);
// turn the resulting array back into a string
$result = implode('',$result);
echo $result;
?>
Note that echo is used here, var_dump is not good as it adds extra formatting to the output.
请注意,这里使用了 echo,var_dump 不好,因为它为输出添加了额外的格式。
Also, note, you're not doing any testing on the result of the curl, if it fails you should probably handle the output differently.
另外,请注意,您没有对 curl 的结果进行任何测试,如果它失败,您可能应该以不同的方式处理输出。
回答by daker
Ahh now I see what you want to do!
啊,现在我明白你想做什么了!
Try this:
试试这个:
<?php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
$userPDF = $_POST['username'];
$passPDF = $_POST['password'];
$idPDF = 'MO-N007175A';
//PDF Function
$data = array("id" => $idPDF, "username" => $userPDF, "password" => $passPDF);
$data_string = json_encode($data);
$ch = curl_init('http://localhost/test/file.pdf');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
var_dump($result);
?>
回答by daker
Set MIME header with header() to match a PDF and then print out byte array.
使用 header() 设置 MIME 标头以匹配 PDF,然后打印出字节数组。
Something like this: In PHP, output as byte array and stream. Which one is better?