はじめに
よくあるWebページからcsvをダウンロードする機能ですが、この記事はFlutterを用いてcsvダウンロード機能とnodejsを用いてawsのWebAPIに実装について書いています。
Flutter Webからダウンロード
AnchorElementクラス
使うSDKはdart:htmlライブラリAnchorElementクラスです。
実装
BOM
エンコードしたファイルの先頭にBOMを設定しないと文字化けすることがあります。
バイト順マーク (バイトじゅんマーク、英: byte order mark) あるいはバイトオーダーマークとは、通称BOM(ボム)といわれるUnicodeの符号化形式で符号化したテキストの先頭につける数バイトのデータのことである。このデータを元にUnicodeで符号化されていることおよび符号化の種類の判別に使用する。
UTF-8の場合、BOMは下記です。
List<int> excelCsvBytes = [0xEF, 0xBB, 0xBF]
CSV SDK
CSVの整形は下記のSKDを使うと便利です。
https://pub.dev/packages/csv
dependencies:
csv: ^5.0.1
実装例
- ModelmからCSVファイルをダウンロード
import 'package:csv/csv.dart';
import 'dart:html';
import 'dart:convert';
// csvデータ
List<List> users = [["姓", "名", "性別"], ["テスト", "太郎", "男"]];
// SDKによるCSVデータ整形
String csvString = const ListToCsvConverter().convert(users);
// utf-8バイト変換
List<int> excelCsvBytes = [0xEF, 0xBB, 0xBF, ...utf8.encode(csvString)];
// base64エンコード変換
String base64ExcelCsvBytes = base64Encode(excelCsvBytes);
// CSVダウンロード
AnchorElement(href: 'data:text/plain;charset=utf-8;base64,$base64ExcelCsvBytes')
..setAttribute('download', 'user.csv')
..click();
- APIリスポンスからデータをダウンロード
// データリクエスト省略
...
// APIResponseからデータを受け取るときはresponse.bodyBytesで受け取る
// base64エンコード変換
String base64ExcelCsvBytes = base64Encode(response.bodyBytes);
// CSVダウンロード
AnchorElement(href: 'data:text/plain;charset=utf-8;base64,$base64ExcelCsvBytes')
..setAttribute('download', 'user.csv')
..click();
NodejsによるWebAPIのCSVデータダウンロード
SDK
package.json
{
"dependencies": {
"csv": "^6.0.4"
}
}
実装
csvデータを作成する関数をWrapする
const CSV = require('csv')
function createCsvData(data) {
return new Promise(resolve => {
CSV.stringify(data, { bom: true, quoted: true, header: true }, (error, csvData) => {
resolve(csvData)
})
})
}
ダミーデータ
const rows = [
{
"姓": "テスト",
"名": "太郎",
"性別": "男",
}
]
const csv = await createCsvData(rows)
リスポンスでデータを送信する
res.setHeader('Content-disposition', `attachment; filename=user.csv`)
res.setHeader('Content-Type', 'text/plain')
res.send(csv)
参考