【问题标题】:Create binary file in Angular在 Angular 中创建二进制文件
【发布时间】:2017-11-11 02:26:51
【问题描述】:

我有一个 Angular 应用程序,我需要从 REST API 获取文件的内容并在客户端生成文件。

由于我无法在客户端写入新文件,我使用this question 作为解决方法。

所以基本上它所做的就是创建一个包含内容的 Blob 并生成一个下载链接,然后模拟点击链接以便下载文档。

这是我的代码:

download(filename) {
    this.service
      .downloadFile(filename)
      .subscribe(data => {
        console.log(data.document);
        this.downloadFile(data.document, filename);
      }, err => this.info = err);
  }

这会从服务器获取数据

private downloadFile(content: string, filename: string) {
    const link = document.createElement('a');
    link.setAttribute('download', filename);
    link.href = this.makeTextFileUrl(content, filename);

    document.body.appendChild(link);

    // wait for the link to be added to the document
    window.requestAnimationFrame(function () {
      const event = new MouseEvent('click');
      link.dispatchEvent(event);
      document.body.removeChild(link);
    });
  }

这会建立链接并模拟点击下载

private makeTextFileUrl(content: string, filename: string): string {
    let url = null;

    const mime = this.getMimeType(filename);
    console.log(mime);
    const blob = new Blob([content], { type: mime });
    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (url !== null) {
      window.URL.revokeObjectURL(url);
    }

    url = window.URL.createObjectURL(blob);
    return url;
  }

这会生成 url 链接

private getMimeType(filename: string): string {
    if (filename.indexOf('.docx') !== -1) return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
    if (filename.indexOf('.doc') !== -1) return 'application/msword';
    if (filename.indexOf('.pdf') !== -1) return 'application/pdf';
    return 'text/plain';
  }

mime 类型因扩展而异

所以,这适用于纯文本文件,但对于 docx 文件,当我尝试打开文件时出现错误,并且使用 pdf 文件似乎是空白的。

我读到对于二进制文件,我需要将 responseType 设置为 ArrayBuffer 才能正常工作,所以我更新了我的服务 get call to this

downloadFile(id: string): Observable<any> {
    return this.authHttp
      .get(`${this.api}/download/${id}`, { responseType: ResponseContentType.ArrayBuffer })
      .map(res => {
        const data = res.json();
        return data;
      });
  }

但现在我尝试下载文件时出现错误,无论它是 txt、pdf 还是 docx 文件SyntaxError: Unexpected token ≻ in JSON at position 0

有谁知道如何解决这个问题?

谢谢

【问题讨论】:

    标签: angular blob httpresponse


    【解决方案1】:

    所以我终于让它工作了。

    事实证明,我正在使用中间 API Rest 来获取文件的内容,然后将它们重新发送到我的前端应用程序,但是在这一步中,正文被解析为字符串,因此,我在我的前端应用不是原始内容。

    在这个线程中是解决这个问题的方法。 Resend body from response exactly as it comes

    然后我只需要在前端应用程序中更改一些内容即可获取二进制文件。

    downloadFile(id: string): Observable<any> {
        return this.authHttp
          .get(`${this.api}/${id}`, { responseType: ResponseContentType.ArrayBuffer })
          .map(res => {
            return res.blob();
          });
      }
    

    所以现在我不是以 json 形式而是以 blob 形式检索数据。

    然后在我的组件中

    download(filename) {
        const id = this.filesIds[filename];
        this.service
          .downloadFile(id)
          .subscribe(blob => {
            this.downloadFile(blob, filename);
          }, err => this.info = err);
      }
    
      private downloadFile(blob: Blob, filename: string) {
        const link = document.createElement('a');
        link.setAttribute('download', filename);
    
        link.href = this.makeTextFileUrl(blob, filename);
    
        document.body.appendChild(link);
    
        // wait for the link to be added to the document
        window.requestAnimationFrame(function () {
          const event = new MouseEvent('click');
          link.dispatchEvent(event);
          document.body.removeChild(link);
        });
      }
    

    其余的保持不变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 2020-08-03
      • 2017-12-24
      • 1970-01-01
      • 2014-04-08
      相关资源
      最近更新 更多