从字节数组中以PHP输出PDF

时间:2012-03-14 18:07:31

标签: php javascript jquery arrays curl

我从WCF服务获取一个字节数组,该服务生成PDF并将其转换为字节数组。我需要能够获取字节数组并使用PHP或Javascript(或jQuery)获取该字节数组并将其转换回可下载的PDF。我更喜欢Javascript中的解决方案,但PHP也可以正常工作。

我用来获取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);
?>

var_dump($result);

string(1053285) "[37,80,68,70,45,49,46,54,10,37,211,244,204,225, ...

阵列持续了一段时间......所以我只提供了一小部分用于示例目的。

我从哪里开始从这个数组中获取PDF?

修改 澄清 - WCF服务IS返回一个实际的PDF,只是一个字节数组。我需要在客户端计算机上将此字节数组保存为PDF。我使用过fwrite等等,但我必须遗漏一些东西,因为我看不到它有效。

另外 - 如果我使用fwrite,它在哪里输出文件? 的修改

5 个答案:

答案 0 :(得分:14)

我必须做同样的事情。对我来说,我正在生成PDF服务器端,但是希望在AJAX响应中将一堆其他数据发送给客户端。这是我最终得到的JavaScript。 BlobsaveAs方法是相当新的技术,因此您可能希望(就像我一样)为每个方法获取polyfill,并将其链接到上面。

// 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);

答案 1 :(得分:2)

起初,我认为这将是JavaScript库PDF.js的一个很好的用途,但后来我意识到你想下载该文件。 最好的地方是在PHP 中设置所有相应的标题。

然而,可能会有适合您的内容,但我从未尝试过使用PDF 。我已经看到在某些浏览器中使用数据URL很好地完成了图像保存。一个很好的例子是Canvas2Image。代码看起来像他所说的那样:

document.location.href = "data:application/pdf;base64," + base64PDFdata;

base64PDFdata将您的字节数组转换为基本64字符串表示形式。 无法保证此工作,但可能值得一试。

答案 2 :(得分:0)

使用header()设置MIME标头以匹配PDF,然后打印出字节数组。

这样的事情: In PHP, output as byte array and stream. Which one is better?

答案 3 :(得分:0)

啊,现在我明白了你想做什么!

试试这个:

<?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);
?>

答案 4 :(得分:0)

在我对你的问题的评论中提到,看起来你正在获得一个字节十进制表示数组的字符串表示。例如"[37,80,68,70]"

您可能需要改变它。

可以这样做:

// 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);

关于将标题设置为强制下载的注释也是相关的,因此您也应该使用它。

这是最终的代码:

<?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;
?>

请注意,此处使用了echo,var_dump不好,因为它为输出添加了额外的格式。

另外,请注意,您没有对卷曲的结果进行任何测试,如果失败,您应该以不同的方式处理输出。