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

Downloading PDF from .NET controller in AngularJS

本文关键字:下载 PDF 控制器 NET AngularJS 中的      更新时间:2023-09-26

好的,我已经阅读了从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来自角度文件保护程序。

完成所有这些之后,新窗口将打开,但出现一个错误:无法加载PDF文档,如果您尝试在Adobe Acrobat中打开它,则会出现错误:Adobe Acrobat Reader DC无法打开"IDcard.pdf",因为它不是受支持的文件类型或因为文件已损坏(例如, 它是作为电子邮件附件发送的,未正确解码)。

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

谢谢!

我对.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'));