【问题标题】:Download .doc file from angular从 Angular 下载 .doc 文件
【发布时间】:2021-01-19 17:30:37
【问题描述】:

我是 Angular 的新手,我正在尝试在单击按钮时创建一个下载链接以下载 doc 文件。该文件已成功下载,但里面的内容是“[object Object]”。文件路径在我的 webroot 中,我正在像这样访问文件:

[Route("api/[Controller]")]
    [ApiController]
    public class DownloadController : Controller
    {
        private readonly IWebHostEnvironment _env;

        public DownloadController(IWebHostEnvironment env)
        {
            _env = env;
        }
        [HttpGet]
        public async Task<IActionResult> Download()
        {
            string filePath = Path.Combine(_env.WebRootPath, "Image\\CV.doc");
            using MemoryStream memorystream = new MemoryStream();
            using (var stream = new FileStream(filePath, FileMode.Open))
            {
                await stream.CopyToAsync(memorystream);
            }
            memorystream.Position = 0;
            return File(memorystream, "application/msword", "CV.doc");
        }
    }

我的共享服务.ts。我也将观察更改为“身体”。

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class SharedService {
  cvFilePathURL = "https://localhost:44346/api/Download";
  constructor(private http: HttpClient) { }
  getCV(): Observable<any> {
    return this.http.get(this.cvFilePathURL, {
      observe: 'response',
      responseType: 'text'
    });
  }
}

这是我的 componenet.ts

import { Component } from '@angular/core';
import { SharedService } from 'src/app/shared.service';
@Component({
  selector: 'app-nav-menu',
  templateUrl: './nav-menu.component.html',
  styleUrls: ['./nav-menu.component.css']
})
export class NavMenuComponent {
  constructor(private service: SharedService) { }
  isExpanded = false;

  collapse() {
    this.isExpanded = false;
  }

  toggle() {
    this.isExpanded = !this.isExpanded;
  }
  public Download(): void {
    this.service.getCV().subscribe((data) => {
      var newBlob = new Blob([data], { type: "application/msword" });
      //For Internet Explorer
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        return window.navigator.msSaveOrOpenBlob(newBlob);
      }
       //For other browsers: 
       //Create a link pointing to the ObjectURL containing the blob.
      const mainData = window.URL.createObjectURL(newBlob);
      var link = document.createElement('a');
      link.href = mainData;
      link.download = "CV.doc";
      link.click();;
    });
  }
}

目标框架 - asp.net core 3.1 角 Cli - 11.0.6 更新: 因此,我设法下载了具有 [objects Objects] 以外的实际内容的文件。但是,该文件充满了特殊字符,长达 206 页。原始文件只有 2 页长。

【问题讨论】:

    标签: javascript asp.net angular typescript


    【解决方案1】:

    我认为您可能需要在代码中进行一些更改,或者您可以查看我将在下面提供的代码。
    您的控制器

       [HttpPost]
        [Route("get-download-file")]
        public HttpResponseMessage GetDownloadFile(dynamic data)
        {
            // var localFilePath = HttpContext.Current.Server.MapPath("~/Documents/" + (string)data.fileName);
            var localFilePath = HttpContext.Current.Server.MapPath((string)data.mappingPath);
            string contentType = MimeMapping.GetMimeMapping(Path.GetExtension(localFilePath));
    
            HttpResponseMessage response = null;
    
            try
            {
                if (!File.Exists(localFilePath))
                {
                    //if file not found than return response as resource not present 
                    response = Request.CreateResponse(HttpStatusCode.Gone);
                }
                else
                {
                    //if file present than read file 
                    var fStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
                    //compose response and include file as content in it
                    response = new HttpResponseMessage
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content = new StreamContent(fStream)
                    };
                    //set content header of reponse as file attached in reponse
                    response.Content.Headers.ContentDisposition =
                    new ContentDispositionHeaderValue("attachment")
                    {
                        FileName = Path.GetFileName(fStream.Name)
                    };
                    //set the content header content type as application/octet-stream as it returning file as reponse 
                    response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                }
            }
            catch (Exception ex)
            {
                return response;
            }
    
            return response;
        }
    

    在您的 Service(Angular) 中添加 httpPostMethod:

    public httpPostFile(url: string, body: any): Observable<Blob> {
        return this.httpClient.post<Blob>(this.baseUri + url, body, { responseType: 'blob' as 'json' })
            .pipe(
                catchError(this.handleClientError)
            );
    }
    

    最后,您必须从 Angular 调用该方法。使用下面的代码->

             let tempBlob: any;
              let contentFileType= 'txt'; //you can make that file type dynamic using some addional code.
                        const data = {
                            fileName: this.fileName,
                            mappingPath: '~/Documents/' + this.fileName
                        };
                        this.apiService.httpPostFile('download/get-download-file/', data)
                            .subscribe(fileData => {
    
                                tempBlob = new Blob([fileData], { type: contentFileType });
                            },
                                (error) => {
                                    
                                }, () => {
    
                                   
                                    const blob: Blob = new Blob(tempBlob, { type: contentFileType });
                                   
                                    const fileName: string = this.filedlName;
                                    const objectUrl: string = URL.createObjectURL(blob);
                                    const a: HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement;
    
                                    a.href = objectUrl;
                                    a.download = fileName;
                                    document.body.appendChild(a);
                                    a.click();
    
                                    document.body.removeChild(a);
                                    URL.revokeObjectURL(objectUrl);
                                });
    

    注意:在 Angular 和 ASP MVC Web API 中下载文件可以有更有效的方法。但这种方式对我有用。你可以试试。如果您发现任何困难,请随时提出。谢谢。

    【讨论】:

    • 嗨@Linker-SJNF。很抱歉这么晚才联系。我一直在尝试你的代码并研究我不理解的位,我也尝试过对其进行一些更改,但它仍然对我不起作用。要么相同要么{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,"minorRevision":-1},"content":{"headers":[{"Key":"Content-Disposition","Value":["attachment; filename=CV.doc"]},{"Key":"Content-Type","Value":["application/msword"]}]},"statusCode":200,"reasonPhrase":"OK","headers":[],"trailingHeaders":[],"requestMessage":null,"isSuccessStatusCode":true}
    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2018-12-13
    相关资源
    最近更新 更多