Unable to download image as zip file using angular 6
here i am having below dynamic data like this
data = [
"https://dummyimage.com/200x200/000/fff.jpg&text=test",
"https://dummyimage.com/200x200/000/fff.jpg&text=testOne",
"https://dummyimage.com/200x200/000/fff.png&text=testTwo"
]
on button click i want to get the all the images from those url's and save it as zip
Issue : when ever i am able download the file as zip and try to extract it i am getting error as could not open image.zip as archieve and if i save as single image also the image is not opening up and is there any way to store the
below is my code
downloadImageData(){
var blob = new Blob([this.data], { type: 'application/zip'' });
FileSaver.saveAs(blob,'image.zip');
}
here i am having both png & jpg and various type of data so what ever data the links will get has to downloaded as zip file is there any approach for angular 5+. i am using filesave angular package also
JS ZIP _body resp
By using the http module im getting the below data [
{
"_body": {
},
"status": 200,
"ok": true,
"statusText": "OK",
"headers": {
"date": [
"Sun",
" 25 Nov 2018 12:18:47 GMT"
],
"cache-control": [
"public",
" max-age=43200"
],
"expires": [
"Mon",
" 26 Nov 2018 00:18:47 GMT"
],
"content-disposition": [
"attachment; filename=2B.JPG"
],
"content-length": [
"40649"
],
"server": [
"Werkzeug/0.14.1 Python/2.7.13"
],
"content-type": [
"image/jpg"
]
},
"type": 2,
"url": "http://some url"
}
]
javascript angular typescript
|
show 1 more comment
here i am having below dynamic data like this
data = [
"https://dummyimage.com/200x200/000/fff.jpg&text=test",
"https://dummyimage.com/200x200/000/fff.jpg&text=testOne",
"https://dummyimage.com/200x200/000/fff.png&text=testTwo"
]
on button click i want to get the all the images from those url's and save it as zip
Issue : when ever i am able download the file as zip and try to extract it i am getting error as could not open image.zip as archieve and if i save as single image also the image is not opening up and is there any way to store the
below is my code
downloadImageData(){
var blob = new Blob([this.data], { type: 'application/zip'' });
FileSaver.saveAs(blob,'image.zip');
}
here i am having both png & jpg and various type of data so what ever data the links will get has to downloaded as zip file is there any approach for angular 5+. i am using filesave angular package also
JS ZIP _body resp
By using the http module im getting the below data [
{
"_body": {
},
"status": 200,
"ok": true,
"statusText": "OK",
"headers": {
"date": [
"Sun",
" 25 Nov 2018 12:18:47 GMT"
],
"cache-control": [
"public",
" max-age=43200"
],
"expires": [
"Mon",
" 26 Nov 2018 00:18:47 GMT"
],
"content-disposition": [
"attachment; filename=2B.JPG"
],
"content-length": [
"40649"
],
"server": [
"Werkzeug/0.14.1 Python/2.7.13"
],
"content-type": [
"image/jpg"
]
},
"type": 2,
"url": "http://some url"
}
]
javascript angular typescript
You have 3'
in'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one
– ams
Nov 22 '18 at 18:15
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
1
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49
|
show 1 more comment
here i am having below dynamic data like this
data = [
"https://dummyimage.com/200x200/000/fff.jpg&text=test",
"https://dummyimage.com/200x200/000/fff.jpg&text=testOne",
"https://dummyimage.com/200x200/000/fff.png&text=testTwo"
]
on button click i want to get the all the images from those url's and save it as zip
Issue : when ever i am able download the file as zip and try to extract it i am getting error as could not open image.zip as archieve and if i save as single image also the image is not opening up and is there any way to store the
below is my code
downloadImageData(){
var blob = new Blob([this.data], { type: 'application/zip'' });
FileSaver.saveAs(blob,'image.zip');
}
here i am having both png & jpg and various type of data so what ever data the links will get has to downloaded as zip file is there any approach for angular 5+. i am using filesave angular package also
JS ZIP _body resp
By using the http module im getting the below data [
{
"_body": {
},
"status": 200,
"ok": true,
"statusText": "OK",
"headers": {
"date": [
"Sun",
" 25 Nov 2018 12:18:47 GMT"
],
"cache-control": [
"public",
" max-age=43200"
],
"expires": [
"Mon",
" 26 Nov 2018 00:18:47 GMT"
],
"content-disposition": [
"attachment; filename=2B.JPG"
],
"content-length": [
"40649"
],
"server": [
"Werkzeug/0.14.1 Python/2.7.13"
],
"content-type": [
"image/jpg"
]
},
"type": 2,
"url": "http://some url"
}
]
javascript angular typescript
here i am having below dynamic data like this
data = [
"https://dummyimage.com/200x200/000/fff.jpg&text=test",
"https://dummyimage.com/200x200/000/fff.jpg&text=testOne",
"https://dummyimage.com/200x200/000/fff.png&text=testTwo"
]
on button click i want to get the all the images from those url's and save it as zip
Issue : when ever i am able download the file as zip and try to extract it i am getting error as could not open image.zip as archieve and if i save as single image also the image is not opening up and is there any way to store the
below is my code
downloadImageData(){
var blob = new Blob([this.data], { type: 'application/zip'' });
FileSaver.saveAs(blob,'image.zip');
}
here i am having both png & jpg and various type of data so what ever data the links will get has to downloaded as zip file is there any approach for angular 5+. i am using filesave angular package also
JS ZIP _body resp
By using the http module im getting the below data [
{
"_body": {
},
"status": 200,
"ok": true,
"statusText": "OK",
"headers": {
"date": [
"Sun",
" 25 Nov 2018 12:18:47 GMT"
],
"cache-control": [
"public",
" max-age=43200"
],
"expires": [
"Mon",
" 26 Nov 2018 00:18:47 GMT"
],
"content-disposition": [
"attachment; filename=2B.JPG"
],
"content-length": [
"40649"
],
"server": [
"Werkzeug/0.14.1 Python/2.7.13"
],
"content-type": [
"image/jpg"
]
},
"type": 2,
"url": "http://some url"
}
]
javascript angular typescript
javascript angular typescript
edited Nov 25 '18 at 12:40
Madpop
asked Nov 20 '18 at 16:52
MadpopMadpop
1751423
1751423
You have 3'
in'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one
– ams
Nov 22 '18 at 18:15
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
1
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49
|
show 1 more comment
You have 3'
in'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one
– ams
Nov 22 '18 at 18:15
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
1
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49
You have 3
'
in 'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one– ams
Nov 22 '18 at 18:15
You have 3
'
in 'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one– ams
Nov 22 '18 at 18:15
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
1
1
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49
|
show 1 more comment
2 Answers
2
active
oldest
votes
I'm a little late, but this code will use your image array and create your GET requests. After that it will perform all requests and the responses will be added to your zip file and then downloaded.
I included two ways to download the file if you don't like to use the fileSaver. Pick whichever you prefer.
EDIT:
If you are using an old version of rxjs you'll have to import forkJoin
in a different way, consult the rxjs documentation.
Also be sure that your backend allows the download of files, otherwise you'll have CORS errors.
forkJoin Documentation
app.component.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = ;
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
I also had to include the path to jszip in my tsconfig.json. Depending on your version of angular you don't have to do this. Inside "compilerOptions"
add following:
tsconfig.json
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
UPDATE:
Here is a solution with the old HttpModule, I tried it out and it works. I would suggest changing to the new HttpClientModule if possible.
UPDATE2:
Like I said in the comments, you can change the file extension when saving the file to handle different file types. This is an example and you can easily expand this solution.
app.component.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = ;
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
UPDATE3:
Solution which extracts the file name from the URL, this way the file type is not needed:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = ;
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Insidedownload()
.createGetRequest
will create your requests from your image array and push them insidegetRequests
. This array will then be passed toforkJoin()
.forkJoin
will perform your requests, it works similar toPromise.all()
.
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
|
show 11 more comments
I have created a demo application here.
P.S: The code is for guidance only, and may not include standard coding practices but may guide you to create your own version of the solution.
I'm using jszip to zip file.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@NgModule({
imports: [ BrowserModule, HttpClientModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts:
import { OnInit, Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@Component({
selector: 'my-app',
template: `<button (click)='downloadZip()'>Download</button>`
})
export class AppComponent {
constructor(private http: HttpClient) {
}
downloadZip() {
this.loadSvgData("https://c.staticblitz.com/assets/client/icons/file-icons/angular-component-31179578a9a8a16512e9e90ade26549a.svg",
this.saveAsZip);
}
private loadSvgData(url: string, callback: Function) : void{
this.http.get(url, { responseType: "arraybuffer" })
.subscribe(x => callback(x));
}
private saveAsZip(content: Blob) : void{
var zip = new JSZip.default();
zip.file("image.svg", content);
zip.generateAsync({ type: "blob" })
.then(blob => saveAs(blob,'image.zip'));
};
}
Explanation:
The application only has one button, which on click will download an image file from the server using HttpClient
. It will zip downloaded data using jszip
and save it to browser using file-saver
.
I hope this helps!
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397818%2funable-to-download-image-as-zip-file-using-angular-6%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'm a little late, but this code will use your image array and create your GET requests. After that it will perform all requests and the responses will be added to your zip file and then downloaded.
I included two ways to download the file if you don't like to use the fileSaver. Pick whichever you prefer.
EDIT:
If you are using an old version of rxjs you'll have to import forkJoin
in a different way, consult the rxjs documentation.
Also be sure that your backend allows the download of files, otherwise you'll have CORS errors.
forkJoin Documentation
app.component.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = ;
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
I also had to include the path to jszip in my tsconfig.json. Depending on your version of angular you don't have to do this. Inside "compilerOptions"
add following:
tsconfig.json
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
UPDATE:
Here is a solution with the old HttpModule, I tried it out and it works. I would suggest changing to the new HttpClientModule if possible.
UPDATE2:
Like I said in the comments, you can change the file extension when saving the file to handle different file types. This is an example and you can easily expand this solution.
app.component.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = ;
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
UPDATE3:
Solution which extracts the file name from the URL, this way the file type is not needed:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = ;
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Insidedownload()
.createGetRequest
will create your requests from your image array and push them insidegetRequests
. This array will then be passed toforkJoin()
.forkJoin
will perform your requests, it works similar toPromise.all()
.
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
|
show 11 more comments
I'm a little late, but this code will use your image array and create your GET requests. After that it will perform all requests and the responses will be added to your zip file and then downloaded.
I included two ways to download the file if you don't like to use the fileSaver. Pick whichever you prefer.
EDIT:
If you are using an old version of rxjs you'll have to import forkJoin
in a different way, consult the rxjs documentation.
Also be sure that your backend allows the download of files, otherwise you'll have CORS errors.
forkJoin Documentation
app.component.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = ;
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
I also had to include the path to jszip in my tsconfig.json. Depending on your version of angular you don't have to do this. Inside "compilerOptions"
add following:
tsconfig.json
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
UPDATE:
Here is a solution with the old HttpModule, I tried it out and it works. I would suggest changing to the new HttpClientModule if possible.
UPDATE2:
Like I said in the comments, you can change the file extension when saving the file to handle different file types. This is an example and you can easily expand this solution.
app.component.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = ;
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
UPDATE3:
Solution which extracts the file name from the URL, this way the file type is not needed:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = ;
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Insidedownload()
.createGetRequest
will create your requests from your image array and push them insidegetRequests
. This array will then be passed toforkJoin()
.forkJoin
will perform your requests, it works similar toPromise.all()
.
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
|
show 11 more comments
I'm a little late, but this code will use your image array and create your GET requests. After that it will perform all requests and the responses will be added to your zip file and then downloaded.
I included two ways to download the file if you don't like to use the fileSaver. Pick whichever you prefer.
EDIT:
If you are using an old version of rxjs you'll have to import forkJoin
in a different way, consult the rxjs documentation.
Also be sure that your backend allows the download of files, otherwise you'll have CORS errors.
forkJoin Documentation
app.component.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = ;
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
I also had to include the path to jszip in my tsconfig.json. Depending on your version of angular you don't have to do this. Inside "compilerOptions"
add following:
tsconfig.json
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
UPDATE:
Here is a solution with the old HttpModule, I tried it out and it works. I would suggest changing to the new HttpClientModule if possible.
UPDATE2:
Like I said in the comments, you can change the file extension when saving the file to handle different file types. This is an example and you can easily expand this solution.
app.component.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = ;
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
UPDATE3:
Solution which extracts the file name from the URL, this way the file type is not needed:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = ;
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
I'm a little late, but this code will use your image array and create your GET requests. After that it will perform all requests and the responses will be added to your zip file and then downloaded.
I included two ways to download the file if you don't like to use the fileSaver. Pick whichever you prefer.
EDIT:
If you are using an old version of rxjs you'll have to import forkJoin
in a different way, consult the rxjs documentation.
Also be sure that your backend allows the download of files, otherwise you'll have CORS errors.
forkJoin Documentation
app.component.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = ;
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
I also had to include the path to jszip in my tsconfig.json. Depending on your version of angular you don't have to do this. Inside "compilerOptions"
add following:
tsconfig.json
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
UPDATE:
Here is a solution with the old HttpModule, I tried it out and it works. I would suggest changing to the new HttpClientModule if possible.
UPDATE2:
Like I said in the comments, you can change the file extension when saving the file to handle different file types. This is an example and you can easily expand this solution.
app.component.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = ;
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
UPDATE3:
Solution which extracts the file name from the URL, this way the file type is not needed:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = ;
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
edited Nov 26 '18 at 10:39
answered Nov 23 '18 at 17:45
amsams
2187
2187
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Insidedownload()
.createGetRequest
will create your requests from your image array and push them insidegetRequests
. This array will then be passed toforkJoin()
.forkJoin
will perform your requests, it works similar toPromise.all()
.
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
|
show 11 more comments
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Insidedownload()
.createGetRequest
will create your requests from your image array and push them insidegetRequests
. This array will then be passed toforkJoin()
.forkJoin
will perform your requests, it works similar toPromise.all()
.
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
can we use using http request bcoz my existing project already using http request so if I put http client module then it will give error I think right
– Madpop
Nov 23 '18 at 17:53
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Inside
download()
. createGetRequest
will create your requests from your image array and push them inside getRequests
. This array will then be passed to forkJoin()
. forkJoin
will perform your requests, it works similar to Promise.all()
.– ams
Nov 23 '18 at 17:54
@Madpop I'm sorry I don't understand what you mean, can you be a little more specific? Inside
download()
. createGetRequest
will create your requests from your image array and push them inside getRequests
. This array will then be passed to forkJoin()
. forkJoin
will perform your requests, it works similar to Promise.all()
.– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
@Madpop Give me a second I'll try it out
– ams
Nov 23 '18 at 17:54
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
ok http module I'm using so if I put http client module then both will have conflict
– Madpop
Nov 23 '18 at 18:26
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
@Madpop Yes, you shouldn't use both, choose one. The old HttpModule is deprecated, that's why I suggested to use the new HttpClientModule. Did my solution work for you?
– ams
Nov 23 '18 at 20:42
|
show 11 more comments
I have created a demo application here.
P.S: The code is for guidance only, and may not include standard coding practices but may guide you to create your own version of the solution.
I'm using jszip to zip file.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@NgModule({
imports: [ BrowserModule, HttpClientModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts:
import { OnInit, Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@Component({
selector: 'my-app',
template: `<button (click)='downloadZip()'>Download</button>`
})
export class AppComponent {
constructor(private http: HttpClient) {
}
downloadZip() {
this.loadSvgData("https://c.staticblitz.com/assets/client/icons/file-icons/angular-component-31179578a9a8a16512e9e90ade26549a.svg",
this.saveAsZip);
}
private loadSvgData(url: string, callback: Function) : void{
this.http.get(url, { responseType: "arraybuffer" })
.subscribe(x => callback(x));
}
private saveAsZip(content: Blob) : void{
var zip = new JSZip.default();
zip.file("image.svg", content);
zip.generateAsync({ type: "blob" })
.then(blob => saveAs(blob,'image.zip'));
};
}
Explanation:
The application only has one button, which on click will download an image file from the server using HttpClient
. It will zip downloaded data using jszip
and save it to browser using file-saver
.
I hope this helps!
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
add a comment |
I have created a demo application here.
P.S: The code is for guidance only, and may not include standard coding practices but may guide you to create your own version of the solution.
I'm using jszip to zip file.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@NgModule({
imports: [ BrowserModule, HttpClientModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts:
import { OnInit, Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@Component({
selector: 'my-app',
template: `<button (click)='downloadZip()'>Download</button>`
})
export class AppComponent {
constructor(private http: HttpClient) {
}
downloadZip() {
this.loadSvgData("https://c.staticblitz.com/assets/client/icons/file-icons/angular-component-31179578a9a8a16512e9e90ade26549a.svg",
this.saveAsZip);
}
private loadSvgData(url: string, callback: Function) : void{
this.http.get(url, { responseType: "arraybuffer" })
.subscribe(x => callback(x));
}
private saveAsZip(content: Blob) : void{
var zip = new JSZip.default();
zip.file("image.svg", content);
zip.generateAsync({ type: "blob" })
.then(blob => saveAs(blob,'image.zip'));
};
}
Explanation:
The application only has one button, which on click will download an image file from the server using HttpClient
. It will zip downloaded data using jszip
and save it to browser using file-saver
.
I hope this helps!
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
add a comment |
I have created a demo application here.
P.S: The code is for guidance only, and may not include standard coding practices but may guide you to create your own version of the solution.
I'm using jszip to zip file.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@NgModule({
imports: [ BrowserModule, HttpClientModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts:
import { OnInit, Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@Component({
selector: 'my-app',
template: `<button (click)='downloadZip()'>Download</button>`
})
export class AppComponent {
constructor(private http: HttpClient) {
}
downloadZip() {
this.loadSvgData("https://c.staticblitz.com/assets/client/icons/file-icons/angular-component-31179578a9a8a16512e9e90ade26549a.svg",
this.saveAsZip);
}
private loadSvgData(url: string, callback: Function) : void{
this.http.get(url, { responseType: "arraybuffer" })
.subscribe(x => callback(x));
}
private saveAsZip(content: Blob) : void{
var zip = new JSZip.default();
zip.file("image.svg", content);
zip.generateAsync({ type: "blob" })
.then(blob => saveAs(blob,'image.zip'));
};
}
Explanation:
The application only has one button, which on click will download an image file from the server using HttpClient
. It will zip downloaded data using jszip
and save it to browser using file-saver
.
I hope this helps!
I have created a demo application here.
P.S: The code is for guidance only, and may not include standard coding practices but may guide you to create your own version of the solution.
I'm using jszip to zip file.
app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@NgModule({
imports: [ BrowserModule, HttpClientModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.ts:
import { OnInit, Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import * as JSZip from 'jszip';
import { saveAs } from 'file-saver';
@Component({
selector: 'my-app',
template: `<button (click)='downloadZip()'>Download</button>`
})
export class AppComponent {
constructor(private http: HttpClient) {
}
downloadZip() {
this.loadSvgData("https://c.staticblitz.com/assets/client/icons/file-icons/angular-component-31179578a9a8a16512e9e90ade26549a.svg",
this.saveAsZip);
}
private loadSvgData(url: string, callback: Function) : void{
this.http.get(url, { responseType: "arraybuffer" })
.subscribe(x => callback(x));
}
private saveAsZip(content: Blob) : void{
var zip = new JSZip.default();
zip.file("image.svg", content);
zip.generateAsync({ type: "blob" })
.then(blob => saveAs(blob,'image.zip'));
};
}
Explanation:
The application only has one button, which on click will download an image file from the server using HttpClient
. It will zip downloaded data using jszip
and save it to browser using file-saver
.
I hope this helps!
answered Nov 23 '18 at 6:21


Dipen ShahDipen Shah
7,17011429
7,17011429
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
add a comment |
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
can use http also instead of httpClient & i have a array of images ?
– Madpop
Nov 23 '18 at 6:28
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
in the code u mentioned zip.file("image.svg", content); say i dont know the conten type either jpg or png or text then ?
– Madpop
Nov 23 '18 at 6:32
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop You need to know name of the file, if not then you at-least need to parse url to determine extension of the file (technically, you can add the file without extension but then user will have to know editor which can open the file).
– Dipen Shah
Nov 23 '18 at 13:21
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
@Madpop, you can modify callback function so that it will wait for all files to be downloaded before zipping them. BTW, which version of angular are you using?
– Dipen Shah
Nov 23 '18 at 13:29
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397818%2funable-to-download-image-as-zip-file-using-angular-6%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You have 3
'
in'application/zip'
, maybe it's an error from copying, but if you have it in your code then you should remove one– ams
Nov 22 '18 at 18:15
@ams That's typo error in application I have 2 only verified that
– Madpop
Nov 22 '18 at 18:46
have you tried downloading the file without using FileSaver? For example with an a tag, I could provide an example if you want to.
– ams
Nov 22 '18 at 19:07
1
If this is all your code, the problem is, that you have to download the binary data first. You cannot simply add an array of URLs and make it magically be a zip file by providing a content type. In angular you'd use the HttpClient to download the files.
– Christoph Lütjen
Nov 22 '18 at 21:22
@ams no i tried only using that as i thought it makes things simple & sure u can provide a sample by using the above urls
– Madpop
Nov 23 '18 at 3:49