All Components

File Saver Overview

The File Saver package allows you to save files on the client machine.

The file saving is done through the saveAs method. The package can be consumed from TypeScript and JavaScript projects alike.

Installation

  1. Download and install the package:

    npm install --save @progress/kendo-file-saver
  2. Once installed, individual functions can be imported and the package is ready to use.

    import { saveAs } from '@progress/kendo-file-saver';

Configuration

To save a file on the client machine, call the saveAs method, and pass a valid data URI and a file name.

The following example demonstrates how to save a text file on the client.

import { saveAs, encodeBase64 } from '@progress/kendo-file-saver';

const dataURI = "data:text/plain;base64," + encodeBase64("Hello World!");
saveAs(dataURI, "test.txt");

Server Proxy

The saveAs attempts to save files by using the client-side API in browsers that support file creation—for example, Internet Explorer 10+, Google Chrome, and Firefox.

Getting Started

If the browser does not implement an API for saving files, then the saveAs method can POST the content to a server-side proxy, which streams the file back to the end user.

To enable the server proxy, set the proxyURL option, as demonstrated below.

import { saveAs, encodeBase64 } from '@progress/kendo-file-saver';

const dataURI = "data:text/plain;base64," + encodeBase64("Hello World!");
saveAs(dataURI, "test.txt", {
  proxyURL: "/path/to/proxy"
});

Forcing Proxy Usage

You are also able to make saveAs always use the server proxy by setting the forceProxy option to true, as demonstrated below.

It is highly recommended to use a server proxy for files bigger than 1MB. If the file is too large to be saved without a proxy, you might get an Unknown network error.

import { saveAs, encodeBase64 } from '@progress/kendo-file-saver';

const dataURI = "data:text/plain;base64," + encodeBase64("Hello World!");
saveAs(dataURI, "test.txt", {
    proxyURL: "/path/to/proxy",
    forceProxy: true
});

Server-Proxy Implementations

Parameters

The proxy receives a POST request with the following parameters in the request body:

  • contentType—This is the MIME type of the file.
  • base64—The Base64-encoded file content.
  • fileName—The file name as requested by the caller.
  • Additional fields set through the optional proxyData.

The proxy is expected to return the decoded file with a set "Content-Disposition" header.

Platforms

The following examples demonstrate the implementation of a server-side proxy for different platforms.

ASP.NET WebAPI Controller

public class SaveFile : ApiController
{
    public class FileData
    {
        public string ContentType { get; set; }
        public string Base64 { get; set; }
        public string FileName { get; set; }
    }

    // POST api/savefile
    public HttpResponseMessage Post([FromBody]FileData file)
    {
        var data = Convert.FromBase64String(file.Base64);

        var result = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StreamContent(new MemoryStream(data))
        };

        result.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType);

        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = file.FileName
        };

        return result;
    }
}

ASP.NET MVC Proxy

public class HomeController
{
    [HttpPost]
    public ActionResult Save(string contentType, string base64, string fileName)
    {
        var fileContents = Convert.FromBase64String(base64);

        return File(fileContents, contentType, fileName);
    }
}

ASP.NET WebForms

public partial class SaveFile : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string contentType = Request.Form["contentType"];
        string base64 = Request.Form["base64"];
        string fileName = Request.Form["fileName"];

        byte[] fileContents = Convert.FromBase64String(base64);

        Response.ContentType = contentType;
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
        Response.BinaryWrite(fileContents);
        Response.End();
    }
}

PHP Proxy

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $fileName = $_POST['fileName'];
    $contentType = $_POST['contentType'];
    $base64 = $_POST['base64'];

    $data = base64_decode($base64);

    header('Content-Type:' . $contentType);
    header('Content-Length:' . strlen($data));
    header('Content-Disposition: attachment; filename=' . $fileName);

    echo $data;
}
?>

Java (Spring MVC)

@RequestMapping(value = "/save", method = RequestMethod.POST)
public @ResponseBody void save(String fileName, String base64, String contentType, HttpServletResponse response) throws IOException {

    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

    response.setContentType(contentType);

    byte[] data = DatatypeConverter.parseBase64Binary(base64);

    response.setContentLength(data.length);
    response.getOutputStream().write(data);
    response.flushBuffer();
}
In this article