Upload and Retrieve Image using SAP HANA XS & SAP UI5
Hello,
One of the most common use case in building XS based Native HANA Application is working with file uploads like image, csv etc.,
In this blog I will explain how to:
- Use SAPUI5 File Uploader to upload an image
- Render preview of the uploaded image
- Save it to HANA DB using a XSJS service.
- Retrieve the saved image using XSJS service and render it on the UI.
Please note this approach can be applied for any type of file. e.g .csv, xlsx etc.,
Upload an Image using SAPUI5 File Uploader:
Use SAP UI5 FileUploader control to upload the image.
Important thing to note in above code snippet is that ‘readAsDataURL’ method of reader has to be used if you are working with images. reader.readAsDataURL(oEvent.target.files.item(0));
In case if you are uploading a .csv file for processing, use ‘readAsText’. reader.readAsText(oEvent.target.files.item(0));
Render preview of the uploaded image:
Add an SAPUI5 image Control with an ‘ID’.
var oImagePreview = new sap.ui.commons.Image(“img_preview”);
Once the Image is uploaded using the File Uploader, the data would be available in ‘oEvent.target.result’. Using below code snippet, get the image element reference and set the data as source.
- document.getElementById(“img_preview”).src = oEvent.target.result;
If needed, add a css styleClass to the Image created with some width and height in px.
By now, you would be able to browse and select an image and also render preview of the selected image.
Save it to HANA DB using a XSJS service:
Create a table to store the image data.
CREATE COLUMN TABLE “RESOURCE_PLANNER”.“IMAGE_STORE” (“USERID” NVARCHAR(8) NOT NULL,
“AVATAR” NCLOB,
PRIMARY KEY (“USERID”)) UNLOAD PRIORITY 5 AUTO MERGE
In the UI, use below code to make an ajax call to save the image data.
/** Get Saved Image for entered User Id */
saveImage : function(imageData, fileType) {
// Get X-CSRF token
$.ajax({
url: “/sap/hana/xs/formLogin/token.xsjs”,
type: “GET”,
headers: {“X-CSRF-Token”: “Fetch”},
async: false,
success: function(incomingdata, textStatus, jqXHR) {
xcsrfToken = jqXHR.getResponseHeader(“X-CSRF-Token”);
$.ajax({
url: “/ResourcePlanner/Services/SaveImage.xsjs?USERID=I066096“,
type: “PUT”,
processData: false,
contentType: fileType,
data: imageData,
beforeSend:function(XMLHttpRequest){
XMLHttpRequest.setRequestHeader(“x-csrf-token”, xcsrfToken);
},
xhr: function() {
var req = $.ajaxSettings.xhr();
if (req) {
if (req.overrideMimeType) {
req.overrideMimeType(‘text/plain; charset=x-user-defined’);
}
if (req.sendAsBinary) {
req.send = req.sendAsBinary;
}
}
return req;
},
success: function(data, textStatus, XMLHttpRequest) {
console.log(“Image Saved”);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
console.error(“Image Save failed: “+XMLHttpRequest.responseText);
}
});
},
error: function(XMLHttpRequest, textStatus, errorThrown){
console.error(“Error in fetching xcsrfToken”);
}
});
},
SAVE XSJS:
Receive the data sent from UI in variable ‘data’ and insert it into our table ‘IMAGE_STORE’.
var conn = $.db.getConnection();
var userId = $.request.parameters.get(“USERID”);
var data = $.request.body.asString();
var pstmt = conn.prepareStatement(‘INSERT INTO “RESOURCE_PLANNER”.”IMAGE_STORE” (USERID, AVATAR) VALUES(?,?)’);
pstmt.setString(1, userId); // Just hardcoding an id. This can very well be part of the ajax post body or url
pstmt.setString(2, data);
pstmt.execute();
pstmt.close();
conn.commit();
conn.close();
$.response.contentType = ‘text/plain’;
$.response.setBody(‘Image uploaded successfully’);
$.response.status = $.net.http.OK;
Retrieve the saved image using XSJS service and render it on the UI:
RETRIEVE XSJS:
In the below example, I am just sending an USERID as url parameter . Refer the URL in the above GET ajax call.
var userImageData = ”;
var userId = $.request.parameters.get(“USERID”);
var conn = $.db.getConnection();
var query = “SELECT * FROM \”RESOURCE_PLANNER\”.\”IMAGE_STORE\” where USERID = ‘”+ userId + “‘”;
var pstmt = conn.prepareStatement(query);
var userImageResult = pstmt.executeQuery();
if (userImageResult.next()) {// User Image retrieved
userImageData = userImageResult.getString(2);
}
$.response.setBody(userImageData);
$.response.contentType = ‘text/plain’;
$.response.status = $.net.http.OK;
In the UI, I have a button to trigger the retrieve event.
// Image control to render retrieved image
var oDBImage = new sap.ui.commons.Image(“img_db”).addStyleClass(‘dBImage’);
var oGetImageButton = new sap.ui.commons.Button({text : “Retrieve Image”,
press : function() {
/** Get Saved Image for entered User Id */
$.ajax({
url: “/ResourcePlanner/Services/RetrieveImage.xsjs?USERID=I066096”,
type: “GET”,
async: false,
success: function(data, textStatus, XMLHttpRequest) {
document.getElementById(“img_db”).src = img;
},
error: function(XMLHttpRequest, textStatus, errorThrown){
console.error(“Error in retrieving image”);
}
});
}
});
Again, once the data is retrieved in the ‘Success’ part of the ajax call, set it to the ‘src’ property of an Image.
Hope this was informative.
Happy Coding 😉
Good Blog Ashok!
Hi Ashok,
Nice post.Is it will support pdf upload and download also?
Naresh, I'm not too sure about handling pdf in this approach.
Nevertheless the file data can be uploaded and saved this way.
And of course the retrieval and rendering has to be done explicitly for pdf.
Hi Ashok,
I am new to Hana UI5 , I am not getting any thing can you please send me complete project to upload .csv file and insert to Hana DB?
Thanks in advance.
Nice blog. I have a question - in your code, how to do you get from the data returned in the success function to the img? I think you have some steps missing. Do we need to convert the data into some format and place it in img?
success: function(data, textStatus, XMLHttpRequest) {
document.getElementById(“img_db”).src = img;
I am working on a similar example - and running into an issue converting the response for the XSJS response to the image.
Looking forward to hear from you,
Thanks,
Jay
Did you have to convert the binary image data to base 64 for the image?
Still awaiting your response.
Thanks,
Jay
Hey Jay,
Nope its not needed. document.getElementById(“img_db”).src = img; should work as the file up-loader already gives the data in ‘base64’ format.
E.g of one of the image I had saved in DB:
‘data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA…’
So it is in ‘data:image/<file_extn>;base64,<image data>’. Hence you can save and retrieve the same and set it to image src property as it is.
FYI – below method is what I am using to retrieve the image content from server.
and set it to an Image control src as:
As you can see, there is absolutely no need to process the image data at all.
Best Regards,
Ashok.
Thanks Ashok!
Hi Ashok,
Do you have complete sample code working on github or some other place? I am new to hana and playing around.
HI Nitin Singh,
I am also new to Hana , can give the complete sample code to upload and retrieve .csv and inserting into DB . if you have found it!
Good One...
Nitin, Vasu,
Unfortunately I no longer have the project :(... In my view, the code in the description pretty much does everything.
If I'm able to locate this project in my old laptop, will post a link here.
Best Regards,
Ashok.
Hello Ashok and thank you for this great Post.
This sadly doesnt work for me.
I am using a HCP Multitenant Database Container, and have used Jay Malla's way for implementing the upload as shown in: https://blogs.sap.com/2017/03/14/how-to-post-an-image-from-sapui5-and-store-in-hana-db-as-blob-using-xsjs/
And am now using your way for retrieving the Data and showing the previously saved .jpg as a picture on my Fiori application.
The code currently looks like this on my side:
but i keep getting this picture:
when I change the query to: var query = "SELECT * FROM \"APPAPP\".\"CHANGE_REQUESTS\"";
though, i dont get the error Message anymore:
Can you please, for the sake of all new users using HANA Cloud trial accounts nowadays, provide some insight on how to deal with this situation.
THANK YOU AGAIN!
Hi Sonja,
what is the exact error/exception you are getting? can you post that?
Also see if you can debug the service to see execution does not end up in error/exceptions.
Best Regards,
Ashok.
Is it possible to add uploaded image into file directory of project instead of adding in database?
Hi Avinash,
Did you get a solution for this? Please share if you have it. Am in the same situation.
Thanks