はじめに
顧客要望で、csvファイルでデータをダウンロードしたいということがあり、
出力方法を毎回調べるのも面倒なので、ここにメモとして残します。
概要
- ボタンをクリックしたら、Userオブジェクトのデータがcsv形式でダウンロードできる
- リンクではなく、ボタンがいい
完成CSVファイル
名前 | 年齢 | 住所 |
---|---|---|
木村太郎 | 25歳 | 東京都〇〇 |
田中花子 | 20歳 | 千葉県〇〇 |
完成画面イメージ
環境
- Next.js v13.5.4
- tailwindCSS
- daisyUI
実装
1. Userクラスを定義
-
出力するデータのオブジェクトを定義します
-
privateプロパティにするかどうかはプロジェクト判断
class User { constructor( private _name: string, private _age: string, private _address: string ) {} }
2. keyを定義
-
出力するデータの一行目の項目名になるものを定義
名前 年齢 住所 -
UserクラスのStaticメソッドで定義しました
class User { constructor( private _name: string, private _age: string, private _address: string ) {} + static key() { + return ['名前', '年齢', '住所'] + } }
3. valueを定義
-
出力するレコードのvalueを定義します
class User { constructor( private _name: string, private _age: string, private _address: string ) {} + value() { + return [this._name, this._age, this._address] + } static key() { return ['名前', '年齢', '住所'] } }
keyとvalueの要素数・順番に注意
4. csvデータ作成メソッドの作成
-
今回出力したいcsvデータの完成系は下のようになデータです。
名前,年齢,住所 木村太郎,25歳,東京都〇〇 田中花子,20歳,千葉県〇〇
-
先ほど作成したkeyとvalueを使い、csvデータを作成するメソッドを作成します。
const convertToCSV = (users: User[]): string => { const key = User.key() const values = users.map((user) => user.value()) const array = [key].concat(values) return array.map((a) => a.join(',')).join('\n') }
5. ボタンとアンカーを配置し、ボタンクリック時にダウンロードする
-
まずボタンとアンカーを配置し、アンカーには
useRef
を設定しておきますconst Page = () => { const anchorRef = useRef<HTMLAnchorElement>(null) return ( <div className='m-5'> <button className='btn'> DownLoad </button> <a ref={anchorRef} className='hidden'></a> </div> ) } export default Page
-
ボタンをクリック時にダウンロードが進むように、ダウンロードメソッドを定義し、onClickに設定
-
ダウンロードメソッドの引数には、csvデータと、filenameを設定
const Page = () => { const anchorRef = useRef<HTMLAnchorElement>(null) + const downloadCSV = (csv: string, filename: string) => {} return ( <div className='m-5'> <button + onClick={() => downloadCSV(convertToCSV(users), 'user_list.csv')} className='btn' > DownLoad </button> <a ref={anchorRef} className='hidden'></a> </div> ) } export default Page
-
ダウンロードメソッドの詳細を書いていきます。
const downloadCSV = (csv: string, filename: string): void => { const link = anchorRef.current if (!link) return const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }) const url = URL.createObjectURL(blob) link.setAttribute('href', url) link.setAttribute('download', filename) link.click() }
これでオブジェクトデータのcsv出力ができるはずです。