Fix #486 Multiple Styles in One Cell ("rich text format") (#852)

* Final modifications - All good

* Lint 7.02 + reader huge was forgotten

Co-authored-by: sandraros <sandra.rossi@gmail.com>
Co-authored-by: sandraros <sandraros@gmail.com>
This commit is contained in:
sandraros 2021-10-24 16:07:58 +02:00 committed by GitHub
parent b31f1730d2
commit 5da41aaab2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 437 additions and 17 deletions

View File

@ -0,0 +1,116 @@
*&---------------------------------------------------------------------*
*& Report zdemo_excel48
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zdemo_excel48.
DATA:
lo_excel TYPE REF TO zcl_excel,
lo_worksheet TYPE REF TO zcl_excel_worksheet,
lo_style_1 TYPE REF TO zcl_excel_style,
lo_style_2 TYPE REF TO zcl_excel_style,
lv_style_1_guid TYPE zexcel_cell_style,
lv_style_2_guid TYPE zexcel_cell_style,
lv_value TYPE string,
ls_rtf TYPE zexcel_s_rtf,
lt_rtf TYPE zexcel_t_rtf.
CONSTANTS:
gc_save_file_name TYPE string VALUE '48_MultipleStylesInOneCell.xlsx'.
INCLUDE zdemo_excel_outputopt_incl.
START-OF-SELECTION.
CREATE OBJECT lo_excel.
lo_worksheet = lo_excel->get_active_worksheet( ).
lo_style_1 = lo_excel->add_new_style( ).
lo_style_1->font->color-rgb = 'FF000000'.
lv_value = 'normal red underline normal red-underline bold italic bigger Times-New-Roman'.
" red
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->color-rgb = 'FFFF0000'.
ls_rtf-offset = 7.
ls_rtf-length = 3.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" underline
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->underline = abap_true.
lo_style_2->font->underline_mode = lo_style_2->font->c_underline_single.
ls_rtf-offset = 11.
ls_rtf-length = 9.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" red and underline
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->color-rgb = 'FFFF0000'.
lo_style_2->font->underline = abap_true.
lo_style_2->font->underline_mode = lo_style_2->font->c_underline_single.
ls_rtf-offset = 28.
ls_rtf-length = 13.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" bold
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->bold = abap_true.
ls_rtf-offset = 42.
ls_rtf-length = 4.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" italic
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->italic = abap_true.
ls_rtf-offset = 47.
ls_rtf-length = 6.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" bigger
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->size = 28.
ls_rtf-offset = 54.
ls_rtf-length = 6.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
" Times-New-Roman
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->name = zcl_excel_style_font=>c_name_roman.
lo_style_2->font->scheme = zcl_excel_style_font=>c_scheme_none.
lo_style_2->font->family = zcl_excel_style_font=>c_family_roman.
" Create an underline double style
lo_style_2 = lo_excel->add_new_style( ).
lo_style_2->font->underline = abap_true.
lo_style_2->font->underline_mode = zcl_excel_style_font=>c_underline_double.
lo_style_2->font->name = zcl_excel_style_font=>c_name_roman.
lo_style_2->font->scheme = zcl_excel_style_font=>c_scheme_none.
lo_style_2->font->family = zcl_excel_style_font=>c_family_roman.
lv_style_2_guid = lo_style_2->get_guid( ).
ls_rtf-offset = 61.
ls_rtf-length = 15.
ls_rtf-font = lo_style_2->font->get_structure( ).
INSERT ls_rtf INTO TABLE lt_rtf.
lv_style_1_guid = lo_style_1->get_guid( ).
lo_worksheet->set_cell(
ip_column = 'B'
ip_row = 2
ip_style = lo_style_1->get_guid( )
ip_value = lv_value
it_rtf = lt_rtf ).
*** Create output
lcl_output=>output( lo_excel ).

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_PROG" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<PROGDIR>
<NAME>ZDEMO_EXCEL48</NAME>
<DBAPL>S</DBAPL>
<DBNA>D$</DBNA>
<SUBC>1</SUBC>
<FIXPT>X</FIXPT>
<LDBNAME>D$S</LDBNAME>
<UCCHECK>X</UCCHECK>
</PROGDIR>
<TPOOL>
<item>
<ID>R</ID>
<ENTRY>abap2xlsx Demo: multiple styles in one cell</ENTRY>
<LENGTH>43</LENGTH>
</item>
</TPOOL>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -100,8 +100,15 @@ CLASS zcl_excel_reader_2007 DEFINITION
END OF ty_ref_formulae .
TYPES:
tyt_ref_formulae TYPE HASHED TABLE OF ty_ref_formulae WITH UNIQUE KEY sheet row column .
TYPES:
BEGIN OF t_shared_string,
value TYPE string,
rtf TYPE zexcel_t_rtf,
END OF t_shared_string .
TYPES:
t_shared_strings TYPE STANDARD TABLE OF t_shared_string WITH DEFAULT KEY .
DATA shared_strings TYPE stringtab .
DATA shared_strings TYPE t_shared_strings .
DATA styles TYPE t_style_refs .
DATA mt_ref_formulae TYPE tyt_ref_formulae .
DATA mt_dxf_styles TYPE zexcel_t_styles_cond_mapping .
@ -865,10 +872,14 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
lo_node_si TYPE REF TO if_ixml_element,
lo_node_si_child TYPE REF TO if_ixml_element,
lo_node_r_child_t TYPE REF TO if_ixml_element,
lo_node_r_child_rPr TYPE REF TO if_ixml_element,
lo_font TYPE REF TO zcl_excel_style_font,
ls_rtf TYPE zexcel_s_rtf,
lv_current_offset TYPE int2,
lv_tag_name TYPE string,
lv_node_value TYPE string.
FIELD-SYMBOLS: <lv_shared_string> LIKE LINE OF me->shared_strings.
FIELD-SYMBOLS: <ls_shared_string> LIKE LINE OF me->shared_strings.
*--------------------------------------------------------------------*
@ -921,7 +932,7 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
lo_node_si ?= lo_shared_strings_xml->find_from_name( 'si' ).
WHILE lo_node_si IS BOUND.
APPEND INITIAL LINE TO me->shared_strings ASSIGNING <lv_shared_string>. " Each <si>-entry in the xml-file must lead to an entry in our stringtable
APPEND INITIAL LINE TO me->shared_strings ASSIGNING <ls_shared_string>. " Each <si>-entry in the xml-file must lead to an entry in our stringtable
lo_node_si_child ?= lo_node_si->get_first_child( ).
IF lo_node_si_child IS BOUND.
lv_tag_name = lo_node_si_child->get_name( ).
@ -930,7 +941,7 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
* §1.1 - "simple" strings
* Example: see above
*--------------------------------------------------------------------*
<lv_shared_string> = lo_node_si_child->get_value( ).
<ls_shared_string>-value = lo_node_si_child->get_value( ).
ELSE.
*--------------------------------------------------------------------*
* §1.2 - rich text formatted strings
@ -938,14 +949,26 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
* as long as rich text formatting is not supported (2do§1) ignore all info about formatting
* Example: see above
*--------------------------------------------------------------------*
CLEAR: lv_current_offset.
WHILE lo_node_si_child IS BOUND. " actually these children of <si> are <r>-tags
CLEAR: ls_rtf.
lo_node_r_child_rpr ?= lo_node_si_child->find_from_name( 'rPr' ). " extracting rich text formating data
IF lo_node_r_child_rpr IS BOUND.
lo_font = load_style_font( lo_node_r_child_rpr ).
ls_rtf-font = lo_font->get_structure( ).
ENDIF.
ls_rtf-offset = lv_current_offset.
lo_node_r_child_t ?= lo_node_si_child->find_from_name( 't' ). " extract the <t>...</t> part of each <r>-tag
IF lo_node_r_child_t IS BOUND.
lv_node_value = lo_node_r_child_t->get_value( ).
CONCATENATE <lv_shared_string> lv_node_value INTO <lv_shared_string> RESPECTING BLANKS.
CONCATENATE <ls_shared_string>-value lv_node_value INTO <ls_shared_string>-value RESPECTING BLANKS.
ls_rtf-length = strlen( lv_node_value ).
ENDIF.
lv_current_offset = strlen( <ls_shared_string>-value ).
APPEND ls_rtf TO <ls_shared_string>-rtf.
lo_node_si_child ?= lo_node_si_child->get_next( ).
ENDWHILE.
@ -1546,6 +1569,11 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
lo_node2 = lo_node_font->find_from_name( 'name' ).
IF lo_node2 IS BOUND.
lo_font->name = lo_node2->get_attribute( 'val' ).
ELSE.
lo_node2 = lo_node_font->find_from_name( 'rFont' ).
IF lo_node2 IS BOUND.
lo_font->name = lo_node2->get_attribute( 'val' ).
ENDIF.
ENDIF.
*--------------------------------------------------------------------*
@ -2342,8 +2370,12 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
lo_data_validation TYPE REF TO zcl_excel_data_validation,
lv_datavalidation_range TYPE string,
lt_datavalidation_range TYPE TABLE OF string,
lt_rtf TYPE zexcel_t_rtf,
ex TYPE REF TO cx_root.
FIELD-SYMBOLS:
<ls_shared_string> TYPE t_shared_string.
*--------------------------------------------------------------------*
* §2 We need to read the the file "\\_rels\.rels" because it tells
* us where in this folder structure the data for the workbook
@ -2483,7 +2515,11 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
WHEN 's'. " String values are stored as index in shared string table
IF lo_ixml_value_elem IS BOUND.
lv_index = lo_ixml_value_elem->get_value( ) + 1.
READ TABLE shared_strings INTO lv_cell_value INDEX lv_index.
READ TABLE shared_strings ASSIGNING <ls_shared_string> INDEX lv_index.
IF sy-subrc = 0.
lv_cell_value = <ls_shared_string>-value.
lt_rtf = <ls_shared_string>-rtf.
ENDIF.
ENDIF.
WHEN 'inlineStr'. " inlineStr values are kept in special node
lo_ixml_value_elem = lo_ixml_cell_elem->find_from_name( name = 'is' ).
@ -2560,7 +2596,8 @@ CLASS zcl_excel_reader_2007 IMPLEMENTATION.
ip_value = lv_cell_value " cell_elem Value
ip_formula = lv_cell_formula
ip_data_type = ls_cell-t
ip_style = lv_style_guid ).
ip_style = lv_style_guid
it_rtf = lt_rtf ).
ENDIF.
lo_ixml_cell_elem ?= lo_ixml_iterator2->get_next( ).
ENDWHILE.

View File

@ -141,14 +141,16 @@ CLASS zcl_excel_reader_huge_file IMPLEMENTATION.
METHOD get_shared_string.
DATA: lv_tabix TYPE i,
lv_error TYPE string.
FIELD-SYMBOLS: <ls_shared_string> TYPE t_shared_string.
lv_tabix = iv_index + 1.
READ TABLE shared_strings INTO ev_value INDEX lv_tabix.
READ TABLE shared_strings ASSIGNING <ls_shared_string> INDEX lv_tabix.
IF sy-subrc NE 0.
CONCATENATE 'Entry ' iv_index ' not found in Shared String Table' INTO lv_error.
RAISE EXCEPTION TYPE lcx_not_found
EXPORTING
error = lv_error.
ENDIF.
ev_value = <ls_shared_string>-value.
ENDMETHOD.
@ -190,10 +192,17 @@ CLASS zcl_excel_reader_huge_file IMPLEMENTATION.
METHOD load_shared_strings.
DATA: lo_reader TYPE REF TO if_sxml_reader.
DATA: lt_shared_strings TYPE TABLE OF string,
ls_shared_string TYPE t_shared_string.
FIELD-SYMBOLS: <lv_shared_string> TYPE string.
lo_reader = get_sxml_reader( ip_path ).
shared_strings = read_shared_strings( lo_reader ).
lt_shared_strings = read_shared_strings( lo_reader ).
LOOP AT lt_shared_strings ASSIGNING <lv_shared_string>.
ls_shared_string-value = <lv_shared_string>.
APPEND ls_shared_string TO shared_strings.
ENDLOOP.
ENDMETHOD.

View File

@ -51,8 +51,11 @@ class lcl_test implementation.
*
method test_shared_string.
data lo_reader type ref to if_sxml_reader.
append `Test1` to out->shared_strings.
append `Test2` to out->shared_strings.
data: ls_shared_string type zcl_excel_reader_huge_file=>t_shared_string.
ls_shared_string-value = `Test1`.
append ls_shared_string to out->shared_strings.
ls_shared_string-value = `Test2`.
append ls_shared_string to out->shared_strings.
lo_reader = get_reader(
`<c r="A1" t="s"><v>1</v></c>`
).
@ -66,7 +69,9 @@ class lcl_test implementation.
data: lo_reader type ref to if_sxml_reader,
lo_ex type ref to lcx_not_found,
lv_text type string.
append `Test` to out->shared_strings.
data: ls_shared_string type zcl_excel_reader_huge_file=>t_shared_string.
ls_shared_string-value = `Test`.
append ls_shared_string to out->shared_strings.
lo_reader = get_reader(
`<c r="A1" t="s"><v>1</v></c>`
).
@ -118,8 +123,11 @@ class lcl_test implementation.
* There is no need to store an empty cell in the ABAP worksheet structure
data: lo_reader type ref to if_sxml_reader.
append `` to out->shared_strings.
append `t` to out->shared_strings.
data: ls_shared_string type zcl_excel_reader_huge_file=>t_shared_string.
ls_shared_string-value = ``.
append ls_shared_string to out->shared_strings.
ls_shared_string-value = `t`.
append ls_shared_string to out->shared_strings.
lo_reader = get_reader(
`<c r="A1" t="s"><v>0</v></c>` &
`<c r="A2" t="inlineStr"><is><t></t></is></c>` &

View File

@ -317,6 +317,7 @@ CLASS zcl_excel_worksheet DEFINITION
!ep_style TYPE REF TO zcl_excel_style
!ep_guid TYPE zexcel_cell_style
!ep_formula TYPE zexcel_cell_formula
!et_rtf TYPE zexcel_t_rtf
RAISING
zcx_excel .
METHODS get_column
@ -462,6 +463,7 @@ CLASS zcl_excel_worksheet DEFINITION
!ip_hyperlink TYPE REF TO zcl_excel_hyperlink OPTIONAL
!ip_data_type TYPE zexcel_cell_data_type OPTIONAL
!ip_abap_type TYPE abap_typekind OPTIONAL
!it_rtf TYPE zexcel_t_rtf OPTIONAL
!ip_column_formula_id TYPE mty_s_column_formula-id OPTIONAL
RAISING
zcx_excel .
@ -697,6 +699,14 @@ CLASS zcl_excel_worksheet DEFINITION
ip_column TYPE zexcel_cell_column
RAISING
zcx_excel.
METHODS check_rtf
IMPORTING
!ip_value TYPE simple
VALUE(ip_style) TYPE zexcel_cell_style OPTIONAL
CHANGING
!ct_rtf TYPE zexcel_t_rtf
RAISING
zcx_excel .
METHODS generate_title
RETURNING
VALUE(ep_title) TYPE zexcel_sheet_title .
@ -1831,6 +1841,62 @@ CLASS zcl_excel_worksheet IMPLEMENTATION.
ENDMETHOD.
METHOD check_rtf.
DATA: lo_style TYPE REF TO zcl_excel_style,
lo_iterator TYPE REF TO cl_object_collection_iterator,
lv_next_rtf_offset TYPE i,
lv_tabix TYPE i,
lv_value TYPE string,
lv_val_length TYPE i,
ls_rtf LIKE LINE OF ct_rtf.
FIELD-SYMBOLS: <rtf> LIKE LINE OF ct_rtf.
IF ip_style IS NOT SUPPLIED.
ip_style = excel->get_default_style( ).
ENDIF.
lo_iterator = excel->get_styles_iterator( ).
WHILE lo_iterator->has_next( ) = abap_true.
lo_style ?= lo_iterator->get_next( ).
IF lo_style->get_guid( ) = ip_style.
EXIT.
ENDIF.
CLEAR lo_style.
ENDWHILE.
lv_next_rtf_offset = 0.
LOOP AT ct_rtf ASSIGNING <rtf>.
lv_tabix = sy-tabix.
IF lv_next_rtf_offset < <rtf>-offset.
ls_rtf-offset = lv_next_rtf_offset.
ls_rtf-length = <rtf>-offset - lv_next_rtf_offset.
ls_rtf-font = lo_style->font->get_structure( ).
INSERT ls_rtf INTO ct_rtf INDEX lv_tabix.
ELSEIF lv_next_rtf_offset > <rtf>-offset.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Gaps or overlaps in RTF data offset/length specs'.
ENDIF.
lv_next_rtf_offset = <rtf>-offset + <rtf>-length.
ENDLOOP.
lv_value = ip_value.
lv_val_length = strlen( lv_value ).
IF lv_val_length > lv_next_rtf_offset.
ls_rtf-offset = lv_next_rtf_offset.
ls_rtf-length = lv_val_length - lv_next_rtf_offset.
ls_rtf-font = lo_style->font->get_structure( ).
INSERT ls_rtf INTO TABLE ct_rtf.
ELSEIF lv_val_length > lv_next_rtf_offset.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'RTF specs length is not equal to value length'.
ENDIF.
ENDMETHOD.
METHOD class_constructor.
c_messages-formula_id_only_is_possible = |{ 'If Formula ID is used, value and formula must be empty'(008) }|.
@ -2010,6 +2076,9 @@ CLASS zcl_excel_worksheet IMPLEMENTATION.
ep_value = ls_sheet_content-cell_value.
ep_guid = ls_sheet_content-cell_style. " issue 139 - added this to be used for columnwidth calculation
ep_formula = ls_sheet_content-cell_formula.
IF et_rtf IS SUPPLIED AND ls_sheet_content-rtf_tab IS NOT INITIAL.
et_rtf = ls_sheet_content-rtf_tab.
ENDIF.
" Addition to solve issue #120, contribution by Stefan Schmöcker
DATA: style_iterator TYPE REF TO cl_object_collection_iterator,
@ -3017,6 +3086,7 @@ CLASS zcl_excel_worksheet IMPLEMENTATION.
lv_value_type TYPE abap_typekind,
lv_style_guid TYPE zexcel_cell_style,
lo_addit TYPE REF TO cl_abap_elemdescr,
lt_rtf TYPE zexcel_t_rtf,
lo_value TYPE REF TO data,
lo_value_new TYPE REF TO data.
@ -3213,6 +3283,14 @@ CLASS zcl_excel_worksheet IMPLEMENTATION.
ENDIF.
IF ip_formula IS INITIAL AND lv_value IS NOT INITIAL AND it_rtf IS NOT INITIAL.
lt_rtf = it_rtf.
check_rtf( EXPORTING ip_value = lv_value
ip_style = lv_style_guid
CHANGING ct_rtf = lt_rtf ).
<fs_sheet_content>-rtf_tab = lt_rtf.
ENDIF.
* Begin of change issue #152 - don't touch exisiting style if only value is passed
* For Date- or Timefields change the formatcode if nothing is set yet
* Enhancement option: Check if existing formatcode is a date/ or timeformat

View File

@ -155,7 +155,8 @@ CLASS zcl_excel_writer_2007 DEFINITION
IMPORTING
!io_document TYPE REF TO if_ixml_document
!io_parent TYPE REF TO if_ixml_element
!is_font TYPE zexcel_s_style_font .
!is_font TYPE zexcel_s_style_font
!iv_use_rtf TYPE abap_bool DEFAULT abap_false .
METHODS create_xl_table
IMPORTING
!io_table TYPE REF TO zcl_excel_table
@ -170,6 +171,7 @@ CLASS zcl_excel_writer_2007 DEFINITION
METHODS get_shared_string_index
IMPORTING
!ip_cell_value TYPE zexcel_cell_value
!it_rtf TYPE zexcel_t_rtf OPTIONAL
RETURNING
VALUE(ep_index) TYPE int4 .
METHODS create_xl_drawings_vml
@ -3546,6 +3548,8 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
DATA: lc_xml_node_sst TYPE string VALUE 'sst',
lc_xml_node_si TYPE string VALUE 'si',
lc_xml_node_t TYPE string VALUE 't',
lc_xml_node_r TYPE string VALUE 'r',
lc_xml_node_rpr TYPE string VALUE 'rPr',
" Node attributes
lc_xml_attr_count TYPE string VALUE 'count',
lc_xml_attr_uniquecount TYPE string VALUE 'uniqueCount',
@ -3556,10 +3560,14 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
lo_element_root TYPE REF TO if_ixml_element,
lo_element TYPE REF TO if_ixml_element,
lo_sub_element TYPE REF TO if_ixml_element,
lo_sub2_element TYPE REF TO if_ixml_element,
lo_font_element TYPE REF TO if_ixml_element,
lo_iterator TYPE REF TO cl_object_collection_iterator,
lo_worksheet TYPE REF TO zcl_excel_worksheet.
DATA: lt_cell_data TYPE zexcel_t_cell_data_unsorted,
lt_cell_data_rtf TYPE zexcel_t_cell_data_unsorted,
lv_value TYPE string,
ls_shared_string TYPE zexcel_s_shared_string,
lv_count_str TYPE string,
lv_uniquecount_str TYPE string,
@ -3568,6 +3576,7 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
lv_uniquecount TYPE i.
FIELD-SYMBOLS: <fs_sheet_content> TYPE zexcel_s_cell_data,
<fs_rtf> TYPE zexcel_s_rtf,
<fs_sheet_string> TYPE zexcel_s_shared_string.
**********************************************************************
@ -3584,12 +3593,25 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
DESCRIBE TABLE lt_cell_data LINES lv_count.
MOVE lv_count TO lv_count_str.
" separating plain and rich text format strings
lt_cell_data_rtf = lt_cell_data.
DELETE lt_cell_data WHERE rtf_tab IS NOT INITIAL.
DELETE lt_cell_data_rtf WHERE rtf_tab IS INITIAL.
SHIFT lv_count_str RIGHT DELETING TRAILING space.
SHIFT lv_count_str LEFT DELETING LEADING space.
SORT lt_cell_data BY cell_value data_type.
DELETE ADJACENT DUPLICATES FROM lt_cell_data COMPARING cell_value data_type.
" leave unique rich text format strings
SORT lt_cell_data_rtf BY cell_value rtf_tab.
DELETE ADJACENT DUPLICATES FROM lt_cell_data_rtf COMPARING cell_value rtf_tab.
" merge into single list
APPEND LINES OF lt_cell_data_rtf TO lt_cell_data.
SORT lt_cell_data BY cell_value rtf_tab.
FREE lt_cell_data_rtf.
DESCRIBE TABLE lt_cell_data LINES lv_uniquecount.
MOVE lv_uniquecount TO lv_uniquecount_str.
@ -3603,6 +3625,7 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
MOVE lv_sytabix TO ls_shared_string-string_no.
MOVE <fs_sheet_content>-cell_value TO ls_shared_string-string_value.
MOVE <fs_sheet_content>-data_type TO ls_shared_string-string_type.
ls_shared_string-rtf_tab = <fs_sheet_content>-rtf_tab.
INSERT ls_shared_string INTO TABLE shared_strings.
ADD 1 TO lv_count.
ENDLOOP.
@ -3628,6 +3651,7 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
LOOP AT shared_strings ASSIGNING <fs_sheet_string>.
lo_element = lo_document->create_simple_element( name = lc_xml_node_si
parent = lo_document ).
IF <fs_sheet_string>-rtf_tab IS INITIAL.
lo_sub_element = lo_document->create_simple_element( name = lc_xml_node_t
parent = lo_document ).
IF boolc( contains( val = <fs_sheet_string>-string_value start = ` ` ) ) = abap_true
@ -3635,6 +3659,34 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
lo_sub_element->set_attribute( name = 'space' namespace = 'xml' value = 'preserve' ).
ENDIF.
lo_sub_element->set_value( value = <fs_sheet_string>-string_value ).
ELSE.
LOOP AT <fs_sheet_string>-rtf_tab ASSIGNING <fs_rtf>.
lo_sub_element = lo_document->create_simple_element( name = lc_xml_node_r
parent = lo_element ).
TRY.
lv_value = substring( val = <fs_sheet_string>-string_value
off = <fs_rtf>-offset
len = <fs_rtf>-length ).
CATCH cx_sy_range_out_of_bounds.
EXIT.
ENDTRY.
IF <fs_rtf>-font IS NOT INITIAL.
lo_font_element = lo_document->create_simple_element( name = lc_xml_node_rpr
parent = lo_sub_element ).
create_xl_styles_font_node( io_document = lo_document
io_parent = lo_font_element
is_font = <fs_rtf>-font
iv_use_rtf = abap_true ).
ENDIF.
lo_sub2_element = lo_document->create_simple_element( name = lc_xml_node_t
parent = lo_sub_element ).
IF boolc( contains( val = lv_value start = ` ` ) ) = abap_true
OR boolc( contains( val = lv_value end = ` ` ) ) = abap_true.
lo_sub2_element->set_attribute( name = 'space' namespace = 'xml' value = 'preserve' ).
ENDIF.
lo_sub2_element->set_value( lv_value ).
ENDLOOP.
ENDIF.
lo_element->append_child( new_child = lo_sub_element ).
lo_element_root->append_child( new_child = lo_element ).
ENDLOOP.
@ -6227,7 +6279,8 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
parent = io_document ).
IF <ls_sheet_content>-data_type EQ 's' OR <ls_sheet_content>-data_type EQ 's_leading_blanks'.
lv_value = me->get_shared_string_index( <ls_sheet_content>-cell_value ).
lv_value = me->get_shared_string_index( ip_cell_value = <ls_sheet_content>-cell_value
it_rtf = <ls_sheet_content>-rtf_tab ).
CONDENSE lv_value.
lo_element_4->set_value( value = lv_value ).
ELSE.
@ -7231,6 +7284,7 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
lc_xml_node_strike TYPE string VALUE 'strike', "strikethrough
lc_xml_node_sz TYPE string VALUE 'sz',
lc_xml_node_name TYPE string VALUE 'name',
lc_xml_node_rfont TYPE string VALUE 'rFont',
lc_xml_node_family TYPE string VALUE 'family',
lc_xml_node_scheme TYPE string VALUE 'scheme',
lc_xml_attr_val TYPE string VALUE 'val'.
@ -7284,8 +7338,13 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
is_color = ls_font-color ).
"name
IF iv_use_rtf = abap_false.
lo_sub_element = lo_document->create_simple_element( name = lc_xml_node_name
parent = lo_document ).
ELSE.
lo_sub_element = lo_document->create_simple_element( name = lc_xml_node_rfont
parent = lo_document ).
ENDIF.
lv_value = ls_font-name.
lo_sub_element->set_attribute_ns( name = lc_xml_attr_val
value = lv_value ).
@ -7845,8 +7904,17 @@ CLASS zcl_excel_writer_2007 IMPLEMENTATION.
DATA ls_shared_string TYPE zexcel_s_shared_string.
* READ TABLE shared_strings INTO ls_shared_string WITH KEY string_value = ip_cell_value BINARY SEARCH.
IF it_rtf IS INITIAL.
READ TABLE shared_strings INTO ls_shared_string WITH TABLE KEY string_value = ip_cell_value.
ep_index = ls_shared_string-string_no.
ELSE.
LOOP AT shared_strings INTO ls_shared_string WHERE string_value = ip_cell_value
AND rtf_tab = it_rtf.
ep_index = ls_shared_string-string_no.
EXIT.
ENDLOOP.
ENDIF.
ENDMETHOD.

View File

@ -804,7 +804,8 @@ CLASS zcl_excel_writer_huge_file IMPLEMENTATION.
<cell>-formula = <content>-cell_formula.
<cell>-type = <content>-data_type.
IF <cell>-type = 's'.
<cell>-value = me->get_shared_string_index( <content>-cell_value ).
<cell>-value = me->get_shared_string_index( ip_cell_value = <content>-cell_value
ir_rtf = <content>-rtf_tab ).
ELSE.
<cell>-value = <content>-cell_value.
ENDIF.

View File

@ -63,6 +63,14 @@
<MASK> INT4</MASK>
<DDTEXT>Column Formula ID</DDTEXT>
</DD03P>
<DD03P>
<FIELDNAME>RTF_TAB</FIELDNAME>
<ROLLNAME>ZEXCEL_T_RTF</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<DATATYPE>TTYP</DATATYPE>
<MASK> TTYPL</MASK>
<COMPTYPE>L</COMPTYPE>
</DD03P>
</DD03P_TABLE>
</asx:values>
</asx:abap>

36
src/zexcel_s_rtf.tabl.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD02V>
<TABNAME>ZEXCEL_S_RTF</TABNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<TABCLASS>INTTAB</TABCLASS>
<DDTEXT>Rich Text Formating Data Record</DDTEXT>
<EXCLASS>4</EXCLASS>
</DD02V>
<DD03P_TABLE>
<DD03P>
<FIELDNAME>OFFSET</FIELDNAME>
<ROLLNAME>INT2</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>LENGTH</FIELDNAME>
<ROLLNAME>INT2</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>FONT</FIELDNAME>
<ROLLNAME>ZEXCEL_S_STYLE_FONT</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<DATATYPE>STRU</DATATYPE>
<MASK> STRUS</MASK>
<COMPTYPE>S</COMPTYPE>
</DD03P>
</DD03P_TABLE>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -7,6 +7,7 @@
<DDLANGUAGE>E</DDLANGUAGE>
<TABCLASS>INTTAB</TABCLASS>
<DDTEXT>Shared strings</DDTEXT>
<MASTERLANG>E</MASTERLANG>
<EXCLASS>1</EXCLASS>
</DD02V>
<DD03P_TABLE>
@ -28,6 +29,14 @@
<ADMINFIELD>0</ADMINFIELD>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>RTF_TAB</FIELDNAME>
<ROLLNAME>ZEXCEL_T_RTF</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<DATATYPE>TTYP</DATATYPE>
<MASK> TTYPL</MASK>
<COMPTYPE>L</COMPTYPE>
</DD03P>
</DD03P_TABLE>
</asx:values>
</asx:abap>

27
src/zexcel_t_rtf.ttyp.xml Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TTYP" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD40V>
<TYPENAME>ZEXCEL_T_RTF</TYPENAME>
<DDLANGUAGE>E</DDLANGUAGE>
<ROWTYPE>ZEXCEL_S_RTF</ROWTYPE>
<ROWKIND>S</ROWKIND>
<DATATYPE>STRU</DATATYPE>
<ACCESSMODE>S</ACCESSMODE>
<KEYDEF>K</KEYDEF>
<KEYKIND>U</KEYKIND>
<KEYFDCOUNT>0001</KEYFDCOUNT>
<DDTEXT>Rich Text Formating Data</DDTEXT>
</DD40V>
<DD42V>
<DD42V>
<TYPENAME>ZEXCEL_T_RTF</TYPENAME>
<KEYFDPOS>0001</KEYFDPOS>
<ROWTYPEPOS>0001</ROWTYPEPOS>
<KEYFIELD>OFFSET</KEYFIELD>
</DD42V>
</DD42V>
</asx:values>
</asx:abap>
</abapGit>