关于javascript:PDF Blob-弹出窗口未显示内容

PDF Blob - Pop up window not showing content

最近几天,我一直在解决这个问题。 尝试在标记上显示流没有运气,我只是试图在新窗口上显示它。

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

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

码:

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


如果要根据响应数据创建blob,则需要将responseType设置为arraybuffer

1
2
3
4
5
6
$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


如果设置{ responseType: 'blob' },则无需自己创建blob。您可以简单地基于响应内容创建url:

1
2
3
4
5
6
7
8
$http({
    url:"...",
    method:"POST",
    responseType:"blob"
}).then(function(response) {
    var fileURL = URL.createObjectURL(response.data);
    window.open(fileURL);
});


我使用AngularJS v1.3.4

HTML:

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

JS控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'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服务:

1
2
3
4
5
6
7
8
9
10
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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;
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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;
};

经过数天的努力,终于为我解决了问题。我必须在新窗口中使window.print() for PDF需要工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 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的元素。但是您可以手动触发打印,这将起作用。


我最终使用以下代码下载了我的pdf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();

}