From d907d03e288ea7c4ed46a8cd0a28d3d00acc7a27 Mon Sep 17 00:00:00 2001 From: mfallen Date: Mon, 18 Feb 2019 07:23:15 +0100 Subject: [PATCH] Header Footer Image including a test program --- src/zcl_excel.clas.abap | 2 + src/zcl_excel_sheet_setup.clas.abap | 131 +++++- src/zcl_excel_writer_2007.clas.abap | 530 +++++++++++++++++++++- src/zcl_excel_writer_2007.clas.xml | 30 ++ src/zexcel_s_worksheet_head_foot.tabl.xml | 33 ++ src/ztest_excel_image_header.prog.abap | 81 ++++ src/ztest_excel_image_header.prog.xml | 28 ++ 7 files changed, 805 insertions(+), 30 deletions(-) create mode 100644 src/ztest_excel_image_header.prog.abap create mode 100644 src/ztest_excel_image_header.prog.xml diff --git a/src/zcl_excel.clas.abap b/src/zcl_excel.clas.abap index 58d8f7f..6444050 100644 --- a/src/zcl_excel.clas.abap +++ b/src/zcl_excel.clas.abap @@ -205,6 +205,8 @@ method ADD_NEW_DRAWING. CASE ip_type. WHEN 'image'. drawings->add( eo_drawing ). + WHEN 'hd_ft'. + drawings->add( eo_drawing ). WHEN 'chart'. charts->add( eo_drawing ). ENDCASE. diff --git a/src/zcl_excel_sheet_setup.clas.abap b/src/zcl_excel_sheet_setup.clas.abap index 6d3742e..d338fee 100644 --- a/src/zcl_excel_sheet_setup.clas.abap +++ b/src/zcl_excel_sheet_setup.clas.abap @@ -144,6 +144,12 @@ public section. !EP_ODD_FOOTER type STRING !EP_EVEN_HEADER type STRING !EP_EVEN_FOOTER type STRING . + methods GET_HEADER_FOOTER + exporting + !EP_ODD_HEADER type ZEXCEL_S_WORKSHEET_HEAD_FOOT + !EP_ODD_FOOTER type ZEXCEL_S_WORKSHEET_HEAD_FOOT + !EP_EVEN_HEADER type ZEXCEL_S_WORKSHEET_HEAD_FOOT + !EP_EVEN_FOOTER type ZEXCEL_S_WORKSHEET_HEAD_FOOT . protected section. *"* protected components of class ZCL_EXCEL_SHEET_SETUP @@ -198,7 +204,34 @@ method CONSTRUCTOR. endmethod. -method GET_HEADER_FOOTER_STRING. +METHOD get_header_footer. + +* Only Basic font/text formatting possible: +* Bold (yes / no), Font Type, Font Size +* +* usefull placeholders, which can be used in header/footer value strings +* '&P' - page number +* '&N' - total number of pages +* '&D' - Date +* '&T' - Time +* '&F' - File Name +* '&Z' - Path +* '&A' - Sheet name +* new line via class constant CL_ABAP_CHAR_UTILITIES=>newline +* +* Example Value String 'page &P of &N' +* +* DO NOT USE &L , &C or &R which automatically created as position markers + + ep_odd_header = me->odd_header. + ep_odd_footer = me->odd_footer. + ep_even_header = me->even_header. + ep_even_footer = me->even_footer. + +ENDMETHOD. + + +METHOD get_header_footer_string. * ---------------------------------------------------------------------- DATA: lc_marker_left(2) TYPE c VALUE '&L' , lc_marker_right(2) TYPE c VALUE '&R' @@ -223,6 +256,19 @@ method GET_HEADER_FOOTER_STRING. CONCATENATE ep_odd_header lc_marker_right lv_value INTO ep_odd_header. ENDIF. + IF me->odd_header-left_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_left lv_value INTO ep_odd_header. + ENDIF. + IF me->odd_header-center_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_center lv_value INTO ep_odd_header. + ENDIF. + IF me->odd_header-right_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_right lv_value INTO ep_odd_header. + ENDIF. + ENDIF. * ---------------------------------------------------------------------- IF ep_odd_footer IS SUPPLIED. @@ -242,6 +288,19 @@ method GET_HEADER_FOOTER_STRING. CONCATENATE ep_odd_footer lc_marker_right lv_value INTO ep_odd_footer. ENDIF. + IF me->odd_footer-left_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_left lv_value INTO ep_odd_footer. + ENDIF. + IF me->odd_footer-center_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_center lv_value INTO ep_odd_footer. + ENDIF. + IF me->odd_footer-right_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_right lv_value INTO ep_odd_footer. + ENDIF. + ENDIF. * ---------------------------------------------------------------------- IF ep_even_header IS SUPPLIED. @@ -261,6 +320,19 @@ method GET_HEADER_FOOTER_STRING. CONCATENATE ep_even_header lc_marker_right lv_value INTO ep_even_header. ENDIF. + IF me->even_header-left_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_left lv_value INTO ep_even_header. + ENDIF. + IF me->even_header-center_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_center lv_value INTO ep_even_header. + ENDIF. + IF me->even_header-right_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_right lv_value INTO ep_even_header. + ENDIF. + ENDIF. * ---------------------------------------------------------------------- IF ep_even_footer IS SUPPLIED. @@ -280,12 +352,25 @@ method GET_HEADER_FOOTER_STRING. CONCATENATE ep_even_footer lc_marker_right lv_value INTO ep_even_footer. ENDIF. + IF me->even_footer-left_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_left lv_value INTO ep_even_footer. + ENDIF. + IF me->even_footer-center_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_center lv_value INTO ep_even_footer. + ENDIF. + IF me->even_footer-right_image IS NOT INITIAL. + lv_value = '&G'. + CONCATENATE ep_odd_header lc_marker_right lv_value INTO ep_even_footer. + ENDIF. + ENDIF. * ---------------------------------------------------------------------- - endmethod. +ENDMETHOD. -method PROCESS_HEADER_FOOTER. +METHOD process_header_footer. * ---------------------------------------------------------------------- * Only Basic font/text formatting possible: @@ -308,29 +393,33 @@ method PROCESS_HEADER_FOOTER. IF IS ASSIGNED AND IS ASSIGNED. - IF -name IS NOT INITIAL. - CONCATENATE '&"' -name ',' INTO rv_processed_string. + IF = '&G'. "image header + rv_processed_string = . ELSE. - rv_processed_string = '&"-,'. + + IF -name IS NOT INITIAL. + CONCATENATE '&"' -name ',' INTO rv_processed_string. + ELSE. + rv_processed_string = '&"-,'. + ENDIF. + + IF -bold = abap_true. + CONCATENATE rv_processed_string 'Bold"' INTO rv_processed_string. + ELSE. + CONCATENATE rv_processed_string 'Standard"' INTO rv_processed_string. + ENDIF. + + IF -size IS NOT INITIAL. + lv_string = -size. + CONCATENATE rv_processed_string '&' lv_string INTO rv_processed_string. + ENDIF. + + CONCATENATE rv_processed_string INTO rv_processed_string. ENDIF. - - IF -bold = abap_true. - CONCATENATE rv_processed_string 'Bold"' INTO rv_processed_string. - ELSE. - CONCATENATE rv_processed_string 'Standard"' INTO rv_processed_string. - ENDIF. - - IF -size IS NOT INITIAL. - lv_string = -size. - CONCATENATE rv_processed_string '&' lv_string INTO rv_processed_string. - ENDIF. - - CONCATENATE rv_processed_string INTO rv_processed_string. - ENDIF. * ---------------------------------------------------------------------- - endmethod. +ENDMETHOD. method SET_HEADER_FOOTER. diff --git a/src/zcl_excel_writer_2007.clas.abap b/src/zcl_excel_writer_2007.clas.abap index b95af7f..9cce673 100644 --- a/src/zcl_excel_writer_2007.clas.abap +++ b/src/zcl_excel_writer_2007.clas.abap @@ -31,8 +31,10 @@ protected section. data SHARED_STRINGS type ZEXCEL_T_SHARED_STRING . data STYLES_COND_MAPPING type ZEXCEL_T_STYLES_COND_MAPPING . data STYLES_MAPPING type ZEXCEL_T_STYLES_MAPPING . - constants C_XL_COMMENTS type STRING value 'xl/comments#.xml' ##NO_TEXT. - constants CL_XL_DRAWING_FOR_COMMENTS type STRING value 'xl/drawings/vmlDrawing#.vml' ##NO_TEXT. + constants C_XL_COMMENTS type STRING value 'xl/comments#.xml'. "#EC NOTEXT + constants CL_XL_DRAWING_FOR_COMMENTS type STRING value 'xl/drawings/vmlDrawing#.vml'. "#EC NOTEXT + constants C_XL_DRAWINGS_VML type STRING value 'xl/drawings/vmlDrawing1.vml'. "#EC NOTEXT + constants C_XL_DRAWINGS_VML_RELS type STRING value 'xl/drawings/_rels/vmlDrawing1.vml.rels'. "#EC NOTEXT methods CREATE_XL_SHEET_SHEET_DATA importing @@ -158,6 +160,25 @@ protected section. !IV_IXML_ELEMENT type ref to IF_IXML_ELEMENT returning value(RV_XSTRING) type XSTRING . + methods CREATE_XL_DRAWINGS_VML + returning + value(EP_CONTENT) type XSTRING . + methods SET_VML_STRING + returning + value(EP_CONTENT) type STRING . + methods CREATE_XL_DRAWINGS_VML_RELS + returning + value(EP_CONTENT) type XSTRING . + methods SET_VML_SHAPE_FOOTER + importing + !IS_FOOTER type ZEXCEL_S_WORKSHEET_HEAD_FOOT + returning + value(EP_CONTENT) type STRING . + methods SET_VML_SHAPE_HEADER + importing + !IS_HEADER type ZEXCEL_S_WORKSHEET_HEAD_FOOT + returning + value(EP_CONTENT) type STRING . private section. *"* private components of class ZCL_EXCEL_WRITER_2007 @@ -183,7 +204,7 @@ METHOD add_further_data_to_zip. ENDMETHOD. -method CREATE. +METHOD create. * Office 2007 file format is a cab of several xml files with extension .xlsx @@ -373,12 +394,14 @@ method CREATE. lo_iterator = me->excel->get_drawings_iterator( zcl_excel_drawing=>type_image ). WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. lo_drawing ?= lo_iterator->if_object_collection_iterator~get_next( ). +* IF lo_drawing->get_type( ) NE zcl_excel_drawing=>type_image_header_footer. - lv_content = lo_drawing->get_media( ). - lv_value = lo_drawing->get_media_name( ). - CONCATENATE 'xl/media/' lv_value INTO lv_value. - lo_zip->add( name = lv_value - content = lv_content ). + lv_content = lo_drawing->get_media( ). + lv_value = lo_drawing->get_media_name( ). + CONCATENATE 'xl/media/' lv_value INTO lv_value. + lo_zip->add( name = lv_value + content = lv_content ). +* ENDIF. ENDWHILE. ********************************************************************** @@ -405,6 +428,20 @@ method CREATE. "------------------------------------------------- ENDWHILE. +********************************************************************** +*** Header Footer Image +*** Thanks to Marios Toumanis for the hints! + lv_content = me->create_xl_drawings_vml( ). + lo_zip->add( name = me->c_xl_drawings_vml + content = lv_content ). + + lv_content = me->create_xl_drawings_vml_rels( ). + lv_xl_drawing_rels = me->c_xl_drawings_vml_rels. + lo_zip->add( name = lv_xl_drawing_rels + content = lv_content ). +********************************************************************** +********************************************************************** + * Second to last step: Allow further information put into the zip archive by child classes me->add_further_data_to_zip( lo_zip ). @@ -412,7 +449,7 @@ method CREATE. * Last step: Create the final zip ep_excel = lo_zip->save( ). - endmethod. +ENDMETHOD. method CREATE_CONTENT_TYPES. @@ -2586,6 +2623,124 @@ method CREATE_XL_DRAWINGS_RELS. endmethod. +METHOD create_xl_drawings_vml. + + DATA: + lo_xml_document TYPE REF TO cl_xml_document, + ld_stream TYPE string. + + +* INIT_RESULT + CLEAR ep_content. + + +* BODY + ld_stream = set_vml_string( ). + + CREATE OBJECT lo_xml_document. + CALL METHOD lo_xml_document->parse_string + EXPORTING + stream = ld_stream. + + CALL FUNCTION 'CRM_IC_XML_STRING2XSTRING' + EXPORTING + instring = ld_stream + IMPORTING + outxstring = ep_content. + +ENDMETHOD. + + +METHOD create_xl_drawings_vml_rels. + +** Constant node name + DATA: lc_xml_node_relationships TYPE string VALUE 'Relationships', + lc_xml_node_relationship TYPE string VALUE 'Relationship', + " Node attributes + lc_xml_attr_id TYPE string VALUE 'Id', + lc_xml_attr_type TYPE string VALUE 'Type', + lc_xml_attr_target TYPE string VALUE 'Target', + " Node namespace + lc_xml_node_rels_ns TYPE string VALUE 'http://schemas.openxmlformats.org/package/2006/relationships', + lc_xml_node_rid_image_tp TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + lc_xml_node_rid_chart_tp TYPE string VALUE 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart'. + + DATA: lo_iterator TYPE REF TO cl_object_collection_iterator, + lo_drawing TYPE REF TO zcl_excel_drawing, + lo_ixml TYPE REF TO if_ixml, + lo_document TYPE REF TO if_ixml_document, + lo_element_root TYPE REF TO if_ixml_element, + lo_element TYPE REF TO if_ixml_element, + lo_encoding TYPE REF TO if_ixml_encoding, + lo_streamfactory TYPE REF TO if_ixml_stream_factory, + lo_ostream TYPE REF TO if_ixml_ostream, + lo_renderer TYPE REF TO if_ixml_renderer, + + lv_value TYPE string, + lv_relation_id TYPE i. + + +* BODY +********************************************************************** +* STEP 1: Create [Content_Types].xml into the root of the ZIP + lo_ixml = cl_ixml=>create( ). + +********************************************************************** +* STEP 2: Set document attributes + lo_encoding = lo_ixml->create_encoding( byte_order = if_ixml_encoding=>co_platform_endian + character_set = 'utf-8' ). + lo_document = lo_ixml->create_document( ). + lo_document->set_encoding( lo_encoding ). + lo_document->set_standalone( abap_true ). + +********************************************************************** +* STEP 3: Create main node relationships + lo_element_root = lo_document->create_simple_element( name = lc_xml_node_relationships + parent = lo_document ). + lo_element_root->set_attribute_ns( name = 'xmlns' + value = lc_xml_node_rels_ns ). + +********************************************************************** +* STEP 4: Create subnodes + lv_relation_id = 0. + lo_iterator = me->excel->get_drawings_iterator( zcl_excel_drawing=>type_image ). + WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. + lo_drawing ?= lo_iterator->if_object_collection_iterator~get_next( ). + IF lo_drawing->get_type( ) = zcl_excel_drawing=>type_image_header_footer. + ADD 1 TO lv_relation_id. + lv_value = lv_relation_id. + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + lo_element = lo_document->create_simple_element( name = lc_xml_node_relationship + parent = lo_document ). + lo_element->set_attribute_ns( name = lc_xml_attr_id +* value = 'LOGO' ). + value = lv_value ). + lo_element->set_attribute_ns( name = lc_xml_attr_type + value = lc_xml_node_rid_image_tp ). + + lv_value = '../media/#'. + REPLACE '#' IN lv_value WITH lo_drawing->get_media_name( ). + lo_element->set_attribute_ns( name = lc_xml_attr_target +* value = '../media/LOGO.png' ). + value = lv_value ). + lo_element_root->append_child( new_child = lo_element ). + ENDIF. + + ENDWHILE. + + + +********************************************************************** +* STEP 5: Create xstring stream + lo_streamfactory = lo_ixml->create_stream_factory( ). + lo_ostream = lo_streamfactory->create_ostream_xstring( string = ep_content ). + lo_renderer = lo_ixml->create_renderer( ostream = lo_ostream document = lo_document ). + lo_renderer->render( ). + +ENDMETHOD. + + method CREATE_XL_DRAWING_ANCHOR. ** Constant node name @@ -3498,6 +3653,12 @@ METHOD create_xl_sheet. lc_xml_node_mergecells TYPE string VALUE 'mergeCells', lc_xml_node_drawing TYPE string VALUE 'drawing', lc_xml_node_drawing_for_cmt TYPE string VALUE 'legacyDrawing', + +********************************************************************** + lc_xml_node_drawing_for_hd_ft TYPE string VALUE 'legacyDrawingHF', +********************************************************************** + + lc_xml_node_headerfooter TYPE string VALUE 'headerFooter', lc_xml_node_oddheader TYPE string VALUE 'oddHeader', lc_xml_node_oddfooter TYPE string VALUE 'oddFooter', @@ -5063,6 +5224,30 @@ METHOD create_xl_sheet. ENDIF. * End - Add - Issue #180 +* Header/Footer Image + DATA: lo_drawing TYPE REF TO zcl_excel_drawing. + lo_iterator = me->excel->get_drawings_iterator( zcl_excel_drawing=>type_image ). + WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. + lo_drawing ?= lo_iterator->if_object_collection_iterator~get_next( ). + IF lo_drawing->get_type( ) = zcl_excel_drawing=>type_image_header_footer. + lo_element = lo_document->create_simple_element( name = lc_xml_node_drawing_for_hd_ft + parent = lo_document ). + ADD 1 TO lv_relation_id. " +1 for legacyDrawings + lv_value = lv_relation_id. + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + lo_element->set_attribute( name = 'r:id' + value = lv_value ). + lo_element_root->append_child( new_child = lo_element ). + + ADD 1 TO lv_relation_id. " +1 for comments (not referenced in XL sheet but let's reserve the rId) + EXIT. + ENDIF. + ENDWHILE. + + +* + * tables DATA lv_table_count TYPE i. @@ -5351,6 +5536,46 @@ METHOD create_xl_sheet_rels. ENDIF. * End - Add - Issue #180 +********************************************************************** +* header footer image + DATA: lo_drawing TYPE REF TO zcl_excel_drawing. + + lo_comments = io_worksheet->get_comments( ). + IF lo_comments->is_empty( ) = abap_true. +* lv_relation_id = 0. + lv_relation_id = iv_drawing_index. + lo_iterator = me->excel->get_drawings_iterator( zcl_excel_drawing=>type_image ). + WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. + lo_drawing ?= lo_iterator->if_object_collection_iterator~get_next( ). + IF lo_drawing->get_type( ) = zcl_excel_drawing=>type_image_header_footer. + ADD 1 TO lv_relation_id. + " Drawing for comment/header/footer + lo_element = lo_document->create_simple_element( name = lc_xml_node_relationship + parent = lo_document ). + lv_value = lv_relation_id. + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + lo_element->set_attribute_ns( name = lc_xml_attr_id + value = lv_value ). + lo_element->set_attribute_ns( name = lc_xml_attr_type + value = lc_xml_node_rid_drawing_cmt_tp ). + + lv_index_str = iv_comment_index. + CONDENSE lv_index_str NO-GAPS. + MOVE me->cl_xl_drawing_for_comments TO lv_value. + REPLACE 'xl' WITH '..' INTO lv_value. + REPLACE '#' WITH lv_index_str INTO lv_value. + lo_element->set_attribute_ns( name = lc_xml_attr_target + value = lv_value ). + lo_element_root->append_child( new_child = lo_element ). + EXIT. + ENDIF. + ENDWHILE. + ENDIF. +*** End Header Footer +********************************************************************** + + lo_iterator = io_worksheet->get_tables_iterator( ). WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. lo_table ?= lo_iterator->if_object_collection_iterator~get_next( ). @@ -7436,6 +7661,293 @@ METHOD render_ixml_element_no_header. ENDMETHOD. +METHOD set_vml_shape_footer. + + CONSTANTS: lc_shape TYPE string VALUE '', + lc_shape_image TYPE string VALUE '', + lc_shape_header_center TYPE string VALUE 'CH', + lc_shape_header_left TYPE string VALUE 'LH', + lc_shape_header_right TYPE string VALUE 'RH', + lc_shape_footer_center TYPE string VALUE 'CF', + lc_shape_footer_left TYPE string VALUE 'LF', + lc_shape_footer_right TYPE string VALUE 'RF'. + + DATA: lv_content_left TYPE string, + lv_content_center TYPE string, + lv_content_right TYPE string, + lv_content_image_left TYPE string, + lv_content_image_center TYPE string, + lv_content_image_right TYPE string, + lv_value TYPE string, + ls_drawing_position TYPE zexcel_drawing_position. + + IF is_footer-left_image IS NOT INITIAL. + lv_content_left = lc_shape. + REPLACE '{ID}' IN lv_content_left WITH lc_shape_footer_left. + ls_drawing_position = is_footer-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_left WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_left WITH lv_value. + lv_content_image_left = lc_shape_image. + lv_value = is_footer-left_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_left WITH lv_value. + ENDIF. + IF is_footer-center_image IS NOT INITIAL. + lv_content_center = lc_shape. + REPLACE '{ID}' IN lv_content_center WITH lc_shape_footer_center. + ls_drawing_position = is_footer-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_center WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_center WITH lv_value. + lv_content_image_center = lc_shape_image. + lv_value = is_footer-center_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_center WITH lv_value. + ENDIF. + IF is_footer-right_image IS NOT INITIAL. + lv_content_right = lc_shape. + REPLACE '{ID}' IN lv_content_right WITH lc_shape_footer_right. + ls_drawing_position = is_footer-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_right WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_right WITH lv_value. + lv_content_image_right = lc_shape_image. + lv_value = is_footer-right_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_right WITH lv_value. + ENDIF. + + CONCATENATE lv_content_left + lv_content_image_left + lv_content_center + lv_content_image_center + lv_content_right + lv_content_image_right + INTO ep_content. + +ENDMETHOD. + + +METHOD set_vml_shape_header. + +* CONSTANTS: lc_shape TYPE string VALUE '', + CONSTANTS: lc_shape TYPE string VALUE '', + lc_shape_image TYPE string VALUE '', + lc_shape_header_center TYPE string VALUE 'CH', + lc_shape_header_left TYPE string VALUE 'LH', + lc_shape_header_right TYPE string VALUE 'RH', + lc_shape_footer_center TYPE string VALUE 'CF', + lc_shape_footer_left TYPE string VALUE 'LF', + lc_shape_footer_right TYPE string VALUE 'RF'. + + DATA: lv_content_left TYPE string, + lv_content_center TYPE string, + lv_content_right TYPE string, + lv_content_image_left TYPE string, + lv_content_image_center TYPE string, + lv_content_image_right TYPE string, + lv_value TYPE string, + ls_drawing_position TYPE zexcel_drawing_position. + + CLEAR ep_content. + + IF is_header-left_image IS NOT INITIAL. + lv_content_left = lc_shape. + REPLACE '{ID}' IN lv_content_left WITH lc_shape_header_left. + ls_drawing_position = is_header-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_left WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_left WITH lv_value. + lv_content_image_left = lc_shape_image. + lv_value = is_header-left_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_left WITH lv_value. + ENDIF. + IF is_header-center_image IS NOT INITIAL. + lv_content_center = lc_shape. + REPLACE '{ID}' IN lv_content_center WITH lc_shape_header_center. + ls_drawing_position = is_header-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_center WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_center WITH lv_value. + lv_content_image_center = lc_shape_image. + lv_value = is_header-center_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_center WITH lv_value. + ENDIF. + IF is_header-right_image IS NOT INITIAL. + lv_content_right = lc_shape. + REPLACE '{ID}' IN lv_content_right WITH lc_shape_header_right. + ls_drawing_position = is_header-left_image->get_position( ). + IF ls_drawing_position-size-height IS NOT INITIAL. + lv_value = ls_drawing_position-size-height. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{HEIGHT}' IN lv_content_right WITH lv_value. + IF ls_drawing_position-size-width IS NOT INITIAL. + lv_value = ls_drawing_position-size-width. + ELSE. + lv_value = '100'. + ENDIF. + CONDENSE lv_value. + REPLACE '{WIDTH}' IN lv_content_right WITH lv_value. + lv_content_image_right = lc_shape_image. + lv_value = is_header-right_image->get_index( ). + CONDENSE lv_value. + CONCATENATE 'rId' lv_value INTO lv_value. + REPLACE '{RID}' IN lv_content_image_right WITH lv_value. + ENDIF. + + CONCATENATE lv_content_left + lv_content_image_left + lv_content_center + lv_content_image_center + lv_content_right + lv_content_image_right + INTO ep_content. + +ENDMETHOD. + + +METHOD set_vml_string. + + DATA: + ld_1 TYPE string, + ld_2 TYPE string, + ld_3 TYPE string, + ld_4 TYPE string, + ld_5 TYPE string, + ld_6 TYPE string, + ld_7 TYPE string, + + lv_value TYPE string, + lv_relation_id TYPE i, + lo_iterator TYPE REF TO cl_object_collection_iterator, + lo_drawing TYPE REF TO zcl_excel_drawing, + lo_worksheet TYPE REF TO zcl_excel_worksheet, + ls_odd_header TYPE zexcel_s_worksheet_head_foot, + ls_odd_footer TYPE zexcel_s_worksheet_head_foot, + ls_even_header TYPE zexcel_s_worksheet_head_foot, + ls_even_footer TYPE zexcel_s_worksheet_head_foot. + + +* INIT_RESULT + CLEAR ep_content. + + +* BODY + ld_1 = ''. + ld_2 = ''. + ld_3 = ''. + ld_4 = ''. + + + CONCATENATE ld_1 + ld_2 + ld_3 + ld_4 + INTO ep_content. + + lv_relation_id = 0. + lo_iterator = me->excel->get_worksheets_iterator( ). + WHILE lo_iterator->if_object_collection_iterator~has_next( ) EQ abap_true. + lo_worksheet ?= lo_iterator->if_object_collection_iterator~get_next( ). + + lo_worksheet->sheet_setup->get_header_footer( IMPORTING ep_odd_header = ls_odd_header + ep_odd_footer = ls_odd_footer + ep_even_header = ls_even_header + ep_even_footer = ls_even_footer ). + + ld_5 = me->set_vml_shape_header( ls_odd_header ). + CONCATENATE ep_content + ld_5 + INTO ep_content. + ld_5 = me->set_vml_shape_header( ls_even_header ). + CONCATENATE ep_content + ld_5 + INTO ep_content. + ld_5 = me->set_vml_shape_footer( ls_odd_footer ). + CONCATENATE ep_content + ld_5 + INTO ep_content. + ld_5 = me->set_vml_shape_footer( ls_even_footer ). + CONCATENATE ep_content + ld_5 + INTO ep_content. + ENDWHILE. + + ld_7 = ''. + + CONCATENATE ep_content + ld_7 + INTO ep_content. + +ENDMETHOD. + + method ZIF_EXCEL_WRITER~WRITE_FILE. me->excel = io_excel. diff --git a/src/zcl_excel_writer_2007.clas.xml b/src/zcl_excel_writer_2007.clas.xml index 8fa5a1c..c238d0a 100644 --- a/src/zcl_excel_writer_2007.clas.xml +++ b/src/zcl_excel_writer_2007.clas.xml @@ -121,6 +121,18 @@ I Create 'xl/drawings/_rels/drawing1.xml.rels' + + ZCL_EXCEL_WRITER_2007 + CREATE_XL_DRAWINGS_VML + E + Create 'xl/drawings/vmlDrawing1.vml' + + + ZCL_EXCEL_WRITER_2007 + CREATE_XL_DRAWINGS_VML_RELS + E + Create 'xl/drawings/_rel/vmlDrawing1.vml.rels' + ZCL_EXCEL_WRITER_2007 CREATE_XL_DRAWING_ANCHOR @@ -511,6 +523,24 @@ E Render ixml element - no header + + ZCL_EXCEL_WRITER_2007 + SET_VML_SHAPE_FOOTER + E + Create Shape VML Footer + + + ZCL_EXCEL_WRITER_2007 + SET_VML_SHAPE_HEADER + E + Create Shape VML Header + + + ZCL_EXCEL_WRITER_2007 + SET_VML_STRING + E + Create VML String + ZCL_EXCEL_WRITER_2007 SHARED_STRINGS diff --git a/src/zexcel_s_worksheet_head_foot.tabl.xml b/src/zexcel_s_worksheet_head_foot.tabl.xml index fb5c514..2121efb 100644 --- a/src/zexcel_s_worksheet_head_foot.tabl.xml +++ b/src/zexcel_s_worksheet_head_foot.tabl.xml @@ -64,6 +64,39 @@ STRUS S + + ZEXCEL_S_WORKSHEET_HEAD_FOOT + LEFT_IMAGE + 0049 + ZCL_EXCEL_DRAWING + 0 + REF + REF RC + R + C + + + ZEXCEL_S_WORKSHEET_HEAD_FOOT + RIGHT_IMAGE + 0050 + ZCL_EXCEL_DRAWING + 0 + REF + REF RC + R + C + + + ZEXCEL_S_WORKSHEET_HEAD_FOOT + CENTER_IMAGE + 0051 + ZCL_EXCEL_DRAWING + 0 + REF + REF RC + R + C + diff --git a/src/ztest_excel_image_header.prog.abap b/src/ztest_excel_image_header.prog.abap new file mode 100644 index 0000000..49669fb --- /dev/null +++ b/src/ztest_excel_image_header.prog.abap @@ -0,0 +1,81 @@ +*&---------------------------------------------------------------------* +*& Report ZTEST_EXCEL_IMAGE_HEADER +*& +*&---------------------------------------------------------------------* +*& +*& +*&---------------------------------------------------------------------* + +REPORT ztest_excel_image_header. + +DATA: lo_excel TYPE REF TO zcl_excel, + lo_worksheet TYPE REF TO zcl_excel_worksheet, + lo_drawing TYPE REF TO zcl_excel_drawing, + ls_key TYPE wwwdatatab, + ls_header TYPE zexcel_s_worksheet_head_foot, + ls_footer TYPE zexcel_s_worksheet_head_foot, + lv_content TYPE xstring, + lo_bitmap TYPE REF TO zcl_abap_bitmap. + + +DATA: ls_io TYPE skwf_io. + +CONSTANTS: gc_save_file_name TYPE string VALUE 'Image_Header_Footer.xlsx'. +INCLUDE zdemo_excel_outputopt_incl. + +START-OF-SELECTION. + + " Creates active sheet + CREATE OBJECT lo_excel. + +********************************************************************** +*** Header Center + " create global drawing, set position and media from web repository + lo_drawing = lo_excel->add_new_drawing( ip_type = zcl_excel_drawing=>type_image_header_footer ). + + ls_key-relid = 'MI'. + ls_key-objid = 'SAPLOGO.GIF'. + lo_drawing->set_media_www( ip_key = ls_key + ip_width = 166 + ip_height = 75 ). +********************************************************************** + ls_header-center_image = lo_drawing. + + +********************************************************************** +*** Header Left + " create global drawing, set position and media from web repository + lo_drawing = lo_excel->add_new_drawing( ip_type = zcl_excel_drawing=>type_image_header_footer ). + + ls_key-relid = 'MI'. + ls_key-objid = 'SAPLOGO.GIF'. + lo_drawing->set_media_www( ip_key = ls_key + ip_width = 166 + ip_height = 75 ). + + + ls_header-left_image = ls_footer-left_image = lo_drawing. + ls_header-left_value = 'Hallo'. + lo_worksheet = lo_excel->get_active_worksheet( ). + + lo_worksheet->sheet_setup->set_header_footer( ip_odd_header = ls_header + ip_odd_footer = ls_footer ). + +********************************************************************** +*** Normal Image + " create global drawing, set position and media from web repository + lo_drawing = lo_excel->add_new_drawing( ). + lo_drawing->set_position( ip_from_row = 3 + ip_from_col = 'B' ). + + ls_key-relid = 'MI'. + ls_key-objid = 'SAPLOGO.GIF'. + lo_drawing->set_media_www( ip_key = ls_key + ip_width = 166 + ip_height = 75 ). + + " assign drawing to the worksheet + lo_worksheet->add_drawing( lo_drawing ). + +*** Create output + lcl_output=>output( lo_excel ). diff --git a/src/ztest_excel_image_header.prog.xml b/src/ztest_excel_image_header.prog.xml new file mode 100644 index 0000000..2fe394f --- /dev/null +++ b/src/ztest_excel_image_header.prog.xml @@ -0,0 +1,28 @@ + + + + + + ZTEST_EXCEL_IMAGE_HEADER + A + X + 1 + D + X + X + + + + D + + + R + Image Excel header + 18 + + + + + + +