【Flutter/Dart開発】csv形式をtxtファイルに直してアプリに取り込み、収支の一覧を表示した話(前編)【個人開発】
こんにちは、たちつてとです。
○○銀行のシステムが酷すぎるので、極力システムを経由せずに厳密に出入金を記録する機能を作る話
の過去記事では、CSVファイルを
銀行システムからダウンロードし、
出費管理アプリに取り込むことで
極力銀行のシステムを介さずに、
出費等を把握したい、ということを話しました。
とりこみのプレビュー?みたいな画面を作ったので
記事にする次第です。
なお、上記の通りCSVファイル自体は
ダウンロードしてあって、Google Driveや
スマホのストレージなどから
CSVにアクセスできる状態というのが
前提(というか準備?)となります。
(file_pickerでDriveやストレージへ
アクセスするため)
結論
追記
csvが悪いんじゃなくて、ファイルそのものの問題ぽい
ダウンロード→ファイルをコピペ
○コピペで複製したファイルは読み込める
×コピペの複製元のファイルはエラー
どゆことやねん...。
2022/01/29さらに追記。
素でダウンロードしたものをコンソールで
utf-8に直すと
エラーが消えた。
CSVを取り込むプレビュー的な
以下、成果物の画面遷移になります。
デザインはこれ以上ないくらい雑っす。
「+」ボタンでスマホのファイル選択、
内容を「見にいく」。
拡張子が「txt」なのは後述します。
(一時フォルダに保存とかしてるわけではなく、
単純にファイルの内容を
参照するのを待機してる状態です。)
画像にメモるの忘れてたんですが、
↑最後の画像のファイル名のとこは、
ボタンになってて押下すると↓画像につながります。
そして実際のファイル内容の表示になります。
赤いところは、僕の年収がわかっちゃう(いやん)ので
伏せてあります。
一行が結構長めなので、
横スクロールで適宜見れるようにしています。
まあ、クレカの払い出しなんて一回だし
ATMの出し入れも月3,4回ないくらいなので
表示の改善の余地はあります。
スクロールとするよりは、
CSVでの一行をアプリの方で二行に分けて表示した方が
便利そうではあります。
まあ、おもろいからよし。
なお、この状態は
CSVの内容を一覧表示してるだけで
登録とかはしてないです。
(ですので、プレビュー的)
拡張子について
ここからわからんくて悔しかったところ。
結論を書くと、CSVファイルの内容取得が
どうしても上手くいきませんでした。
しかし、txtファイルでの読み取りはできたので
とりあえずcsv→txtとファイルの拡張子を変更して
インポートしてます。
さて、file_picker(4.2.4)という
パッケージを使っているんですが。
1.わからんだとこ
まずcsvの選択のみでフィルターをかけると
Androidくんの方が悪いのか
csv形式も選択不可にしちゃってる...
→結局、CSVのファイル選択できず...
// 以下、ダメな例
FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ["csv"]// CSVファイルだけを選択肢に(作戦1)
);
if (result != null) {
PlatformFile file = result.files.first;
if (file.extension != "csv") {// CSVファイル以外が選択ならNG(作戦2)
_showAlertDialog(buildContext);
return null;
}
File newFile = File(file.path.toString());
//String name = basename(newFile.path);//.replaceAll(RegExp(r"\..*"), "");
//newFile.copy("temp/$name");
return newFile;
(外部パッケージ:file_pickerの)PlatformFlieの
プロパティallowedExtensionsで"csv"を設定しても
csvが選択できない...
↑ソースのコメント:作戦1が失敗。
仕方ないので↑のソースの
作戦1のあたり、
type:Filetype.any
という指定だけに直しました。
(加えてallowed〜を削除)
で、PlatformFlieのプロパティextensionを利用して
if(file.extension != "csv"){
return ;// CSV以外なら強制終了
}
と選択ファイルのチェックを書いてました。
作戦2は上手く機能しており、
あとはCSVの内容を取り出すだけでした。
2.わからんだとこ
しかし、今度はファイル読み込みで
なんかわからんけど失敗...
final File file = File(ファイルパス);
Stream fread = file.openRead();
fread
.transform(systemEncoding.decoder)
.transform(const LineSplitter())
.listen((String row) {
// 変数rowにCSVの一行一行が入る予定だった...
}
こんな感じのソースを書いていて
一行目のファイルパスにCSVのパスを渡せば
ほぼ実装は終わっていたはずでした。
FormatException: Unexpected extension byte (at offset 1)
おわた\(^o^)/
正直原因(というか英語が)わからず。
もちろんググりはしました。
作戦2、失敗。
あまりにもわからず、魔がさしたのか
試しにcsv→txtに拡張子直してみたんです。
csvは、たかがカンマ付の文字列データですし、
少なくともmacはtxtでも表示してくれたので。
通った...
はい。
file_pickerかAndroidか
両方が悪いのかも分かりませんが
csv相性悪い?
追記
上述の通り、ファイルの問題?
コピペしたファイルは取り込めるという謎。
まとめと補足
→現象としては、csvファイルも
選択不可になってしまいました。
- しゃあないので、csv→txtのひと手間を添える
- 追記:ではなく、ファイルをコピペする手間を添える
→読み込みに失敗するので、このような処置をとりました。
Flutter モバイルアプリ開発バイブル |