32 lines
1.1 KiB
Dart
32 lines
1.1 KiB
Dart
// 📄 [웹 전용] file_picker의 웹 구현체에 pickFile(s)가 아직 없어서(UnimplementedError),
|
|||
|
|
// 숨겨진 <input type="file">를 직접 만들어 처리한다.
|
||
|
|
import 'dart:async';
|
||
|
|
import 'dart:js_interop';
|
||
|
|
import 'dart:typed_data';
|
||
|
|
import 'package:web/web.dart' as web;
|
||
|
|
|
||
|
|
/// 사용자가 엑셀(.xlsx) 파일을 고르면 바이트를 돌려준다. 취소하면 null.
|
||
|
|
Future<Uint8List?> pickExcelFileBytes() async {
|
||
|
|
final completer = Completer<web.File?>();
|
||
|
|
final input = web.HTMLInputElement()
|
||
|
|
..type = 'file'
|
||
|
|
..accept = '.xlsx'
|
||
|
|
..style.display = 'none';
|
||
|
|
// 문서에 실제로 붙어있지 않으면 일부 브라우저/자동화 환경에서 change 이벤트가
|
||
|
|
// 안정적으로 안 잡힌다 — 그래서 body에 잠깐 붙였다가 끝나면 반드시 제거한다.
|
||
|
|
web.document.body!.append(input);
|
||
|
|
|
||
|
|
input.onchange = (web.Event event) {
|
||
|
|
final file = input.files?.item(0);
|
||
|
|
input.remove();
|
||
|
|
completer.complete(file);
|
||
|
|
}.toJS;
|
||
|
|
|
||
|
|
input.click();
|
||
|
|
final file = await completer.future;
|
||
|
|
if (file == null) return null;
|
||
|
|
|
||
|
|
final buffer = await file.arrayBuffer().toDart;
|
||
|
|
return buffer.toDart.asUint8List();
|
||
|
|
}
|