サーバを使わずに、フロントエンド (vue.jsやreact)のみでファイルのダウンロードをするクラスを作成しました。

ライブラリはこちらを使用しました。 https://github.com/eligrey/FileSaver.js

必要なライブラリのインストール

$ npm i file-saver
$ npm i --save-dev @types/file-saver (tsの場合)

FileDownloader.ts

csvと、json, text, urlでそれぞれダウンロードできるようにメソッドを分けました。 URLの場合は、同一ドメインじゃない場合はセキュリティ上ダウンロードされないと思います。

import { saveAs } from 'file-saver'

export default class FileDownloader {
  /**
   * CSVをダウンロードする
   */
  public static downloadCsv = (
    filename: string,
    csvData: any[][],
    separator = ',',
    LF = '\n',
  ) => {
    const bom = new Uint8Array([0xef, 0xbb, 0xbf])
    const file = csvData
      .map((row) => {
        return row.join(separator)
      })
      .join(LF)

    // download
    const blob = new Blob([bom, file], {
      type: 'text/csv',
    })
    saveAs(blob, filename)
  }

  /**
   * jsonをダウンロードする
   */
  public static downloadJSon = (jsonObject: any, filename: string) => {
    const blob = new Blob([JSON.stringify(jsonObject, null, 2)], {
      type: 'application/json',
    })

    saveAs(blob, filename)
  }

  /**
   * textをダウンロードする
   */
  public static downloadText = (
    text: string,
    filename: string,
    type = 'text/plain;charset=utf-8',
  ) => {
    const blob = new Blob([text], { type: type })
    saveAs(blob, filename)
  }

  /**
   * URLのファイルをダウンロードする
   */
  public static downloadUrl = (url: string, filename: string) => {
    // NOTE: ここのfilenameは適用されないかも
    saveAs(url, filename)
  }
}

使い方

こんな感じでインポートします。

import FileDownloader from './utils/FileDownloader'

// csv download
FileDownloader.downloadCsv('csv_download.csv', [
  ['項目1', '項目2', '項目3'],
  [200, 300, 400],
  [500, 600, 700],
])

// text download
FileDownloader.downloadText('テキストの内容です。', 'text.txt')

// json download
FileDownloader.downloadJSon(
  {
    aaa: 'bbb',
    ccc: 'ddd',
    eee: {
      fff: 'ggg',
      hhh: 'iii',
    },
    jjj: [0, 1, 2, 3, 4],
  },
  'json_download.json',
)

// url download
FileDownloader.downloadUrl(
  'https://walking-succession-falls.com/my-icon.png',
  'icon.png',
)