从AngularJS中的.NET控制器下载PDF

时间:2016-03-04 19:27:57

标签: javascript c# .net angularjs pdf

好的,我已经阅读了有关从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默认在浏览器中打开和/或通过浏览器保存,以便他们知道发生了什么。

My 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文档,如果您尝试在Adobe Acrobat中打开它,则会显示错误消息:Adobe Acrobat Reader DC无法打开&#39; idcard.pdf&#39;因为它不是受支持的文件类型,或者因为文件已损坏(例如,它是作为电子邮件附件发送的,并且未正确解码)。

非常感谢任何帮助。我觉得我已经完成了许多其他SO问题中提出的所有问题,但也许我错过了一些我无法看到的东西。

谢谢!

1 个答案:

答案 0 :(得分:0)

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

我从另一个SO答案中获取了javascript代码来下载该文件,我无法将其链接起来,因为我不记得它在哪里。

我的网络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;


}

角度服务:

&#13;
&#13;
(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'));
&#13;
&#13;
&#13;