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 😉

       

To report this post you need to login first.

7 Comments

You must be Logged on to comment or reply to a post.

    1. Ashok Kumar M 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.

      (0) 
  1. 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

     

    (0) 
    1. Jay Malla

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

       

      Still awaiting your response.

       

      Thanks,

      Jay

       

      (0) 
      1. Ashok Kumar M 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.

        (1) 

Leave a Reply