This is a migrated thread and some comments may be shown as answers.

KendoUI file-saver saving a zip file

6 Answers 1002 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Chau
Top achievements
Rank 1
Chau asked on 15 May 2018, 07:36 PM

Being a newbie to Angular 4 and typescript, I am not sure how to receive a memory stream sent back by the API controller and popup a file dialog to save it on the client.

This is what I currently have:

1) in my API controller, I am sending back an HttpResponseMessage such as:

    public HttpResponseMessage Post(ReportsManagementUI workobj)
        {

                    var zipfilename = workobj.CreateZipReport(session, sessionuser);
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (FileStream file = new FileStream(zipfilename, FileMode.Open, FileAccess.Read))
                        {
                            byte[] bytes = new byte[file.Length];
                            file.Read(bytes, 0, (int)file.Length);
                            ms.Write(bytes, 0, (int)file.Length);

                            HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
                            httpResponseMessage.Content = new ByteArrayContent(bytes.ToArray());
                            httpResponseMessage.Content.Headers.Add("x-filename", zipfilename);
                            httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                            httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                            httpResponseMessage.Content.Headers.ContentDisposition.FileName = zipfilename;
                            httpResponseMessage.StatusCode = HttpStatusCode.OK;
                            return httpResponseMessage;
                        }
                    }

     }

 

2) in my provider.ts, I have a function createReportsManagement which posts to the API controller code above:

public createReportsManagement(updatetype: string, reportsManagementObj: any) {
        reportsManagementObj.actiontype = updatetype;
        var headers = new Headers();
        headers.append('Content-Type', 'application/json');
        var objectToSend = JSON.stringify(reportsManagementObj);
        let apiURL = this.framework_virtual_path + "api/ReportsManagement";
        return this.http_request.post(apiURL, objectToSend, { headers: headers })
            .map(response => response.text())
            .catch(this.handleError);

}

3) On my html page, I have a component which calls  the provider to create the report zip file.

  This is where I am trying to use the KendoUI file-saver method saveAs() to popup the File Save dialog:

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

 

private btnExcelClick() {
        this.reportsLoading = true;
        var responseType = 'arraybuffer';

        this.myProvider.createReportsManagement("createReport", this.reportsMgmtObj)
            .subscribe(
            (response: any) => {

                //question !!! is "data:text/plain" OK for zip file content?
                const dataURI = "data:text/plain;base64," + encodeBase64(response);
                saveAs(dataURI, "test.zip");

                //this test code works and downloads the file test.txt
                //const dataURI = "data:text/plain;base64," + encodeBase64("HELLO TEST");
                //saveAs(dataURI, "test.txt");

            } );

}

Thanks for any pointer!

 

6 Answers, 1 is accepted

Sort by
0
Svet
Telerik team
answered on 17 May 2018, 10:46 AM
Hi Chau,

encodeBase64 accepts only one parameter of type string. Make sure that the response is of type string.

Also, the first parameter of the saveAs method could be of type Blob (even though this is not documented). Thus, something like the following could do the trick:

const blob = new Blob(response);
saveAs(blob, "test.zip");

I hope this helps. Let me know in case further assistance is required for this case.

Regards,
Svetlin
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Chau
Top achievements
Rank 1
answered on 17 May 2018, 02:25 PM

Hi Svetlin,

I got a compile error:  argument of type Blob cannot be assigned to string (see attached png).

I just installed npm -install --save @progress/kendo-file-saver

Is there anything else I need to install?

0
Svet
Telerik team
answered on 21 May 2018, 10:13 AM
Hi Chau,

Thank you for the screenshot.

I implemented the following example demonstrating the functionality of the saveAs method when we pass a blob object to it:

https://plnkr.co/edit/pZX98Z0qLsnvT6Q1GKld?p=preview

The important part is the following:

save(){
  this.pdf.export().then((group)=>{
    exportPDF(group).then((res)=>{
      console.log(res)
      let blob = this.dataURItoBlob(res);
      console.log(blob)
      saveAs(blob, 'myPDF.pdf')
    })
  })
}

In the example, I am using the custom dataURItoBlob method, to convert the dataUri to a Blob object, suggested in the following StackOverflow question:

https://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata

The saveAs method functions as expected and saves the file.

If there are some compilation errors as the one described we could try to avoid them by casting the blob to string as follows:

saveAs(<string>blob, 'myPDF.pdf')

I hope this helps.

Regards,
Svetlin
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Manuel
Top achievements
Rank 1
answered on 24 May 2018, 10:43 PM

Hi Svetlin.

 

I am struggeling with the same issue as Chau.

I am getting the compile error that saveAs does not accept a blob - it awaits a string: " Argument of type 'Blob' is not assignable to parameter of type 'string'.".

Casting the blob to a string as you have shown <string> does not work: "Type Blob cannot be converted to type string."

My szenario is a little bit different as I am not using the exportPDF but I guess the principle should be the same:

                                this.fileService.downloadFile(fileId)
                                    .subscribe(res => {
                                         console.log(res);
                                        const dataURI = "data:application/pdf;base64," + encodeBase64(res.body);
                                        console.log(dataURI);
                                        let blob = this.dataURItoBlob(dataURI);
                                        console.log(blob);
                                       //saveAs(blob, filename); --> does not work and shows the errors above
})

Any help would be great. Thanks.

 

 

 

0
Svet
Telerik team
answered on 28 May 2018, 10:44 AM
Hi,

The saveAs method can now accept string or Blob type for its data parameter. The update is available in the latest dev version 1.0.6 of the File Saver:

https://www.telerik.com/kendo-angular-ui-develop/components/filesaver/changelog/

Please note that it will take some time for the update to pass all internal checks before the version is officially released.

Regards,
Svetlin
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Manuel
Top achievements
Rank 1
answered on 28 May 2018, 04:06 PM

Hi Svetlin,

That was the missing link. So thanks for the brand new and freshly baked update.

And now it actually works :-)

Best regards

Manuel

Tags
General Discussions
Asked by
Chau
Top achievements
Rank 1
Answers by
Svet
Telerik team
Chau
Top achievements
Rank 1
Manuel
Top achievements
Rank 1
Share this question
or