1

我们在 Angular4 中设计了一个页面,其中包含下载 PDF 文件功能。当用户单击下载时,我的应用程序会调用 Web API 并获取 PDF 文件数据。我为此使用了文件保护程序包。下面是它的代码片段。

Angular4代码:

    downloadPdf(url: string, body: any, basePage: BaseErrorPage, showSpinner: boolean = false, goBackToMaster: boolean = true) {
    if (showSpinner) {
        basePage.spinner.runningRefCountIncrement();
    }

    let headers = new Headers({ 
        'UserID': this.storage.UserID,
        'ADUserName': this.storage.ADUserName,
        'Content-Type': 'application/json', 
        'Accept': 'application/pdf'
    });        

    let options = new RequestOptions({ headers: headers });
    options.responseType = ResponseContentType.Blob;

    this.http.get(
        url).subscribe(
          (response) => {
            var mediaType = 'application/pdf';
            var blob = new Blob([response.blob], {type: mediaType});
            var filename = 'test.pdf';
            console.log(blob);
            console.log(response);
            saveAs(blob, filename);
          });
}

这就是我的 API 的样子:

    [Route("download/{invoiceID}")]
    [HttpGet]
    public HttpResponseMessage DownloadInvoice(int invoiceID)
    {
        var result = service.GetPDFByID(invoiceID);
        if (result == null)
        {
            HttpResponseMessage r4 = new HttpResponseMessage(HttpStatusCode.NotFound);
            return r4;
        }

        HttpResponseMessage r = new HttpResponseMessage(HttpStatusCode.OK);
        r.Content = new StreamContent(new MemoryStream(result.Data));
        r.Content.Headers.ContentType = new MediaTypeHeaderValue("application/blob");
        r.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        r.Content.Headers.ContentDisposition.FileName = result.FileName;

        return r;
    }

该代码在某种程度上似乎运行良好。当我单击下载时,API 调用被命中并收到响应。此外,还下载了一个文件。但是,当我尝试打开它时,它显示“加载 PDF 文档失败”。我想我在内容匹配中犯了一些错误并尝试了各种选项,但都没有成功。

有没有人对此有任何意见,请!

提前致谢。

4

1 回答 1

1

经过一番研究,我能够解决这个问题。上面的代码适用于 .Net Framework 4.6(或其他版本)。但是,就我而言,我正在研究 .Net core 2.0/web API2。HttpResponseMessage 在此处以 json 形式返回。我们需要编写一个自定义类以返回流对象。下面是新的代码,它有效。

希望这可以帮助某人。

API 控制器:

    [HttpGet]
    [ProducesResponseType(typeof(byte[]), 200)]
    public IActionResult Get()
    {
        byte[] buffer = new byte[16 * 1024];
        FileStream fs = new FileStream("C:\\Backup\\123.pdf", FileMode.Open);

        string fileName = "FileName.pdf";
        return new FileResultFromStream(fileName, fs, "application/pdf");            
    }

下面的自定义类:

   public class FileResultFromStream : ActionResult
   {
    public FileResultFromStream(string fileDownloadName, Stream fileStream, string contentType)
    {
        FileDownloadName = fileDownloadName;
        FileStream = fileStream;
        ContentType = contentType;
    }

    public string ContentType { get; private set; }
    public string FileDownloadName { get; private set; }
    public Stream FileStream { get; private set; }

    public async override Task ExecuteResultAsync(ActionContext context)
    {
        var response = context.HttpContext.Response;
        response.ContentType = ContentType;
        context.HttpContext.Response.Headers.Add("Content-Disposition", new[] { "attachment; filename=" + FileDownloadName });
        await FileStream.CopyToAsync(context.HttpContext.Response.Body);
    }
  }

和 Angular 4 代码:

   downloadPdf(url: string, fileName: string, body: any, basePage: BaseErrorPage, showSpinner: boolean = false, goBackToMaster: boolean = true) 
   {

    if (showSpinner) {
        basePage.spinner.runningRefCountIncrement();
    }

    let headers = new Headers({ 
        'UserID': this.storage.UserID,
        'ADUserName': this.storage.ADUserName,
        'Content-Type': 'application/json', 
        'Accept': 'application/pdf'
    });        

    let options = new RequestOptions({ headers: headers });
    options.responseType = ResponseContentType.ArrayBuffer;

    this.http.get(
        url, options).subscribe(
          (response) => {
            var mediaType = 'application/pdf';
            var blob = new Blob([response.blob()], {type: mediaType});
            saveAs(blob, fileName+'.pdf');
          });
    }
于 2018-01-10T18:38:31.143 回答