0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ローカルでCSVファイルを作ってダウンロードさせる

Last updated at Posted at 2023-06-05

諸元

処理の結果をファイルとして返すけど、ユーザーの任意のタインミングでダウンロードさせたい。
そうするとバックエンドでファイルを作り込んでおいて永続化(S3とか)するか、セッションにバイト配列として保持しておくか、または取得リクエストの際に別途作るのか・・・・・・。

いろいろやり方はあると思うのですが、データだけフロントに返しておいてフロント側で構築すればいいのでは?と思いました。
もちろん、ファイルの容量が大きくなってしまうような場合は取れない手段だと思うのですが。

また、ファイルの文字コードにはShift_JISとUTF8の2種類を出しわけられるようにするとします。

実現方法

バックエンド

適切な文字コードで表現したCSV内容をバイト配列化、Base64エンコードした文字列として返却します。
Springでの例です。

model.addAttribute("bytes", Base64.getEncoder().encodeToString(file.toByteArray()))

適当に埋め込んでおきます。

<input type="hidden" id="data" value="${bytes}" />

フロントエンド

// Base64からバイト配列に復元する
const bs = atob($('#data').val());
const bytes = new Uint8Array(bs.length);
for (let i = 0; i < bs.length; i++) {
    bytes[i] = bs.charCodeAt(i);
}

// Fileオブジェクトを作る
// 第一引数がデータ
const file = new File([bytes.buffer], 'hoge.csv', {type: 'text/csv'});

// ダウンロード用a要素を作って
const a = document.createElement('a');
a.download = 'hoge.csv';

// fileを対象としたURLを作る
a.href = URL.createObjectURL(file);
document.body.append(a);
a.click();

単に持ってる文字列をファイル化したいなら第一引数は['hoge']みたいな感じでいいんですが……。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?