I am trying to download file but it is opening in new tab, but here I want to download file directly.
What I have tried
<a href={api_Url+'/SurveyImages/'+link} target = "_blank" download ={link}>{link}</a>
if I remove target = "_blank" then it replacing the file with my application tab.
How can I directly download it?
your code:
target = "_blank"
solution:
target = "_self"
Best solution as per new chrome specification https://developers.google.com/web/updates/2018/02/chrome-65-deprecations
Convert this code in React.
Vanilla JavaScript
public static downloadFile(url: string): void {
const xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = () => {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
const blobUrl = window.URL.createObjectURL(xmlHttp.response);
const e = document.createElement('a');
e.href = blobUrl;
e.download = blobUrl.substr(blobUrl.lastIndexOf('/') + 1);
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
};
xmlHttp.responseType = 'blob';
xmlHttp.open('GET', url, true);
xmlHttp.send(null);
}
If you're using angular try this.
async downloadBrochure(url: string) {
try {
const res = await this.httpClient.get(url, { responseType: 'blob' }).toPromise();
this.downloadFile(res);
} catch (e) {
console.log(e.body.message);
}
}
downloadFile(data) {
const url = window.URL.createObjectURL(data);
const e = document.createElement('a');
e.href = url;
e.download = url.substr(url.lastIndexOf('/') + 1);
document.body.appendChild(e);
e.click();
document.body.removeChild(e);
}
Click to download
This is not supported on all browsers: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a tags.
Try this:
axios({
url: 'http://localhost:5000/static/example.pdf',
method: 'GET',
responseType: 'blob', // important
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf');
document.body.appendChild(link);
link.click();
});
Reference: https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
You can try "HTML download Attribute"
https://www.w3schools.com/tags/att_a_download.asp
Download
Related
I have tested the API in Postman and the PDF renders fine. So I know the API is working correctly.
When I fetch the PDF from within my React code Adobe gives me the error: "Adobe Acrobat cannot open the because it is neither a supported file type or because the file has been damaged"
My React code:
const downloadFile = async uploadId => {
const response = await callFetch("/uploads/download/" + uploadId + "?officerId=" + officerId, "GET", "");
if (response.status === 401 || response.status === 403) {
alert("Error " + response.status);
sessionStorage.clear();
return;
}
const file = response.blob();
const url = URL.createObjectURL(
new Blob([file], {type:"application/pdf"})
);
const link = document.createElement('a');
link.href = url;
link.setAttribute(
'download',
`FileName.pdf`,
);
// Append to html link element page
document.body.appendChild(link);
// Start download
link.click();
// Clean up and remove the link
link.parentNode.removeChild(link);
URL.revokeObjectURL(url);
};
const callFetch = (endpoint, method, jsonStr) => {
let myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Accept","application/json");
return callFetchApi(endpoint, method, jsonStr, myHeaders);
};
const callFetchApi = (endpoint, method, data, myHeaders) => {
const serverName = "http://localhost:8080/AuxPolice/api";
myHeaders.append("Access-Control-Allow-Credentials", 'true');
myHeaders.append("Access-Control-Allow-Origin", '*');
const jwt = sessionStorage.getItem("jwt");
let headerJwt = "Bearer " + jwt;
if (jwt != null) {
myHeaders.append("Authorization", headerJwt);
}
let myInit = {method: method
,headers: myHeaders
};
let url = serverName + endpoint;
if (data) {
myInit.body = data;
}
let returnFetch = fetch(url, myInit);
return returnFetch;
};
Here is my Java code:
#GetMapping(value = "/download" + "/{id}")
public ResponseEntity<Resource> downloadGet(#PathVariable Long id, #RequestParam Long officerId) throws SQLException
{
Officer loggedInOfficer = this.auxPoliceService.getOfficer(officerId);
Upload paramRec = new Upload();
paramRec.setUploadId(id);
Upload download = auxPoliceService.getUploads(loggedInOfficer.getOfficerId(), paramRec).get(0);
Blob blob = download.getBlob();
byte [] bytes = blob.getBytes(1, (int)blob.length());
blob.free();
InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
String filename = download.getFilename();
String contentType = "application/pdf; name=\"" + filename() + "\"";
HttpHeaders headers = new HttpHeaders();
headers.set("content-disposition", "inline; filename=" + filename);
return ResponseEntity.ok()
.headers(headers)
.contentLength(bytes.length)
.contentType(MediaType.parseMediaType(contentType))
.body(resource);
}
Any ideas?
I have a question about react. I need to download a file from the uploads/doc folder.
I've written my code, but it downloads an empty file. Could you give me a hint on how to fix this issue? Thank you so much!
if (result.isConfirmed) {
//console.log("error while downloading document: ");
await getDocfile(_id);
fetch('http://localhost:4200/uploads/docs')
.then(response => {
response.blob().then(blob => {
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = document_name + '.pdf';
a.click();
});
});
}
Thanks in advance for taking a look. I am working on being able to download a zip file from react through a django api request. I am able to click on my pop up that downloads the zip file, but when I double click on the zip file to open, I get this error: "Unable to expand file_name.zip. It is an unsupported format" My response with the zip file seems to be passing correctly to the front end, so I am thinking it may be something wrong with the react code when making the "blob"? Thanks again.
Django code:
class DownloadZip(APIView):
def post(self, request, format=None):
# information to find file to create zip
profile_name = request.data["profile"]
profile_year = request.data["year"]
# file path to create zips from
path = str(Path(__file__).parent.resolve())
zip_dir = shutil.make_archive(profile_name + profile_year, "zip", path + "/" + profile_name + profile_year)
s = io.StringIO(zip_dir)
response = HttpResponse(s, content_type = "application/zip")
zip_name = profile_name + profile_year + ".zip"
response["Content-Disposition"] = f"attachment; filename={zip_name}"
return response
React code:
downloadZip = async () => {
const params = {
profile: this.state.profileName,
year: this.state.year,
};
axios({
url: `${serverUrl}/download_zip`,
method: "post",
data: params
}).then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data],{type:'application/zip'}));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip');
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
(error) => {
console.log(error);
});
}
I did do a fellow commentor's suggestion, and updated to get route with query params, but am having the same issue. I can double click on the zip link on the web browser but a pop up appears "Unable to expand filename.zip. It is an unsupported format"
Please try adding {responseType: 'arraybuffer'}. I also had the same problem but after adding this {responseType: 'arraybuffer'}. I am getting correct file.
downloadZip = async () => {
const params = {
profile: this.state.profileName,
year: this.state.year,
};
axios.post(
`${serverUrl}/download_zip`,
params,
{
responseType: 'arraybuffer'
}
).then(
(res) => {
const url = window.URL.createObjectURL(new Blob([res.data],{type:'application/zip'}));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip');
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
(error) => {
console.log(error);
});
}
I want to, when i click on button (separate for both CSV and PDF), it automatically download in CSV and PDF file with correct Formatting.
this CSV code i want to add PDF inside code
$scope.downloadData = function() {
var datasets = $scope.datasets.reverse();
var file_name = $scope.m_id+ '.csv';
var dataUrl = 'data:text/csv;charset=utf-8,';
var json = [];
if(datasets !== null) {
for(idx = 0; idx < datasets.length; idx++) {
var dataset = datasets[idx].data;
var time = datasets[idx].timestamp;
time = $filter('date')(time, "dd/MMMM/yyyy-hh:mm a");
dataset.time = time;
json.push(dataset);
}
var fields = Object.keys(json[0]);
var csv = json.map(
function(row) {
return fields.map(
function(fieldName) {
return '"' + (row[fieldName] || '') + '"';
}
);
}
);
csv.unshift(fields);
var csv_str = csv.join('%0A');
var downloadURL = dataUrl + csv_str;
var saveAs = function(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
document.body.appendChild(link); // Firefox requires the link to be in the body
link.download = filename;
link.href = uri;
link.target = "_blank";
link.click();
document.body.removeChild(link); // remove the link when done
} else {
location.replace(uri);
}
};
saveAs(downloadURL, file_name);
} else {
$scope.err_msg = 'Failed to get data. Try reloading the page.';
}
};
I try some of script i found on internet, but it is not working, some have formatting issue and save have downloading.
In Advance Thanks.
You should use this awesome library for pdf/csv or whatever else formats.. File Saver
Here's is code example, service created using FileSaver
function download(api, file, contentType) {
var d = $q.defer();
$http({
method: 'GET',
url: api,
responseType: 'arraybuffer',
headers: {
'Content-type': contentType
}
}).success(function(response) {
var data = new Blob([response], {
type: contentType+ ';charset=utf-8'
});
FileSaver.saveAs(data, file);
d.resolve(response);
}).error(function(response) {
d.reject(response);
});
return d.promise;
}
file input is name of file, you can use same service and pass the types and file names direct from controller.
Let;s you service name is homeService
for pdf call
homeservice.download('/api/download/whaever', 'export.pdf', 'application/pdf')
I have a complex object parameter that I need to send as post, as it could be too long for querystring. The post call is asking to have an excel file dynamically generated and then downloaded asynchronously. But all of this is happening inside of a react application. How does one do this using axios.post, react, and webapi? I have confirmed that the file does generate and the download up to the response does come back, but I'm not sure how to actually open the file. I have a hidden iframe that I'm trying to set the path, src, of the file to, but I dont know what response property to use.
// webapi
[HttpPost]
public HttpResponseMessage Post([FromBody]ExcelExportModel pModel)
{
var lFile = ProductDataModel.GetHoldingsExport(pModel);
var lResult = new HttpResponseMessage(HttpStatusCode.OK);
lResult.Content = new ByteArrayContent(lFile);
lResult.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "HoldingsGridExport.xls"
};
lResult.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return lResult;
}
// client side api
static getHoldingsExport({ UserConfigurationID, UserID, Configurations, ViewName, SortModel, FilterModel, UserConfigType, IsDefault, LastPortfolioSearchID = null, ProductId }) {
const filterModel = JSON.stringify(FilterModel); // saving as string as this model is dynamically generated by grid out of my control
const sortModel = JSON.stringify(SortModel);
let params = JSON.stringify({
UserConfigurationID,
UserID,
Configurations,
ViewName,
filterModel,
sortModel,
UserConfigType,
IsDefault,
LastPortfolioSearchID,
ProductId
});
return axiosInstance.post("/api/HoldingsExport", params);
}
// client side app call to get file
HoldingsApi.getHoldingsExport(config)
.then(function(response) {
debugger;
let test = response;
})
.catch(error => {
toastr.success('Failed to get export.');
});
This is how I've achieved file downloads by POSTing via Axios:
Axios.post("YOUR API URI", {
// include your additional POSTed data here
responseType: "blob"
}).then((response) => {
let blob = new Blob([response.data], { type: extractContentType(response) }),
downloadUrl = window.URL.createObjectURL(blob),
filename = "",
disposition = response.headers["content-disposition"];
if (disposition && disposition.indexOf("attachment") !== -1) {
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,
matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, "");
}
}
let a = document.createElement("a");
if (typeof a.download === "undefined") {
window.location.href = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
}).catch((error) => {
// ...
});
Just in case the above solution does not serve you quite well, here is how I could be able to download videos that are hosted on S3 AWS buckets,
const handleDownload = () => {
const link = document.createElement("a");
link.target = "_blank";
link.download = "YOUR_FILE_NAME"
axios
.get(url, {
responseType: "blob",
})
.then((res) => {
link.href = URL.createObjectURL(
new Blob([res.data], { type: "video/mp4" })
);
link.click();
});
};
And I trigger handleDownload function in a button with onClick.
The url in the function has the video URL from S3 buckets