通过使用ajax调用显示包含返回数据的pdf-不是iframe-JQuery

时间:2018-11-20 13:31:15

标签: javascript jquery ajax

This这个问题不能回答我的问题,因为它没有提供解决方案,我想知道现在(到2018年)我们是否有更好的方法。

所以问题是我想调用我的服务器,该服务器正在创建pdf文件(不是物理方式)并将文件内容作为流提供给http response。现在,通过对该Web服务的ajax调用,我想尽可能将返回的数据显示为pdf文件。

function callProducePdf(webServiceUrl, resultAreaId){
        var jqxhr = $.ajax({
            type:"GET",
            url: webServiceUrl
        });

        jqxhr.done(function(data){
            //data contains the pdf in inputStream form
            //how can I display the pdf in resultAreaId which is a div?             

            //if I do something like this it works but this is not what I want
            var iframe = $('<iframe height="500px">');
            iframe.attr('src', webServiceUrl);
            resultAreaId.prepend(iframe, "<br>");
        });

        jqxhr.fail(function(){
            //I have this function defined which is working fine
            appendError(resultAreaId);
        });
    }

服务器端代码:

@GetMapping("/producePdfWithDefault")
public ModelAndView producePdfWithDefault(HttpServletRequest request, HttpServletResponse response) {
    Resource resource = new ClassPathResource("/path/a/static/pdf/file.pdf");       
    InputStream resourceAsStream;
    try {
        resourceAsStream = resource.getInputStream();
        byte[] resourceInBytes = Base64.encodeBase64(IOUtils.toByteArray(resourceAsStream));
        response.reset();
        response.setContentType("application/pdf");
        response.setHeader("content-disposition","inline; filename=documentPreview.pdf");
        response.setContentLength(resourceInBytes.length); 
        OutputStream output = response.getOutputStream();
        output.write(resourceInBytes);
        output.flush();
        output.close();
    } catch (IOException e) {
            response.setStatus(500);
    }
    return null;
}

非常感谢您的帮助。谢谢你。

2 个答案:

答案 0 :(得分:1)

我会做这样的事情...

...
jqxhr.done(function(data) {
  var blob = new Blob([data]);
  var link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = "<ANY_FILENAME_WITH_EXTENSION>";
  link.click();
}),
...

(未经测试)

客户端将下载文件并在默认的PDF阅读器中将其打开。

答案 1 :(得分:0)

您可以使用PDF.js将PDF呈现为canvas元素。

下面的演示摘自他们的examples

// atob() is used to convert base64 encoded PDF to binary-like data.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
// Base64_encoding_and_decoding.)
var pdfData = atob(
  'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
  'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
  'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
  'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
  'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
  'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
  'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
  'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
  'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
  'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
  'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
  'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
  'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');

// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];

// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

// Using DocumentInitParameters object to load binary data.
var loadingTask = pdfjsLib.getDocument({
  data: pdfData
});
loadingTask.promise.then(function(pdf) {
  console.log('PDF loaded');

  // Fetch the first page
  var pageNumber = 1;
  pdf.getPage(pageNumber).then(function(page) {
    console.log('Page loaded');

    var scale = 1.5;
    var viewport = page.getViewport(scale);

    // Prepare canvas using PDF page dimensions
    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    // Render PDF page into canvas context
    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    var renderTask = page.render(renderContext);
    renderTask.then(function() {
      console.log('Page rendered');
    });
  });
}, function(reason) {
  // PDF loading error
  console.error(reason);
});
<script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>

<h1>PDF.js 'Hello, base64!' example</h1>

<canvas id="the-canvas"></canvas>