How perform multi upload files in Webdynpro ABAP using SAP UI5 library sap.m.UploadCollection
2023-12-11 17:17:0 Author: blogs.sap.com(查看原文) 阅读量:13 收藏

In this example we will create a simple Webdynpro ABAP component called ZWDA_UI5_FILEUPLOADER to show how to use SAP UI5 component sap.m.UploadCollection to upload multiple files in your webdynpro application.

1%20-%20Eclipse%20screenshot%20Webdynpro%20Component%20Creation

1 – Eclipse screenshot Webdynpro Component Creation

Create a node called FILES_UPLOADED with cardinality/selection 0…N and the following attributes:

name data element category length
FILENAME_WITH_FILETYPE STRING
MIMETYPE W3CONTTYPE char 128
SIZE STRING
CONTENT XSTRING

2%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Context%20Node%20Creation

2 – SAP GUI screenshot Webdynpro Context Node Creation

Context Mapping of the node FILES_UPLOADED 

SAP%20GUI%20screenshot%20Webdynpro%20Context%20Mapping.png

3 – SAP GUI screenshot Webdynpro Context Mapping.png

Create a CTable to show all the files that will be uploaded ( context node FILES_UPLOADED) with the following columns:

Column Cell Editor property bind
COL_FILEDOWNLOAD FileDownload (See the next picture)
COL_MIMETYPE TextView MAIN.FILES_UPLOADED.MIMETYPE
COL_SIZE TextView MAIN.FILES_UPLOADED.SIZE

Filedownload column bind properties:

SAP%20GUI%20screenshot%20Webdynpro%20File%20Download%20column%20properties

4 – SAP GUI screenshot Webdynpro File Download column properties

Create an HtmlIsland with the name HTML_ISLAND_FILE_UPLOADER_UI5

Now we will add two scripts on the HtmlIsland, the first one is to call the SAP UI5 library, and the other is to call our custom javascript code. 

Script to call the SAP UI5 library

Right click on the HtmlIsland and choose Script Insert

SAP%20GUI%20screenshot%20Webdynpro%20Script%20Insert%20Menu

5 – SAP GUI screenshot Webdynpro Script Insert Menu

Rename it to UI5_CORE_SCRIPT

Adding Custom Scripts Attributes

Now we need to add 2 Custom Script Attributes, to do that perform the following action 2 times:

Right click on the HtmlScript UI5_CORE_SCRIPT and choose Custom Attribute Insert

6%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Custom%20Attribute%20Insert%20Menu

6 – SAP GUI screenshot Webdynpro Custom Attribute Insert Menu

After change the properties of theses Script Attributes

  • The first one is to perform the UI5 Bootstrap

ID ID_CSA

name id

value sap-ui-bootstrap

7%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Custom%20Attribute%20Properties

7 – SAP GUI screenshot Webdynpro Custom Attribute Properties

  • The second one is used to load all the UI5 libraries that we need (use comma to separate the names of the UI5 libraries if you need more than one, example “sap.ui.commons,sap.m”). In our example, we only need the UI5 library sap.m:

ID LIB_CSA

name data-sap-ui-libs

value sap.m

8%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Custom%20Attribute%20Properties

8 – SAP GUI screenshot Webdynpro Custom Attribute Properties

Script to call our custom javascript code

Right click on the HtmlIsland and choose Script Insert

9%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Script%20Insert%20Menu

9 – SAP GUI screenshot Webdynpro Script Insert Menu

Rename the ID property to CUSTOM_JS

Fill the source property with the name FileUploaderUI5.js (it is the name of the MIME object that we will import in the next step).

10%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Html%20Script%20Properties

10 – SAP GUI screenshot Webdynpro Html Script Properties

Create a Javascript file in your preferred IDE.

Paste the following code in the Javascript File:

var MyFileUploader = MyFileUploader || {
    init: function (oCallbackApi, maxFilenameLength, maxFileSize, fileType) {
        if (fileType !== null) {
            var filetypeArray = fileType.split(",");
        } else {
            filetypeArray = null
        }
        this.oCallbackApi = oCallbackApi;
        this.oFileUploader = new sap.m.UploadCollection({
            maximumFilenameLength: parseInt(maxFilenameLength),
            maximumFileSize: parseInt(maxFileSize), // Specifies a file size limit in megabytes
            multiple: true,
            sameFilenameAllowed: false,
            instantUpload: false,
            fileType: filetypeArray,
            change: this.onChange,
            typeMissmatch: this.ontypeMissmatch,
            fileSizeExceed: this.onfileSizeExceed,
            filenameLengthExceed: this.onfilenameLengthExceed,
        });

        this.oFileUploader.placeAt("FileUploadUI5");
    },
    onChange: function (oControlEvent) {
        for (let index = 0; index < oControlEvent.mParameters["files"].length; index++) {
            const file = oControlEvent.mParameters["files"][index];
            MyFileUploader.uploadToCallbackAPI(file);
        }
    },
    ontypeMissmatch: function (oControlEvent) {
        let file = oControlEvent.mParameters["files"][0];
        MyFileUploader.oCallbackApi.fireEvent('UI5TypeMismatch', '{"filename":"' + file.name + '",' + '"filetype":"' + file.fileType + '"}');
    },
    onfilenameLengthExceed: function (oControlEvent) {
        let file = oControlEvent.mParameters["files"][0];
        MyFileUploader.oCallbackApi.fireEvent('UI5NameLenghtExceed', file.name );
    },
    onfileSizeExceed: function (oControlEvent) {
        let file = oControlEvent.mParameters["files"][0];
        MyFileUploader.oCallbackApi.fireEvent('UI5SizeExceed', file.name );
    },
    uploadToCallbackAPI(file) {

        if (file == null) {
            return;
        }
        var oFileReader = new FileReader();
        var fileName = file.name.split(".")[0];
        var fileType = file.name.split(".")[1];
        var mimetype = file.type;
        var size = file.size;

        oFileReader.onload = function (evt) {
            var raw = evt.target.result;
            var hexString = MyFileUploader.convertBinaryToHex(raw).toUpperCase();
            var fileAsJsonString = MyFileUploader.createJsonObjectForFileInfo(fileName, fileType, mimetype, size, hexString);

            MyFileUploader.oCallbackApi.fireEvent('UI5Upload', fileAsJsonString);

        };

        oFileReader.onerror = function (evt) {
            sap.m.MessageToast.show("error");
        };
        oFileReader.readAsArrayBuffer(file);


    },
    createJsonObjectForFileInfo: function (fileName, fileType, mimetype, size, hexString) {
        return '{"filename":"' + fileName + '",' +
            '"filetype":"' + fileType + '",' +
            '"mimetype":"' + mimetype + '",' +
            '"size":"' + size + '",' +
            '"hexcont":"' + hexString + '"}';
    },

    convertBinaryToHex: function (buffer) {
        return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
    },
    removeFirstFile: function (evt) {
        var oFirstFileItem = MyFileUploader.oFileUploader.getItems()[0];
        MyFileUploader.oFileUploader.removeItem(oFirstFileItem);
    }
}

Right click on the Webdynpro component and chose: Create > MIME Object > Import

11%20-%20SAP%20GUI%20screenshot%20Webdynpro%20MIME%20Object%20Import

11 – SAP GUI screenshot Webdynpro MIME Object Import

In the following popup, just click in the Save button

12%20-%20SAP%20GUI%20screenshot%20Webdynpro%20MIME%20Object%20Import%20confirm

12 – SAP GUI screenshot Webdynpro MIME Object Import confirm

Now your Javascript code is part of your Webdynpro component as a MIME Object.

13%20-%20SAP%20GUI%20screenshot%20Webdynpro%20MIME%20Object%20Importation%20result

13 – SAP GUI screenshot Webdynpro MIME Object Importation result

Everytime that you need to update it, just change your Javascript file in your preferred IDE and upload it again.

To do that, perform an right click on the MIME Object and choose: Upload/Download > Upload and Replace

14%20-%20SAP%20GUI%20screenshot%20Webdynpro%20MIME%20Object%20Replace

14 – SAP GUI screenshot Webdynpro MIME Object Replace

Create a view attribute called MO_HTML_ISLAND type ref to CL_WD_HTML_ISLAND (it will be filled in the method WDDOMODIFYVIEW).

15%20-%20SAP%20GUI%20screenshot%20Webdynpro%20View%20attribute%20creation

15 – SAP GUI screenshot Webdynpro View attribute creation

Create a view attribute called MV_REMOVE_FILE type WDY_BOOLEAN (it will be filled in the method ONACTIONUI5_UPLOAD anc checked in the method WDDOMODIFYVIEW ).

15b%20-%20SAP%20GUI%20screenshot%20Webdynpro%20View%20attribute%20creation

15b – SAP GUI screenshot Webdynpro View attribute creation

In the WDDOMODIFYVIEW method, put the following code:

METHOD wddomodifyview .

  CONSTANTS:
    c_file_upload_html_id TYPE string VALUE 'FileUploadUI5',
    c_html_insland_id     TYPE string VALUE 'HTML_ISLAND_FILE_UPLOADER_UI5',
    c_ui5_core_script_id  TYPE string VALUE 'UI5_CORE_SCRIPT'.

  IF first_time = abap_true.

    " use central UI5-version provided by WDA
    DATA(lv_script_string) = cl_wd_utilities=>get_ui5_root_path( ).
    IF lv_script_string IS NOT INITIAL.
      CONCATENATE lv_script_string 'sap-ui-core.js' INTO lv_script_string.
      CONDENSE lv_script_string NO-GAPS.
      CAST cl_wd_html_script( view->get_element( id = c_ui5_core_script_id ) )->set_source( value = lv_script_string ).
    ENDIF.

    " set static html
    DATA(lv_static_html) = |<div id="{ c_file_upload_html_id }" style="height:100%"></div>|.

    wd_this->mo_html_island = CAST cl_wd_html_island( view->get_element( c_html_insland_id ) ).
    wd_this->mo_html_island->set_static_html( lv_static_html ).

    " Call the Init Javascript function and pass the Webdynpro callback API to allow the JavaScript code call Webdynpro Actions
    wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
        )->variable( `MyFileUploader`
        )->function( `init`
        )->add_callback_api(
        )->add_string( '100'                      " Maximum Filename Length
        )->add_string( '1'                        " Maximum FileSize (Specifies a file size limit in megabytes)
        )->add_string( 'jpg,pdf,txt,xls,xlsx,png' " FileTypes (use comma as separator)
*        )->add_null( " Use add_null if all the file types should be allowed
        ) ).

  ELSEIF wd_this->mv_remove_file = abap_on.

    wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
        )->variable( `MyFileUploader`
        )->function( `removeFirstFile` ) ).

    wd_this->mv_remove_file = abap_off.

  ENDIF.

ENDMETHOD.

Now we need to create 4 actions for our view

16%20-%20SAP%20GUI%20screenshot%20Webdynpro%20View%20action%20creation

16 – SAP GUI screenshot Webdynpro View action creation

Create an View Action to be called by the Javascript code

In your view, create a new action called: UI5_UPLOAD 

In that action put the following code:

METHOD onactionui5_upload .

  TYPES:
    BEGIN OF ty_file_uploaded,
      filename TYPE string,
      filetype TYPE string,
      mimetype TYPE string,
      size     TYPE string,
      hexcont  TYPE string,
    END OF ty_file_uploaded.

  DATA ls_file_uploaded_js TYPE ty_file_uploaded.

  DATA ls_files_uploaded_wd TYPE wd_this->element_files_uploaded.
  DATA:
    BEGIN OF ls_file_size,
      value TYPE  k_bytes,
      unit  TYPE  cacs_byte_unit,
    END OF ls_file_size.

  IF wdevent IS NOT BOUND.
    RETURN.
  ENDIF.

  DATA(lv_file_upload_json) = wdevent->get_string( `DATA` ).

  /ui2/cl_json=>deserialize( EXPORTING json = lv_file_upload_json
                             CHANGING  data = ls_file_uploaded_js ).

  ls_files_uploaded_wd-mimetype               = ls_file_uploaded_js-mimetype.
  ls_files_uploaded_wd-content                = ls_file_uploaded_js-hexcont.
  ls_files_uploaded_wd-filename_with_filetype = |{ ls_file_uploaded_js-filename }.{ ls_file_uploaded_js-filetype }|.

  CALL FUNCTION 'CACS_CONVERT_BYTE'
    EXPORTING
      i_byte  = CONV k_bytes( ls_file_uploaded_js-size )
    IMPORTING
      e_value = ls_file_size-value
      e_unit  = ls_file_size-unit.

  ls_files_uploaded_wd-size = |{ ls_file_size-value } { ls_file_size-unit }|.

  DATA(lo_nd_files_uploaded) = wd_context->get_child_node( wd_this->wdctx_files_uploaded ).

  lo_nd_files_uploaded->bind_structure( new_item = ls_files_uploaded_wd
                                        set_initial_elements = abap_false ).

  wd_this->mv_remove_file = abap_on.

ENDMETHOD.

Create an View Action to the File Size Exceeded error

In your view, create a new action UI5_FILE_SIZE_EXCEED

In that action put the following code:

METHOD onactionui5_file_size_exceed .

  DATA(lv_filename) = wdevent->get_string( `DATA` ).

  wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
    EXPORTING
      message_text = |The File "{ lv_filename }"   exceeded the size limit| ).

ENDMETHOD.

Create an View Action to the Name Length Exceeded error

In your view, create a new action UI5_NAME_LENG_EXCEED

In that action put the following code:

METHOD onactionui5_name_leng_exceed .

  DATA(lv_filename) = wdevent->get_string( `DATA` ).

  wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
    EXPORTING
      message_text = |"{ lv_filename }" file name is longer than allowed| ).

ENDMETHOD.

Create an View Action to the Name Length Exceeded error

In your view, create a new action UI5_TYPE_MISSMATCH

In that action put the following code:

method ONACTIONUI5_TYPE_MISSMATCH .

 TYPES:
    BEGIN OF ty_file_uploaded,
      filename TYPE string,
      filetype TYPE string,
    END OF ty_file_uploaded.

  DATA ls_file_uploaded_js TYPE ty_file_uploaded.

  IF wdevent IS NOT BOUND.
    RETURN.
  ENDIF.

  DATA(lv_file_upload_json) = wdevent->get_string( `DATA` ).

  /ui2/cl_json=>deserialize( EXPORTING json = lv_file_upload_json
                             CHANGING  data = ls_file_uploaded_js ).

wd_this->wd_get_api( )->get_message_manager( )->report_error_message(
  EXPORTING
    message_text = |The File type { ls_file_uploaded_js-filetype } from the file { ls_file_uploaded_js-filename } is not allowed| ).

endmethod.

17%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Insert%20Html%20Event

17 – SAP GUI screenshot Webdynpro Insert Html Event

Change its properties to:

ID HTML_EVT_UI5_UPLOAD

name UI5Upload

Events / onAction UI5_UPLOAD

ID HTML_EVT_UI5_SIZE_EXCEED

name UI5SizeExceed

Events / onAction UI5_FILE_SIZE_EXCEED

ID HTML_EVT_UI5_NAME_LENG_EXCEED

name UI5NameLenghtExceed

Events / onAction UI5_NAME_LENG_EXCEED

ID HTML_EVT_UI5_TYPE_MISMATCH

name UI5TypeMismatch

Events / onAction UI5_TYPE_MISSMATCH

18%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Html%20Events%20results

18 – SAP GUI screenshot Webdynpro Html Events results

Create a group with the caption “Webdynpro ABAP” and put the CTable on it

Create a group with the caption “SAP UI5 (class sap.m.UploadCollection)” and put the Html Island on it

Create a new Webdynpro application called ZWDA_UI5_FILEUPLOADER and test it

19%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Application%20Creation

19 – SAP GUI screenshot Webdynpro Application Creation

The application should be appear like this:

20%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Application%20Initial%20screen

20 – SAP GUI screenshot Webdynpro Application Initial screen

When you add multiple files to the first area using drag and drop or the “+” button, the application will perform the upload of the files to the Webdynpro component. 

Before

21%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Application%20Drop%20Files

21 – SAP GUI screenshot Webdynpro Application Drop Files

After

22%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Application%20upload%20result

22 – SAP GUI screenshot Webdynpro Application upload result

You can click on the first column to perform a download of the file.

The SAP UI5 component sap.m.UploadCollection can optionally validate the file types, the filesize and the filename length according to the parameters that we assign to the initialization routine present in WDDOMODIFYVIEW.

    " Call the Init Javascript function and pass the Webdynpro callback API to allow the JavaScript code call Webdynpro Actions
    wd_this->mo_html_island->add_script_call( cl_wd_html_script_call=>new_call(
        )->variable( `MyFileUploader`
        )->function( `init`
        )->add_callback_api(
        )->add_string( '100'                      " Maximum Filename Length
        )->add_string( '1'                        " Maximum FileSize (Specifies a file size limit in megabytes)
        )->add_string( 'jpg,pdf,txt,xls,xlsx,png' " FileTypes (use comma as separator)
*        )->add_null( " Use add_null if all the file types should be allowed
        ) ).

The webdynpro will receive the name of the file when an error occurs. So we can emit a error message in the webdynpro application.

In the following example, I tried to realize a upload of the file “A pdf file with more than 1 megabytes.pdf” that has more than 1 megabytes.

22%20-%20SAP%20GUI%20screenshot%20Webdynpro%20Application%20example%20error

23 – SAP GUI screenshot Webdynpro Application example error

The following articles was used as reference:

https://blogs.sap.com/2015/06/30/team-fpm-creating-a-ui5-based-uibb/

https://answers.sap.com/questions/12970830/issue-in-adding-uploadcollection-ui-element-in-web.html

https://blogs.sap.com/2018/07/06/creating-a-gos-attachment-with-sapui5/


文章来源: https://blogs.sap.com/2023/12/11/how-perform-multi-upload-files-in-webdynpro-abap-using-sap-ui5-library-sap.m.uploadcollection/
如有侵权请联系:admin#unsafe.sh