I want to implement file download using this Angular 6 code:
Rest API:
private static final Logger LOG = LoggerFactory.getLogger(DownloadsController.class);
private static final String EXTERNAL_FILE_PATH = "/Users/test/Documents/blacklist_api.pdf";
@GetMapping("export")
public ResponseEntity<FileInputStream> export() throws IOException {
File pdfFile = Paths.get(EXTERNAL_FILE_PATH).toFile();
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity.ok().headers(headers).contentLength(pdfFile.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(new FileInputStream(pdfFile));
}
Service:
import {Injectable} from '@angular/core';
import {HttpClient, HttpParams} from "@angular/common/http";
import {Observable} from "rxjs/index";
import {environment} from "../../../environments/environment";
import {HttpUtils} from "../common/http-utils";
import { map } from 'rxjs/operators';
import {Http, ResponseContentType} from '@angular/http';
@Injectable({
providedIn: 'root'
})
export class DownloadService {
constructor(private http: HttpClient) {
}
downloadPDF(): any {
return this.http.get(environment.api.urls.downloads.getPdf, {
responseType: 'blob'
})
.pipe(
map((res: any) => {
return new Blob([res.blob()], {
type: 'application/pdf'
})
})
);
}
}
Component:
import {Component, OnInit} from '@angular/core';
import {DownloadService} from "../service/download.service";
import {ActivatedRoute, Router} from "@angular/router";
import {flatMap} from "rxjs/internal/operators";
import {of} from "rxjs/index";
import { map } from 'rxjs/operators';
@Component({
selector: 'app-download',
templateUrl: './download.component.html',
styleUrls: ['./download.component.scss']
})
export class DownloadComponent implements OnInit {
constructor(private downloadService: DownloadService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
}
export() {
this.downloadService.downloadPDF().subscribe(res => {
const fileURL = URL.createObjectURL(res);
window.open(fileURL, '_blank');
});
}
}
The file is present in the directory but when I try to download it I get error:
18:35:25,032 WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (default task-2) Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
Do you know how I can fix this issue? Do I need to add additional configuration in order to download the file via Angular web UI?
I use spring-boot-starter-parent version 2.1.0.RELEASE
FileSaver npmjs.com/package/ngx-filesaver is the best library for file download in Angular6 but it has various issues in ios devices. We fixed it by writing own methods and conditionally handling it .
Component
download() {
this.downloadService.downloadPDF().subscribe(async (res: Blob) => {
if (this.isIOSMobileDevice) {
const file = new File([res], fileName, { type: 'application/pdf' });
const dataStringURL: any = await this.fileService.readFile(file);
this.hrefLink = this.sanitizer.bypassSecurityTrustUrl(dataStringURL);
} else {
saveFile(res, fileName);
}
});
}
export const saveFile = (blobContent: Blob, fileName) => {
const isIOS = (!!navigator.platform.match(/iPhone|iPod|iPad/)) || (navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2);
const blob = new Blob([blobContent], { type: 'application/pdf' });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
document.body.appendChild(link);
link.href = url;
link.target = '_self';
link.download = fileName;
link.click();
document.body.removeChild(link);
}
};
File Service
async readFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
HTML code
<a *ngIf="isIOSMobileDevice" [href]="hrefLink"
target="_blank">Download</a>
<a *ngIf="!isIOSMobileDevice" href="javascript:;" (click)="download"
target="_blank">Download</a>
For ios Mobile devices ,download method has to be called in prerequisite so that we get hrefLink.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With