PDF Blob - 弹出窗口不显示内容

时间:2014-02-12 13:35:03

标签: javascript angularjs pdf

过去几天我一直在this problem工作。试图在<embed src>标签上显示流时没有运气,我只是想在新窗口上显示它。

新窗口仅显示PDF 控件 enter image description here

知道为什么pdf的内容没有显示?

CODE:

$http.post('/fetchBlobURL',{myParams}).success(function (data) {
    var file = new Blob([data], {type: 'application/pdf'});
    var fileURL = URL.createObjectURL(file);
    window.open(fileURL);
});

9 个答案:

答案 0 :(得分:89)

如果您想从回复数据中创建responseType,则需要将arraybuffer设置为blob

$http.post('/fetchBlobURL',{myParams}, {responseType: 'arraybuffer'})
   .success(function (data) {
       var file = new Blob([data], {type: 'application/pdf'});
       var fileURL = URL.createObjectURL(file);
       window.open(fileURL);
});

更多信息:Sending_and_Receiving_Binary_Data

答案 1 :(得分:15)

如果设置{ responseType: 'blob' },则无需自行创建Blob。您只需根据回复内容创建网址:

$http({
    url: "...",
    method: "POST",
    responseType: "blob"
}).then(function(response) {
    var fileURL = URL.createObjectURL(response.data);
    window.open(fileURL);
});

答案 2 :(得分:8)

我使用AngularJS v1.3.4

<强> HTML:

<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>

JS控制器:

'use strict';
angular.module('xxxxxxxxApp')
    .controller('MathController', function ($scope, MathServicePDF) {
        $scope.downloadPdf = function () {
            var fileName = "test.pdf";
            var a = document.createElement("a");
            document.body.appendChild(a);
            MathServicePDF.downloadPdf().then(function (result) {
                var file = new Blob([result.data], {type: 'application/pdf'});
                var fileURL = window.URL.createObjectURL(file);
                a.href = fileURL;
                a.download = fileName;
                a.click();
            });
        };
});

JS服务:

angular.module('xxxxxxxxApp')
    .factory('MathServicePDF', function ($http) {
        return {
            downloadPdf: function () {
            return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) {
                return response;
            });
        }
    };
});

Java REST Web服务 - Spring MVC:

@RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf")
    public ResponseEntity<byte[]> getPDF() {
        FileInputStream fileStream;
        try {
            fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf"));
            byte[] contents = IOUtils.toByteArray(fileStream);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/pdf"));
            String filename = "test.pdf";
            headers.setContentDispositionFormData(filename, filename);
            ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
            return response;
        } catch (FileNotFoundException e) {
           System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
        }
        return null;
    }

答案 3 :(得分:2)

// I used this code with the fpdf library.
// Este código lo usé con la libreria fpdf.

var datas = json1;
var xhr = new XMLHttpRequest();
xhr.open("POST", "carpeta/archivo.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.responseType = "blob";
xhr.onload = function () {
    if (this.status === 200) {
        var blob = new Blob([xhr.response], {type: 'application/pdf'});
        const url = window.URL.createObjectURL(blob);
        window.open(url,"_blank");
        setTimeout(function () {
            // For Firefox it is necessary to delay revoking the ObjectURL
            window.URL.revokeObjectURL(datas)
                , 100
        })
    }
};
xhr.send("men="+datas);

答案 4 :(得分:1)

我知道这很旧,但既然这为我指明了正确的方向,我想我会分享我正在做的事情,以防其他人来到这里。顺便说一句,我没有使用 Angular。

用户可以查看或下载文件。选择是通过 2 个按钮或 2 个链接给出的

gsonBuilder.excludeFieldsWithoutExposeAnnotation()

我将 jQuery 与 xhr2 的本机插件一起使用。这处理链接/按钮

<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="Download File" data-formid="{{ @your-id }}" data-forcedownload="1">
    <i class="fas fa-file-download"></i>
</button>

<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="View File" data-formid="{{ @your-id }}" data-forcedownload="0">
    <i class="fas fa-search"></i>
</button>

然后,为模态添加一些 javascript

$('.download-form').click(function(event) {
    event.preventDefault();
    let fid = $(this).data('formid');
    let force_download = $(this).data('forcedownload');
    $.ajax({
          url: '/download',
          dataType: 'native',
          type: 'POST',
          xhrFields: {
              responseType: 'blob'
          },
          data: {
               //you can send any parameters via POST here
               personID: "{{ @personID }}",
               file_record_id: pfid,
               file_type: "contract_form",
               dept: "your-dept",
               file_category: "fcategory",
               force_download: force_download
           },
           success: function(blob, status, xhr){
                if (xhr.getResponseHeader('Custom-FileError')>1) {
                      alertify.error(xhr.getResponseHeader('Custom-ErrorMsg'));
                }else{
                      //I thought this would work when viewing the PDF but it does not.
                      blob.name = xhr.getResponseHeader('Custom-FileName');
                      var fileURL = URL.createObjectURL(blob);
                      if (xhr.getResponseHeader('Custom-ForceDownload')==1) {
                            window.open(fileURL);
                            var link=document.createElement('a');
                            link.href=window.URL.createObjectURL(blob);
                            link.download=xhr.getResponseHeader('Custom-FileName');
                            link.click();
                       }else{
                            file_modal(fileURL,'Any Title');
                       }
                       
                   }
              }
           })
});

在服务器端,您需要发送这样的自定义标头 [PHP]

function file_modal(blob,the_title)
{

    let spinner = "<div class='text-center'><i class='fa fa-spinner fa-spin fa-5x fa-fw'></i></div>";
    $("#modal_static_label").html('Loading');
    $("#modal_static .modal-body").html(spinner);
    if (blob.length > 1) {
        $("#modal_static").modal("show");
        $("#modal_static_label").html(the_title);
        $("#modal_static .modal-body").empty().append('<iframe src='+blob+' width="100%" height="500px" style="border:none;"></iframe>');
    }else{
         $("#modal_static .modal-body").empty().html('File error');
    }
    $("#modal_static .modal-footer").html('<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>');
        
}

如果用户点击“查看”,如果他们点击“下载”,模态将显示 PDF,下载窗口将显示您选择的文件名。我已经用小于 10mb 的 PDF 文件对此进行了测试,它按预期工作。

我希望有人觉得这很有用。

答案 5 :(得分:0)

我已经奋斗了几天,最后给出了对我有用的解决方案。我必须在新窗口中使window.print() for PDF需要工作。

 var xhr = new XMLHttpRequest();
      xhr.open('GET', pdfUrl, true);
      xhr.responseType = 'blob';

      xhr.onload = function(e) {
        if (this['status'] == 200) {          
          var blob = new Blob([this['response']], {type: 'application/pdf'});
          var url = URL.createObjectURL(blob);
          var printWindow = window.open(url, '', 'width=800,height=500');
          printWindow.print()
        }
      };

      xhr.send();

关于在新窗口中加载PDF和打印的一些注意事项。

  • 可以通过iframe在新窗口中加载pdf,但是如果url为外部url,则无法进行打印。
  • 必须允许浏览器弹出窗口,然后才可以使用。
  • 如果您尝试从外部网址加载iframe并尝试使用window.print(),则会得到空的打印内容或不包含iframe的元素。但是您可以手动触发打印,这将起作用。

答案 6 :(得分:0)

问题是,没有将其转换为正确的格式。使用功能“ printPreview(binaryPDFData)” 获取二进制pdf数据的打印预览对话框。 如果不想打开打印对话框,可以注释脚本部分。

printPreview = (data, type = 'application/pdf') => {
    let blob = null;
    blob = this.b64toBlob(data, type);
    const blobURL = URL.createObjectURL(blob);
    const theWindow = window.open(blobURL);
    const theDoc = theWindow.document;
    const theScript = document.createElement('script');
    function injectThis() {
        window.print();
    }
    theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
    theDoc.body.appendChild(theScript);
};

b64toBlob = (content, contentType) => {
    contentType = contentType || '';
    const sliceSize = 512;
     // method which converts base64 to binary
    const byteCharacters = window.atob(content); 

    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        const slice = byteCharacters.slice(offset, offset + sliceSize);
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }
    const blob = new Blob(byteArrays, {
        type: contentType
    }); // statement which creates the blob
    return blob;
};

答案 7 :(得分:0)

如果您的数据是字节数组,则不需要设置响应类型,请确保在将其传递给 blob 之前将其转换为 Uint8Array。

示例:

let byteArray = new Uint8Array(data)
let file = new Blob(
  [byteArray],
  {type: 'application/pdf'}
)

它对我有用。

如果您的数据不是 byteArray,请确保将其转换为 byteArray 并按照上述步骤使其工作。

//For example if your data is base-64 encoded string.
let byteChars = atob(data); //To decrypt data
let dataArray = = new Array(byteChars.length);
for(let i=0; i< byteChars.length; i++){
   dataArray[i] = byteChars.charCodeAt(i);
}
let byteArray = new Uint8Array(dataArray)
let file = new Blob(
  [byteArray],
  {type: 'application/pdf'}
)

答案 8 :(得分:-1)

我最终只是使用以下代码下载了pdf

function downloadPdfDocument(fileName){

var req = new XMLHttpRequest();
req.open("POST", "/pdf/" + fileName, true);
req.responseType = "blob";
fileName += "_" + new Date() + ".pdf";

req.onload = function (event) {

    var blob = req.response;

    //for IE
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {

        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = fileName;
        link.click();
    }
};

req.send();

}