Skip to content

[Angular | Capacitor] How to save and/or open file

In this short tutorial, I will show you how to save and open files in a capacitor app.

Georg Höller
Georg Höller
3 min read
[Angular | Capacitor] How to save and/or open file
Photo by Jonah Pettrich / Unsplash

The Capacitor Framework helps you in a lot of situations and makes it easy to build an app out of a finished angular website.
But not everything is working out of the box. In this short tutorial, I will show you how to save and open files in a capacitor app.

Version Information

Capacitor: 3.2
Angular: 11.1

Capacitor Utils

To prevent code duplications I created a 'capacitorUtils.ts' file in my angular workspace and created the class 'CapacitorUtils'. Place the file in a folder you can access from everywhere - I placed it in a shared folder.
Your file should look like the following:

import { Capacitor } from '@capacitor/core';

export class CapacitorUtils {
    static readonly isApp = Capacitor.getPlatform() !== 'web';

I added a static variable to check the platform we are running at. You may need this to differ if you should run the following code or the default browser download logic.


For this tutorial you have to install 3 Plugins:

npm install @capacitor/filesystem
npm install cordova-plugin-file-opener2
npm install @ionic-native/file-opener


With the filesystem plugin from capacitor, you can write data to the phone's file system.
With the ionic file opener, you can open the file with the default app for the specific mime type.

Don't forget to call capacitor to sync!

npx cap sync


If you don't use android - skip this section :)

After the sync command I wasn't able tobuild the android solution.
It failed at the file "FileProvider" because the plugin is too old.
To fix this open the file and find the following line:

public class FileProvider extends {

Replace the whole line with this:

public class FileProvider extends androidx.core.content.FileProvider {

Edit 09.02.22
You can fix this problem with jetifier - just run the following (works with every old plugin which doesn't support androidx):

npm install jetifier
npx jetify
npx cap sync android

Save and Open Blob Data

Open your 'capacitorUtils.ts' file and add the following method in the CapacitorUtils class:

static async writeAndOpenFile(data: Blob, fileName: string) {
    var reader = new FileReader();
    reader.onloadend = async function () {
        var base64data = reader.result;
        try {
            const result = await Filesystem.writeFile({
                path: fileName,
                data: <string>base64data,
                directory: Directory.Data,
                recursive: true
            let fileOpener: FileOpener = new FileOpener();
  , data.type)
                .then(() => console.log('File is opened'))
                .catch(e => console.log('Error opening file', e));

            console.log('Wrote file', result.uri);
        } catch (e) {
            console.error('Unable to write file', e);

Don't forget to add all the imports for the source above:

import { FileOpener } from '@ionic-native/file-opener/ngx';
import { Filesystem, Directory } from '@capacitor/filesystem';

This code takes a blob object and writes it to the data directory from the phone. To open the file we created a new FileOpener and use the resulting path from 'writeFile'.
If everything works as intended we should have downloaded the file to our device and it should open automatically.

Now you can call this code from anywhere in your angular app.

if (CapacitorUtils.isApp)
    CapacitorUtils.writeAndOpenFile(, filename);
    saveAs(, filename);


Whenever I run into any kind of issue with this code I will add it here:

  1. Recently I had to download and open a .csv file and it failed. I had to set the mime-type manually to 'text/plain'.

I hope you enjoyed reading this short capacitor tutorial. Keep coding!



Related Posts

Members Public

[Angular] Routing Helper - a Typesafe Routing Attempt

It always bothered me that you have to define the routing paths as strings. If a route changes, you have to change all references manually. There must be a better way! Routing Constants The constants are for your specific app - here you can define a class which represents your

[Angular] Routing Helper - a Typesafe Routing Attempt
Members Public

[ASP.NET Core 6.0 | Angular] Hosting with Ionos

Update for my previous posts about hosting an angular frontend and ASP.NET Core 6 backend. Prerequirements: * active ionos windows hosting subscription * core 6 project * buildable angular project Ionos Setup Open up your favorite FTP client and connect it to your ionos webspace. Create two new folders -

[ASP.NET Core 6.0 | Angular] Hosting with Ionos
Members Public

Transition from Windows to Mac - Frontend Developer

My Windows journey started with Windows 98 I think, maybe Windows 95. Now it is the end of 2022 and I was in need for a new laptop. I have been searching for weeks for a suitable windows notebook, tested an Asus ROG X13 but sent it back because hardware

Transition from Windows to Mac - Frontend Developer