首页 > 解决方案 > 使用 asp.net core 和 angular 生成下载链接

问题描述

请帮我解决我的问题。

我正在创建一个网站,用户可以上传要转换为 pdf 的 word 文档。并且用户应该能够下载处理后的文件。

到目前为止,我有这个 Html 代码

<input type="file" (change)="upload($event.target.files)" />
    Upload Percent: {{percentDone}}% <br />

    <ng-container *ngIf="uploadSuccess">
      <button type="button">Download</button>
    </ng-container> 

这是 Angular 代码

upload(files: File[]){

    this.uploadAndProgress(files);
  }

uploadAndProgress(files: File[]){
    console.log(files)
    var formData = new FormData();
    Array.from(files).forEach(f => formData.append('file',f))

    this.http.post('http://localhost:5000/api/DocumentToPdf/Document', formData, {reportProgress: true, observe: 'events'})
      .subscribe(event => {
        if (event.type === HttpEventType.UploadProgress) {
          this.percentDone = Math.round(100 * event.loaded / event.total);
        } else if (event instanceof HttpResponse) {
          this.uploadSuccess = true;
        }
    });
  }

这是 Asp.net Core 代码

[Route("api/[controller]")]
[ApiController]
public class DocumentToPdfController : ControllerBase
{
    private readonly IDocumentToPdf _documentToPdf;

    public DocumentToPdfController(IDocumentToPdf documentToPdf)
    {
        _documentToPdf = documentToPdf;
    }    

    [HttpPost("Document")]
    public async Task<Stream> Document()
    {
        try
        {
            var file = Request.Form.Files;

            return  _documentToPdf.DocumentToPdf(file[0].OpenReadStream());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
            throw;
        }
    }
}

我能够处理上传的文件。

但问题是我没有下载输出文件的功能。

截至目前,Asp.net 核心的回归是 Stream。

我怎样才能调整它以能够下载文件过程?

如果我要编写在服务器端处理的文件。如何创建能够下载输出文件的下载链接?

更新:根据 sdev95 评论。我把我的代码改成

控制器:

public HttpResponseMessage Document()
        {
            try
            {
                var file = Request.Form.Files;

                var fileData = _documentToPdf.DocumentToPdf(file[0].OpenReadStream());
                HttpResponseMessage response = null;


                response = new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK,
                    Content = new ByteArrayContent(fileData.ToArray())
                };
                response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                response.Content.Headers.ContentDisposition.FileName = "pdf.pdf";
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response.Content.Headers.ContentLength = fileData.Length;

                Console.WriteLine(fileData.Length);


                return response;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                throw;
            }
        }

还有角码

upload(files: File[]){

    this.uploadAndProgress(files);
  }

  uploadAndProgress(files: File[]){
    console.log(files)
    var formData = new FormData();
    Array.from(files).forEach(f => formData.append('file',f))

    this.http.post('http://localhost:5000/api/DocumentToPdf/Document', formData, {reportProgress: true, responseType: 'blob',  observe: 'events'})
      .subscribe(event => {
        if (event.type === HttpEventType.UploadProgress) {
          this.percentDone = Math.round(100 * event.loaded / event.total);
        } else if (event instanceof HttpResponse) {
          this.uploadSuccess = true;
          console.log('Success');
          console.log('event: ' + event);
          this.downloadFile(event, 'download.pdf');
        }
    });
  }

  downloadFile(data: any, filename: string) {
    const blob = new Blob([data], { type: 'application/octet-stream' });
    saveAs(blob, filename);
  }

但我现在的问题是。它下载一个文件,但下载的文件只有1kb。

我调试了asp.net核心,代码fileData.Length返回了类似的东西,49648但为什么它只返回一个1kb的文件。我的代码有什么问题?

谢谢

标签: angularasp.net-coreasp.net-web-apiangular7filesaver.js

解决方案


假设您从后端获取正确的数据。你有几个选择。

在客户端下载文件的几个库选项:

如果您不想使用 3rd 方库,您可以尝试手动执行并从后端返回一个字节数组,那么下面的代码可以工作:)。

示例中的结果是来自后端的响应。

let file = new Blob([result.blob()], {type: 'application/pdf'});
let fileUrl = URL.createObjectURL(file);
var link = document.createElement('a');
link.href = fileUrl;
link.download = "filename___x.pdf";
document.body.appendChild(link);
link.click();

推荐阅读