saveFile method

  1. @override
Future<String?> saveFile({
  1. String? dialogTitle,
  2. String? fileName,
  3. String? initialDirectory,
  4. FileType type = FileType.any,
  5. List<String>? allowedExtensions,
  6. Uint8List? bytes,
  7. bool lockParentWindow = false,
})
override

Opens a save file dialog which lets the user select a file path and a file name to save a file.

For mobile, this function will save a file with the given fileName and bytes and return the path where the file was saved.

For desktop platforms, this function opens a dialog to let the user choose a location for the file and returns the selected path. If the bytes are provided, then the bytes are written to a file at the chosen path.

On the web, this function will start a download for the file with bytes and fileName. If the bytes or fileName are omitted, this will throw an ArgumentError. The returned path for the downloaded file will always be null, as the browser handles the download.

The User Selected File Read/Write entitlement is required on macOS.

dialogTitle can be set to display a custom title on desktop platforms. Not supported on macOS.

fileName can be set to a non-empty string to provide a default file name. Throws an IllegalCharacterInFileNameException under Windows if the given fileName contains forbidden characters.

initialDirectory can be optionally set to an absolute path to specify where the dialog should open. Only supported on Linux, macOS, and Windows. On macOS the home directory shortcut (~/) is not necessary and passing it will be ignored. On macOS if the initialDirectory is invalid the user directory or previously valid directory will be used.

The file type filter type defaults to FileType.any. Optionally, allowedExtensions might be provided (e.g. [pdf, svg, jpg]). Both parameters are just a proposal to the user as the save file dialog does not enforce these restrictions.

If lockParentWindow is set, the child window (file picker window) will stay in front of the Flutter window until it is closed (like a modal window). This parameter works only on Windows desktop.

Returns null if aborted. Returns a Future<String?> which resolves to the absolute path of the selected file, if the user selected a file.

Implementation

@override
Future<String?> saveFile({
  String? dialogTitle,
  String? fileName,
  String? initialDirectory,
  FileType type = FileType.any,
  List<String>? allowedExtensions,
  Uint8List? bytes,
  bool lockParentWindow = false,
}) async {
  if (bytes == null || bytes.isEmpty) {
    throw ArgumentError(
      'The bytes are required when saving a file on the web.',
    );
  }

  if (fileName == null || fileName.isEmpty) {
    throw ArgumentError(
      'A file name is required when saving a file on the web.',
    );
  }

  if (p.extension(fileName).isEmpty) {
    throw ArgumentError(
      'The file name should include a valid file extension.',
    );
  }

  final blob = Blob([bytes.toJS].toJS);
  final url = URL.createObjectURL(blob);

  // Start a download by using a click event on an anchor element that contains the Blob.
  HTMLAnchorElement()
    ..href = url
    ..target = 'blank' // Always open the file in a new tab.
    ..download = fileName
    ..click();

  // Release the Blob URL after the download started.
  URL.revokeObjectURL(url);
  return null;
}