There are several posts discussing techniques for file downloads. We wanted to offer the following technique, mostly so the community can poke holes in it and improve it (!) and also in case it’s of value to anyone here.
Our solution is for a medical practice and file downloads contain protected health information. We were leary about using anything that requires files to be exposed on the public Internet, either through our server, or in S3, etc., or for files to be stored in a temp location on our server without total control over them. The data api method of getting a URL seems interesting but we wanted to wait until that’s more tested, and I believe it relies on temporarily storing files in a Public location.
So what we’re doing is this:
(1) An authenticated user clicks a button on a form and that fires a standard utility hook
(2) Inside the hook:
(a) Go to the user’s record, where we have the PDF file stored as a base64 string in a text field (Users::base64ofPDF). When you generate the base64 string, do this: Substitute(Base64Encode ( Users::containerOfPDF ); Char(13)&Char(10); “”).
(b) Insert text with target $function:
let data64 = ‘d64’;
let a = document.createElement(“a”);
a.href = “data:application/octet-stream;base64,”+data64;
a.download = “Results.pdf”
© Set variable $function
Substitute($function; “d64”; Users::base64ofPDF)
(d) Set variable $$BF_Actions
BF_SetAction_function ( $function )
That’s it - when the hook completes, the function will run and download a file “Results.pdf”. With a 1pg PDF, the script execution time is ~200ms. With a 20pg PDF, it’s 300-400ms but further testing is in order. PDFs shouldn’t contain large hi res graphics.
Very interested to know if anyone sees anything wrong with this or any way to improve?