// The download resource
@GET
@Path("/exportCSV")
Response exportCSV();
@Override
public Response exportCSV() throws IOException {
ResponseBuilder builder = Response.ok();
builder.entity(tallySheetApi.exportCSV(httpServletResponse));
return builder.build();
}
public void exportCSV(HttpServletResponse response) throws IOException {
// write result to csv file
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
response.setContentType("text/csv");
response.addHeader("Content-disposition", "attachment;filename=\"animes.csv\"");
writeToCSV(response.getOutputStream(), listValuesHere);
response.flushBuffer();
}
private void writeToCSV(ServletOutputStream servletOutputStream, List<Anime> animes) throws IOException {
Writer writer = new BufferedWriter(new OutputStreamWriter(servletOutputStream));
for (Anime anime : animes) {
writer.write(anime.getTitle());
writer.write(CSV_DELIMITER);
writer.write(anime.getReleaseDate());
writer.write(CSV_DELIMITER);
writer.write(anime.getRating());
writer.write(System.getProperty("line.separator"));
}
writer.close();
}
exportCSV() {
window.location.href = this.apiUrl + this.RESOURCE_URL + '/exportCSV';
}
public class ByteDto {In this approach, we save the byte array in a DTO instead of writing it in the outputStream. Note that we needed to encode the byte array as Base64, otherwise we will have a problem during deserialization. It also requires some additional work on the Angular side.
private String fileContent;
public String getFileContent() {
return fileContent;
}
public void setFileContent(String fileContent) {
this.fileContent = fileContent;
}
}
// The download resource
@GET
@Path("/exportCSV")
Response exportCSV();
@Override
public Response exportCSV() throws IOException {
ResponseBuilder builder = Response.ok();
builder.entity(tallySheetApi.exportCSV());
return builder.build();
}
public ByteDto exportCSV() throws IOException {
ByteArrayOutputStream baos = writeToCSV(listValuesHere);
ByteDto byteDto = new ByteDto();
byteDto.setFileContent(Base64.getEncoder().withoutPadding().encodeToString(baos.toByteArray()));
return byteDto;
}
private ByteArrayOutputStream writeToCSV(List<Anime> animes) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer writer = new BufferedWriter(new OutputStreamWriter(baos));
for (Anime anime : animes) {
writer.write(anime.getTitle());
writer.write(CSV_DELIMITER);
writer.write(anime.getReleaseDate());
writer.write(CSV_DELIMITER);
writer.write(anime.getRating());
writer.write(System.getProperty("line.separator"));
}
writer.close();
return baos;
}
exportCSV() {In this version we needed to decode the byte array from the response and use the msSaveOrOpenBlob method from windows.navigator object. We also need to create a tag on the fly to invoke the download.
this.http.get<any>( this.apiUrl + this.RESOURCE_URL + '/exportCSV', { params: this.params } ).subscribe( data => {
console.log( 'downloaded data=' + data.fileContent )
var blob = new Blob( [atob( data.fileContent )], { type: 'text/csv' } )
let filename = 'animes.csv'
if ( window.navigator && window.navigator.msSaveOrOpenBlob ) {
window.navigator.msSaveOrOpenBlob( blob, filename )
} else {
var a = document.createElement( 'a' )
a.href = URL.createObjectURL( blob )
a.download = filename
document.body.appendChild( a )
a.click()
document.body.removeChild( a )
}
} )
}