WDA學習(17):WDA excel upload && download
1.10 Excel upload && download
在WDA中實現excel上傳下載。
建立WDA Component,Z_TEST_WDA13。
1.建立Context上下文
建立上傳表節點
建立NODE:NODE_SFLIGHT,型別:SFLIGHT;
上傳檔案資訊節點:
建立NODE:NODE_UPLOAD_DATA
建立Attribute:FILENAME,型別String;
建立Attribute:FILETYPE,型別String;
建立Attribute:DATA,型別XString;
2.建立Layout檢視
建立E_FILEUP,FILEUPLOAD檢視控制元件,上傳檔案選擇操作;
建立E_BUTTON,BUTTON檢視控制元件,上傳動作;
建立E_BUTTON1,BUTTON檢視控制元件,下載動作;
建立E_TABLE,TABLE檢視控制元件,用來顯示上傳結果;
設定上傳按鈕text屬性,建立對應Action;
設定下載按鈕text屬性,建立對應Action;
繫結Context節點,data對應NODE_UPLOAD_DATA-DATA,fileName對應NODE_UPLOAD_DATA-FILENAME,mineType對應NODE_UPLOAD_DATA-FILETYPE;
選擇E_TABLE,右鍵選擇Creat Binding,繫結上下文節點Context;
3.實現Action等方法
實現SHOW_MSG方法
程式碼例項:
method SHOW_MSG . "顯示資訊 DATA: l_current_controller TYPE REF TO if_wd_controller, l_message_manager TYPE REF TO if_wd_message_manager. l_current_controller ?= wd_this->wd_get_api( ). CALL METHOD l_current_controller->get_message_manager RECEIVING message_managerView Code= l_message_manager. * report message IF msg_type = 'S'. CALL METHOD l_message_manager->report_success EXPORTING message_text = msg. ELSEIF msg_type = 'E'. CALL METHOD l_message_manager->report_error_message EXPORTING message_text = msg. ELSEIF msg_type = 'I'. CALL METHOD l_message_manager->report_message EXPORTING message_text = msg. ENDIF. endmethod.
實現相應Action方法
建立INIT_SFLIGHT方法,初始化查詢sflight表資訊,並且繫結節點Context。
程式碼例項:
method INIT_SFLIGHT . DATA:lo_node TYPE REF TO if_wd_context_node. DATA:lt_sflight TYPE wd_this->Elements_node_sflight. DATA:ls_sflight LIKE LINE OF lt_sflight. "獲取節點 lo_node = wd_context->get_child_node( name = 'NODE_SFLIGHT' ). "查詢資料 SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_sflight FROM sflight. "繫結資料 lo_node->bind_table( lt_sflight ). endmethod.
初始化方法呼叫初始化init_sfight
method WDDOINIT .
init_sflight( ).
endmethod.
實現上傳Action方法
method ONACTIONUPLOAD . DATA:lo_node TYPE REF TO if_wd_context_node. DATA:lt_node_sflight TYPE wd_this->Elements_node_sflight. DATA:ls_node_sflight LIKE LINE OF lt_node_sflight. "檔案節點資料 DATA:ls_node_upload_data TYPE wd_this->Element_node_upload_data. "檔案資料 DATA:lv_file TYPE xstring. "excel文件類物件 DATA:lo_excel TYPE REF TO zcl_excel. "excel worksheet類物件 DATA:lo_worksheet TYPE REF TO zcl_excel_worksheet. "異常類 DATA:lf_cxexcel TYPE REF TO ZCX_EXCEL. "上傳excel DATA:cl_reader TYPE REF TO zif_excel_reader. "excel匯入內表 TYPES:BEGIN OF s_excel, carrid TYPE string, connid TYPE string, fldate TYPE string, price TYPE string, currency TYPE string, planetype TYPE string, seatsmax TYPE string, seatsocc TYPE string, paymentsum TYPE string, END OF s_excel. DATA:lt_excel TYPE TABLE OF s_excel. DATA:ls_excel LIKE LINE OF lt_excel. "讀取行列數 DATA:col_count TYPE I. DATA:row_count TYPE I. DATA:col TYPE I. DATA:row TYPE I. "獲取節點資料 lo_node = wd_context->get_child_node( name = 'NODE_UPLOAD_DATA'). lo_node->get_static_attributes( IMPORTING static_attributes = ls_node_upload_data ). lv_file = ls_node_upload_data-data. "是否選擇上傳檔案 IF lv_file IS INITIAL. "報錯沒有選擇檔案 wd_comp_controller->show_msg( msg = '請選擇上傳檔案' msg_type = 'E' ). RETURN. ENDIF. TRY. CREATE OBJECT lo_excel. "cl_reader物件 CREATE OBJECT cl_reader TYPE zcl_excel_reader_2007. "載入檔案 lo_excel = cl_reader->load( I_EXCEL2007 = lv_file ). lo_worksheet = lo_excel->get_active_worksheet( ). "獲取行數,列數,去掉首行 row_count = lo_worksheet->get_highest_row( ) - 1. col_count = lo_worksheet->get_highest_column( ). DO row_count TIMES. row = sy-index + 1. CLEAR ls_excel. DO col_count TIMES. col = sy-index. CASE col. WHEN 1. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-carrid ). WHEN 2. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-connid ). WHEN 3. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-fldate ). WHEN 4. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-price ). WHEN 5. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-currency ). WHEN 6. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-planetype ). WHEN 7. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-seatsmax ). WHEN 8. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-seatsocc ). WHEN 9. lo_worksheet->get_cell( EXPORTING ip_column = col ip_row = row IMPORTING ep_value = ls_excel-paymentsum ). ENDCASE. ENDDO. APPEND ls_excel TO lt_excel. ENDDO. "是否上傳資料 IF lt_excel IS INITIAL. wd_comp_controller->show_msg( msg = '上傳excel沒有資料' msg_type = 'E' ). RETURN. ENDIF. "將資料轉換指定型別 LOOP AT lt_excel INTO ls_excel. MOVE-CORRESPONDING ls_excel TO ls_node_sflight. APPEND ls_node_sflight TO lt_node_sflight. ENDLOOP. CATCH ZCX_EXCEL INTO lf_cxexcel. "獲取錯誤資訊 DATA:result TYPE string. CALL METHOD lf_cxexcel->IF_MESSAGE~GET_TEXT RECEIVING result = result. wd_comp_controller->show_msg( msg = result msg_type = 'E' ). ENDTRY. "獲取節點 lo_node = wd_context->get_child_node( name = 'NODE_SFLIGHT' ). "繫結資料 lo_node->bind_table( lt_node_sflight ). endmethod.View Code
實現下載Action方法
method ONACTIONDOWNLOAD . DATA:lo_node TYPE REF TO if_wd_context_node. DATA:lt_node_sflight TYPE wd_this->Elements_node_sflight. DATA:ls_node_sflight LIKE LINE OF lt_node_sflight. "excel文件類物件 DATA:lo_excel TYPE REF TO zcl_excel. "excel worksheet類物件 DATA:lo_worksheet TYPE REF TO zcl_excel_worksheet. "異常類 DATA:lf_cxexcel TYPE REF TO ZCX_EXCEL. "style類 DATA:lo_style TYPE REF TO zcl_excel_style. "style的guid,header DATA:lv_style_guid TYPE zexcel_cell_style. "文字樣式 DATA:lv_style_guid_text TYPE zexcel_cell_style. "列選擇物件 DATA:lo_column_dimension TYPE REF TO zcl_excel_worksheet_columndime. "下載顯示excel轉換 DATA:cl_writer TYPE REF TO zif_excel_writer. DATA:xdata TYPE xstring. "列數對應字母 DATA:col_alpha TYPE zexcel_cell_column_alpha. DATA:lv_row TYPE I. DATA:lv_column TYPE I. FIELD-SYMBOLS:<fs_value> TYPE ANY. TYPES:BEGIN OF s_excel, name TYPE string, desc TYPE string, END OF s_excel. DATA:out_excel TYPE TABLE OF s_excel. DATA:wa_excel LIKE LINE OF out_excel. "檔名 DATA:filename TYPE string. "設定檔名 filename = sy-datum && '.xlsx'. "獲取上下文節點資料 lo_node = wd_context->get_child_node( name = 'NODE_SFLIGHT'). lo_node->get_static_attributes_table( IMPORTING table = lt_node_sflight ). "建立匯出欄位及描述 wa_excel-name = 'CARRID'. wa_excel-desc = '航班ID'. APPEND wa_excel TO out_excel. wa_excel-name = 'CONNID'. wa_excel-desc = 'ID'. APPEND wa_excel TO out_excel. wa_excel-name = 'FLDATE'. wa_excel-desc = '航班日期'. APPEND wa_excel TO out_excel. wa_excel-name = 'PRICE'. wa_excel-desc = '價格'. APPEND wa_excel TO out_excel. wa_excel-name = 'CURRENCY'. wa_excel-desc = '幣別'. APPEND wa_excel TO out_excel. wa_excel-name = 'PLANETYPE'. wa_excel-desc = '型別'. APPEND wa_excel TO out_excel. wa_excel-name = 'SEATSMAX'. wa_excel-desc = '座位數'. APPEND wa_excel TO out_excel. wa_excel-name = 'SEATSOCC'. wa_excel-desc = '已佔用'. APPEND wa_excel TO out_excel. wa_excel-name = 'PAYMENTSUM'. wa_excel-desc = '合計'. APPEND wa_excel TO out_excel. TRY. "建立excel物件 CREATE OBJECT lo_excel. "獲得當前worksheet lo_worksheet = lo_excel->get_active_worksheet( ). "建立一個新style lo_style = lo_excel->add_new_style( ). "加粗 lo_style->font->bold = abap_true. "字型大小 lo_style->font->size = 11. "填充型別 lo_style->fill->filltype = zcl_excel_style_fill=>c_fill_solid. "前景色 lo_style->fill->fgcolor-rgb = 'FF66FFCC'. "背景色 lo_style->fill->bgcolor-rgb = 'FF33CCFF'. "獲取style的編碼uuid lv_style_guid = lo_style->get_guid( ). "設定excel表頭 LOOP AT out_excel INTO wa_excel. lv_column = sy-tabix. "將列數轉換成對應列字母 col_alpha = zcl_excel_common=>convert_column2alpha( ip_column = lv_column ). lo_worksheet->set_cell( ip_column = col_alpha ip_row = 1 ip_style = lv_style_guid ip_value = wa_excel-desc ). ENDLOOP. CLEAR lv_column. CLEAR lv_row. LOOP AT lt_node_sflight INTO ls_node_sflight. lv_row = sy-tabix + 1. LOOP AT out_excel INTO wa_excel. lv_column = sy-tabix. "將列數轉換成對應列字母 col_alpha = zcl_excel_common=>convert_column2alpha( ip_column = lv_column ). ASSIGN COMPONENT wa_excel-name OF STRUCTURE ls_node_sflight TO <fs_value>. lo_worksheet->set_cell( ip_column = col_alpha ip_row = lv_row ip_value = <fs_value> ). ENDLOOP. ENDLOOP. "cl_writer物件 CREATE OBJECT cl_writer TYPE zcl_excel_writer_2007. xdata = cl_writer->write_file( lo_excel ). CALL METHOD cl_wd_runtime_services=>attach_file_to_response( EXPORTING I_FILENAME = filename I_CONTENT = xdata I_MIME_TYPE = 'EXCEL' I_IN_NEW_WINDOW = abap_false I_INPLACE = abap_false ). CATCH ZCX_EXCEL INTO lf_cxexcel. "獲取錯誤資訊 DATA:result TYPE String. CALL METHOD lf_cxexcel->IF_MESSAGE~GET_TEXT RECEIVING result = result. wd_comp_controller->show_msg( msg = result msg_type = 'E' ). ENDTRY. endmethod.View Code
4.建立Application
問題1:上傳日期格式時,匯出的excel顯示為日期格式xxxx/xx/xx,但是上傳時先轉換為文字格式,excel日期資料轉換為文字數字,ABAP並不能識別這個數字,並且轉換為對應日期。
ABAP中日期格式轉換Function:
CONVERT_DATE_TO_INTERNAL:日期轉換MM/DD/YYYY轉換為YYYYMMDD;
Excel中設定日期欄位為文字格式,日期格式:MM/DD/YYYY
程式碼例項:
LOOP AT lt_excel INTO ls_excel. "轉換日期格式為abap內部日期格式 DATA:lv_date TYPE S_DATE. CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL' EXPORTING DATE_EXTERNAL = ls_excel-fldate IMPORTING DATE_INTERNAL = lv_date. MOVE-CORRESPONDING ls_excel TO ls_node_sflight. ls_node_sflight-fldate = lv_date. APPEND ls_node_sflight TO lt_node_sflight. ENDLOOP.View Code
問題2:匯出時,如果不額外設定,日期欄位自動和Excel的日期格式相匹配。但是再次原文件上傳時,日期格式自動轉換為文字格式時,就會出現問題1。
直接下載時,匯出為日期格式
ABAP中日期格式轉換Function:
CONVERT_DATE_TO_EXTERNAL:日期格式轉換YYYYMMDD轉換為MM/DD/YYYY。
程式碼例項:
IF wa_excel-name = 'FLDATE'. "日期格式處理 DATA:lv_date TYPE S_DATE. DATA:lv_date_str TYPE string. ASSIGN COMPONENT wa_excel-name OF STRUCTURE ls_node_sflight TO <fs_value>. lv_date = <fs_value>. CALL FUNCTION 'CONVERT_DATE_TO_EXTERNAL' EXPORTING DATE_INTERNAL = lv_date IMPORTING DATE_EXTERNAL = lv_date_str. lo_worksheet->set_cell( ip_column = col_alpha ip_row = lv_row ip_value = lv_date_str ). ELSE. ASSIGN COMPONENT wa_excel-name OF STRUCTURE ls_node_sflight TO <fs_value>. lo_worksheet->set_cell( ip_column = col_alpha ip_row = lv_row ip_value = <fs_value> ). ENDIF.View Code
問題3:上傳錯誤資訊顯示欄位,如果出現條錯誤資訊,那麼錯誤資訊那一欄會很長,錯誤資訊在一行中換行顯示。
1.在NODE_SFLIGHT建立Attribute:MSG,資料型別STRING_TABLE
2.修改Layout,Creat Binding,將MSG加入顯示。
3.修改INIT_SFLIGHT方法,初始化時,設定錯誤資訊顯示效果
method INIT_SFLIGHT . DATA:lo_node TYPE REF TO if_wd_context_node. DATA:lt_sflight TYPE wd_this->Elements_node_sflight. DATA:ls_sflight LIKE LINE OF lt_sflight. DATA:lt_msg TYPE STRING_TABLE. DATA:ls_msg TYPE string. "獲取節點 lo_node = wd_context->get_child_node( name = 'NODE_SFLIGHT' ). "查詢資料 SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_sflight FROM sflight. "初始化,模擬錯誤資訊 LOOP AT lt_sflight INTO ls_sflight. CLEAR lt_msg[]. ls_msg = '模擬錯誤資訊1;'. APPEND ls_msg TO lt_msg. ls_msg = '模擬錯誤資訊2;'. APPEND ls_msg TO lt_msg. ls_sflight-msg = lt_msg. MODIFY lt_sflight FROM ls_sflight. EXIT. ENDLOOP. "繫結資料 lo_node->bind_table( lt_sflight ). endmethod.View Code