【问题标题】:Downloading PDF from .NET controller in AngularJS在 AngularJS 中从 .NET 控制器下载 PDF
【发布时间】:2016-06-18 16:29:33
【问题描述】:

好的,我已经阅读了有关从 Web 服务下载 PDF 的所有 Stack Overflow 问题。到目前为止,他们都没有帮助过我。我把它作为最后的努力来尝试得到一些答案。基本上,我正在向 API 发出 GET 请求,并且需要取回动态生成的 PDF。我们已经尝试通过接收byte[] 来执行此操作,现在我们正在返回包含内容的流。以下是我们在 Web 服务控制器中的内容:

var result = await resp.Content.ReadAsAsync<byte[]>();
var response = request.CreateResponse(HttpStatusCode.OK);
var dataStream = new MemoryStream(result);
response.Content = new StreamContent(dataStream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "idcard.pdf";

var fileStream = new FileStream(@"c:\temp\temp.pdf", FileMode.Create);
fileStream.Write(result, 0, result.Length);
fileStream.Close();

return response;

FileStream 部分是我们正在进行的一项测试,以查看将数据保存到临时文件是否有效以及是否可以保存 PDF。那部分确实有效。转到 c:\temp 并打开 idcard.pdf 文件效果很好。这样做的问题之一是它静默进行,用户不会知道它的存在。我们可以告诉他们,但我们真的更希望 PDF 在默认情况下在浏览器中打开和/或通过浏览器保存,以便他们知道发生了什么事。

我的 Angular 代码如下所示:

.factory('memberIdCard', ['$http', function($http) {

var get = function() {
    return $http({
        method: 'GET',
        url: '/Member/IdCard',
        headers: {
            accept: 'application/octet-stream'
        },
        responseType: 'arraybuffer',
        transformResponse: function(data) {
            var pdf;
            console.log('data: ', data);
            if (data) {
                pdf = new Blob([data], {
                    type: 'application/pdf'
                });
                console.log('pdf: ', pdf);
            }
            return pdf;
        }
    })
}

return {
    get: get
}
}]);

我已经用$http$resource 尝试过这部分,但都不起作用。现在,在我的控制器中:

$scope.printIdCard = function() {
memberIdCard.get().then(function(data) {
    var pdf = data.data;
    FileSaver.saveAs(pdf, 'idcard.pdf');

    var pdfUrl = window.URL.createObjectURL(pdf);

    $scope.pdfView = $sce.trustAsResourceUrl(pdfUrl);
    window.open($scope.pdfView);

});

请注意,FileSaver 来自 angular-file-saver

之后,新窗口打开,但出现错误提示:无法加载 PDF 文档,如果您尝试在 Adob​​e Acrobat 中打开它,则会出现错误提示:Adobe Acrobat Reader DC 无法打开' idcard.pdf',因为它不是受支持的文件类型或文件已损坏(例如,它是作为电子邮件附件发送的并且未正确解码)。

任何帮助将不胜感激。我觉得我已经完成了许多其他 SO 问题中建议的所有内容,但也许我错过了一些我无法看到的东西。

谢谢!

【问题讨论】:

    标签: javascript c# .net angularjs pdf


    【解决方案1】:

    我为 .xlsx 文件做了类似的事情,但概念是一样的。希望这可以帮助你,它对我有用。

    我得到了从另一个 SO 答案下载文件的 javascript 代码,我无法链接,因为我不记得它在哪里。

    我的 web api 控制器如下所示:

    [Route("all")]
    [HttpGet]
    public HttpResponseMessage GetAll(HttpRequestMessage request)
    {
    
    HttpResponseMessage response = null;
    
    MemoryStream stream = _exportService.CreateDataStream();
    
    response = request.CreateResponse(HttpStatusCode.OK);
    
    response.Content = new ByteArrayContent(stream.GetBuffer());
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    response.Content.Headers.Add("content-type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    
    return response;
    
    
    }
    

    还有角度服务:

    (function (app) {
    
      'use strict';
    
      app.factory('exportService', exportService);
    
      exportService.$inject = ['$q', '$http'];
    
      function exportService($q, $http) {
    
        var extension = '.xlsx';
    
        var service = {
            export: exportData
        };
    
        function exportData(event, fname){
    
            var config = {
                responseType: 'arraybuffer'
            }
    
            var path = 'api/export/'+event;
    
            var deferred = $q.defer();
    
            return $http.get(path, config).then(
                function(response) {
    
                    var data = response.data;
                    var status = response.status;
                    var headers = response.headers();
    
                    var octetStreamMime = 'application/octet-stream';
                    var success = false;
    
                    var filename = fname + extension;
    
                    var contentType = headers['content-type'] || octetStreamMime;
    
                    try
                    {
                        // Try using msSaveBlob if supported
                        var blob = new Blob([data], { type: contentType });
                        if(navigator.msSaveBlob)
                            navigator.msSaveBlob(blob, filename);
                        else {
                            // Try using other saveBlob implementations, if available
                            var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
                            if(saveBlob === undefined) throw "Not supported";
                            saveBlob(blob, filename);
                        }
                        success = true;
                        deferred.resolve();
                    } catch(ex)
                    {
                    }
    
                    if(!success)
                    {
                        // Get the blob url creator
                        var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
                        if(urlCreator)
                        {
                            // Try to use a download link
                            var link = document.createElement('a');
                            if('download' in link)
                            {
                                // Try to simulate a click
                                try
                                {
                                    // Prepare a blob URL
                                    var blob = new Blob([data], { type: contentType });
                                    var url = urlCreator.createObjectURL(blob);
                                    link.setAttribute('href', url);
    
                                    // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
                                    link.setAttribute("download", filename);
    
                                    // Simulate clicking the download link
                                    var event = document.createEvent('MouseEvents');
                                    event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
                                    link.dispatchEvent(event);
                                    success = true;
                                    deferred.resolve();
                                } catch(ex) {
                                }
                            }
    
                            if(!success)
                            {
                                // Fallback to window.location method
                                try
                                {
                                    var blob = new Blob([data], { type: octetStreamMime });
                                    var url = urlCreator.createObjectURL(blob);
                                    window.location = url;
                                    success = true;
                                    deferred.resolve();
                                } catch(ex) {
                                    deferred.reject();
                                }
                            }
    
                        }
                    }
                    return deferred.promise;
                },
                function(error) {
                    return $q.reject(error);
                });
        }
    
        return service;
      }
    
    })(angular.module('core.module'));

    【讨论】:

    • 感谢您的回复和与我们联系。我实现了所有这些,但结果仍然没有帮助我。我认为它基本上是在做 angular-file-saver 所做的,只是以不同的方式。我们这边一定有其他东西出了问题并使其无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    相关资源
    最近更新 更多