Skip to Content
Author's profile photo Ashok Kumar M

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:

  1. Use SAPUI5 File Uploader to upload an image
  2. Render preview of the uploaded image
  3. Save it to HANA DB using a XSJS service.
  4. 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.
/wp-content/uploads/2016/09/1_1028148.png

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));

/wp-content/uploads/2016/09/2_1028149.png

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.

  1. 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.

 

/wp-content/uploads/2016/09/3_1028162.png

 

Hope this was informative.

 

Happy Coding 😉

       

Assigned Tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Siddharth Rajora
      Siddharth Rajora

      Good Blog Ashok!

      Author's profile photo Naresh kumar
      Naresh kumar

      Hi Ashok,

      Nice post.Is it will support pdf upload and download also?

      Author's profile photo Ashok Kumar M
      Ashok Kumar M
      Blog Post Author

      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.

      Author's profile photo vasu srinu
      vasu srinu

      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.

      Author's profile photo Jay Malla
      Jay Malla

      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

       

      Author's profile photo Jay Malla
      Jay Malla

      Did you have to convert the binary image data to base 64 for the image?

       

      Still awaiting your response.

       

      Thanks,

      Jay

       

      Author's profile photo Ashok Kumar M
      Ashok Kumar M
      Blog Post Author

      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.

      	/** Get Saved Image for entered User Id */
      	getImage : function() {
      		var imageData = '';
      		var that = this;
      	        $.ajax({
      	        	  url: "/ResourcePlanner/Services/RetrieveImage.xsjs",
      	        	  type: "GET", 
      	        	  async: false,
      	              success: function(data, textStatus, XMLHttpRequest) {
      	            	  imageData = JSON.parse(data).IMAGEDATA;
      	            	  that.showNotification("Image Retrieved", 1200);						
      	              },
      	        	  error: function(XMLHttpRequest, textStatus, errorThrown){
      	                	console.error("Error in retrieving image");
      	                	that.showNotification("Error in retrieving image", 1200);						
              	  }
      	         });
      	        return imageData;
      	},

      and set it to an Image control src as:

      		var oGetImageButton = new sap.ui.commons.Button({text : "Retrieve Image",
      			press : function() {
      					var img = oController.getImage();
      	                document.getElementById("img_db").src = img;
      			}
      		});

      As you can see, there is absolutely no need to process the image data at all.

      Best Regards,

      Ashok.

      Author's profile photo Jay Malla
      Jay Malla

      Thanks Ashok!

      Author's profile photo Former Member
      Former Member

      Hi Ashok,

      Do you have complete sample code working on github or some other place? I am new to hana and playing around.

      Author's profile photo vasu srinu
      vasu srinu

      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!

      Author's profile photo Jayakanth Ramakanthan
      Jayakanth Ramakanthan

      Good One...

      Author's profile photo Ashok Kumar M
      Ashok Kumar M
      Blog Post Author

      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.

       

      Author's profile photo Former Member
      Former Member

      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:

      var userImageData = "";
      
            var conn = $.db.getConnection();
            var query = "SELECT IMAGE_CONTENT FROM \"APPAPP\".\"CHANGE_REQUESTS\" where IMAGE_NAME = 'abc.jpg";
      
            var pstmt = conn.prepareStatement(query);//conn.prepareStatement(query);
            var userImageResult = pstmt.executeQuery();
            if (userImageResult.next()) {// User Image retrieved
                  userImageData = userImageResult.getString(2);
            }
            $.response.setBody(userImageData);
            $.response.contentType = 'text/html';
            $.response.status = $.net.http.OK;

      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!

      Author's profile photo Ashok Kumar M
      Ashok Kumar M
      Blog Post Author

      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.

      Author's profile photo Avinash Raut
      Avinash Raut

      Is it possible to add uploaded image into file directory of project instead of adding in database?

      Author's profile photo Dominic Gichuhi
      Dominic Gichuhi

      Hi Avinash,

      Did you get a solution for this? Please share if you have it. Am in the same situation.

      Thanks