5.6 KiB
title | pagination_prev | pagination_next | sidebar_position | sidebar_custom_props | ||
---|---|---|---|---|---|---|
Flutter | demos/static/index | demos/desktop/index | 5 |
|
import current from '/version.js'; import CodeBlock from '@theme/CodeBlock';
Dart + Flutter is a cross-platform alternative to JS + React Native.
For the iOS and Android targets, the flutter_js
package wraps JavaScriptCore
and QuickJS engines respectively.
The Standalone scripts can be parsed and evaluated in the wrapped engines.
The "Complete Example" creates an app that looks like the screenshots below:
iOS |
---|
:::warning Telemetry
Before starting this demo, manually disable telemetry. On MacOS:
dart --disable-telemetry
dart --disable-analytics
flutter config --no-analytics
flutter config --disable-telemetry
:::
Integration Details
This demo assumes familiarity with Dart and Flutter.
Loading SheetJS
Adding the scripts
The flutter.assets
property in pubspec.yaml
specifies assets. Assuming the
standalone script and shim are placed in the scripts
folder, the following
snippet loads the scripts as assets:
flutter:
assets:
- scripts/xlsx.full.min.js
- scripts/shim.min.js
Once loaded, the contents can be loaded with rootBundle.loadString
:
import 'package:flutter/services.dart' show rootBundle;
String shim = await rootBundle.loadString("scripts/shim.min.js");
String sheetjs = await rootBundle.loadString("scripts/xlsx.full.min.js");
Initialization
It is strongly recommended to add the engine to the state of a StatefulWidget
:
import 'package:flutter_js/flutter_js.dart';
class SheetJSFlutterState extends State<SheetJSFlutter> {
// highlight-next-line
late JavascriptRuntime _engine;
@override void initState() {
// highlight-next-line
_engine = getJavascriptRuntime();
}
}
Running SheetJS Scripts
Since fetching assets is asynchronous, it is recommended to create a wrapper
async
function and sequentially await each script:
class SheetJSFlutterState extends State<SheetJSFlutter> {
String _version = '0.0.0';
@override void initState() {
_engine = getJavascriptRuntime();
_initEngine(); // note: this is not `await`-ed
}
Future<void> _initEngine() async {
/* fetch and evaluate the shim */
String shim = await rootBundle.loadString("scripts/shim.min.js");
_engine.evaluate(shim);
// highlight-start
/* fetch and evaluate the main script */
String sheetjs = await rootBundle.loadString("scripts/xlsx.full.min.js");
_engine.evaluate(sheetjs);
// highlight-end
/* capture the version string */
JsEvalResult vers = _engine.evaluate("XLSX.version");
setState(() => _version = vers.stringResult);
}
}
Reading data
The most common binary data type in Dart is Uint8List
. It is the data type
for http.Response#bodyBytes
and the return type of File#readAsBytes()
.
The Flutter JS connector offers no simple interop for Uint8List
data. The data
should be converted to Base64 before parsing.
The csv
package provides a special CsvToListConverter
converter to generate
List<List<dynamic>>
(Dart's spiritual equivalent of the array of arrays):
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:csv/csv.dart';
class SheetJSFlutterState extends State<SheetJSFlutter> {
List<List<dynamic>> _data = [];
void _processBytes(Uint8List bytes) {
String base64 = base64Encode(bytes);
JsEvalResult func = _engine.evaluate("""
var wb = XLSX.read('$base64');
XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
""");
String csv = func.stringResult;
setState(() { _data = CsvToListConverter(eol: "\n").convert(csv); });
}
Demo
:::note
This demo was tested on an Intel Mac on 2023 May 31 with Flutter 3.10.2,
Dart 3.0.2, and flutter_js
0.7.0
The iOS simulator runs iOS 16.2 on an iPhone 14 Pro Max.
:::
- Disable telemetry.
dart --disable-telemetry
dart --disable-analytics
flutter config --no-analytics
flutter config --disable-telemetry
- Create a new Flutter project:
flutter create sheetjs_flutter
cd sheetjs_flutter
-
Open the iOS simulator
-
While the iOS simulator is open, start the application:
flutter run
Once the app loads in the simulator, stop the terminal process.
- Install Flutter / Dart dependencies:
flutter pub add http csv flutter_js
- Open
pubspec.yaml
with a text editor. Search for the line that starts withflutter:
(no whitespace) and add the highlighted lines:
# The following section is specific to Flutter packages.
flutter:
// highlight-start
assets:
- scripts/xlsx.full.min.js
- scripts/shim.min.js
// highlight-end
- Download dependencies to the
scripts
folder:
{\ mkdir -p scripts cd scripts curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js cd ..
}
- Download
main.dart
tolib/main.dart
:
curl -L -o lib/main.dart https://docs.sheetjs.com/flutter/main.dart
- Launch the app:
flutter run
The app fetches https://sheetjs.com/pres.numbers, parses, converts data to an
array of arrays, and presents the data in a Flutter Table
widget.