Skip to Content
Author's profile photo Pavol Olejar

OpenXML in word processing – how to merge multiple word documents into one using altChunk – preparation of code

In my previous blog I described how to use altChunk for merging of documents into one word document. In this blog I describe necessary steps to enhance, copy and change standard classes in order to be able to use altChunk technique in ABAP. Before you go through this I reccomend to start with this blog as intoridction to OpenXML in word processing with ABAP.

Now let’s discuss steps which need to be done if we want to use altChunk.

1. Class CL_DOCX_ALTERNATIVEFORMATPART

As mentioned above alternative part can have couple of content types. Standard sap class does not have one we need which is content type representing word document. Word document is stored in alternative part with *.dat extension. So we enhance class and add following into attributes to support this option:

  • CO_CONTENT_TYPE_WORD – application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
  • CO_FILEEXT_WORD – dat
  • CO_CONTENT_TYPE_WORDT – application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml
  • CO_FILEEXT_WORDT – dat

Word here stands for word document and wordt stands for word template. In picture I highlighted standard content types and added content types and also extension types for each content type.

2. Class CL_DOCX_MAINDOCUMENTPART

Alternative part will be related to main document part. So now we create new class ZCL_DOCX_MAINDOCUMENTPART as copy of standard one. And we change its method ADD_ALTERNATIVEFORMATPART in following way:

METHOD add_alternativeformatpart.
  CASE iv_content_type.
    WHEN cl_docx_alternativeformatpart=>co_content_type_text.
    WHEN cl_docx_alternativeformatpart=>co_content_type_rtf.
    WHEN cl_docx_alternativeformatpart=>co_content_type_html.
    WHEN cl_docx_alternativeformatpart=>co_content_type_word.
    WHEN cl_docx_alternativeformatpart=>co_content_type_wordt.
    WHEN OTHERS.
      RAISE EXCEPTION TYPE cx_openxml_not_allowed.
  ENDCASE.
  rr_part ?= package->delegate_add_1_to_n_part( ir_parturi = me->parturi
                                                iv_content_type = iv_content_type ).
ENDMETHOD.

Activate it. With this step we allowed adding alternative part with required content type. Otherwise we would get exception.

3. Class CL_DOCX_DOCUMENT

Create new class ZCL_DOCX_DOCUMENT as copy of standard class as final. In this class there is method LOAD_DOCUMENT which defines some kind of customiznig what is allowed in word document in SAP. It includes content types of different parts, relations between parts, classes to represents these parts and parts handling.

Add new attribute:

  • CO_RELATION_TYPE_AFCHUNK – http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk

For following methods change returning parameter:

GET_MAINDOCUMENTPART

CREATE_DOCUMENT, LOAD_DOCUMENT

Change method CUSTOMIZE_PACKAGE_TYPE at following places:

macro add_1_to_n_af_relation

    DEFINE add_1_to_n_af_relation.
      add_allowed_rel( iv_content_type_from = &1=>co_content_type
                       iv_content_type_to   = &2=>co_content_type_text
                       iv_relation_type     = &2=>co_relation_type ).
      add_allowed_rel( iv_content_type_from = &1=>co_content_type
                       iv_content_type_to   = &2=>co_content_type_rtf
                       iv_relation_type     = &2=>co_relation_type ).
      add_allowed_rel( iv_content_type_from = &1=>co_content_type
                       iv_content_type_to   = &2=>co_content_type_html
                       iv_relation_type     = &2=>co_relation_type ).
* Added part
      add_allowed_rel( iv_content_type_from = &1=>co_content_type
                       iv_content_type_to   = &2=>co_content_type_word
                       iv_relation_type     = &2=>co_relation_type ).
      add_allowed_rel( iv_content_type_from = &1=>co_content_type
                       iv_content_type_to   = &2=>co_content_type_wordt
                       iv_relation_type     = &2=>co_relation_type ).
    END-OF-DEFINITION.

add_partclass for CL_DOCX_DOCUMENT

*    add_partclass cl_docx_maindocumentpart. "comment out
    add_partclass zcl_docx_maindocumentpart. "added part
    add_partclass_m cl_docx_maindocumentpart macro.
    add_partclass_m cl_docx_maindocumentpart template.
    add_partclass_m cl_docx_maindocumentpart macrotemplate.

add_partclass_a for alterniative part

    add_partclass_a cl_docx_alternativeformatpart text.
    add_partclass_a cl_docx_alternativeformatpart rtf.
    add_partclass_a cl_docx_alternativeformatpart html.
* Added part
    add_partclass_a cl_docx_alternativeformatpart word.
    add_partclass_a cl_docx_alternativeformatpart wordt.

Actuvate it.

4. Class CL_OPENXML_PACKAGE

Create class ZCL_OPENXML_PACKAGE not as final which inherits from standard one. This class describes a package. Add following into attributes part:

  • PART_HANDLING_MAP_TABLE_EXT which is type
PRIVATE SECTION.

  DATA part_handling_map_table_ext TYPE HASHED TABLE OF ty_part_handling_map WITH UNIQUE KEY content_type class_name.

This table holds our custom part handling.

  • CO_CONTENT_TYPE_WORD – application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
  • CO_CLASS_WORD – CL_DOCX_ALTERNATIVEFORMATPART
  • CO_CONTENT_TYPE_WORDT – application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml

Now redefine methods:

ADD_PART_HANDLING

  METHOD add_part_handling.

    CALL METHOD super->add_part_handling
      EXPORTING
        iv_content_type  = iv_content_type
        iv_class_name    = iv_class_name
        iv_filepath      = iv_filepath
        iv_filename      = iv_filename
        iv_fileext       = iv_fileext
        iv_numbered_path = iv_numbered_path
        iv_numbered_file = iv_numbered_file
        iv_guid_name     = iv_guid_name
        iv_default_type  = iv_default_type.

    IF ( iv_content_type EQ me->co_content_type_word OR
         iv_content_type EQ me->co_content_type_wordt  ) AND
       iv_class_name EQ me->co_class_word.
      DATA: lph TYPE ty_part_handling_map.
      CLEAR lph.
      lph-content_type = me->normalize_content_type( iv_content_type ).
      lph-class_name = iv_class_name.
      lph-filepath = iv_filepath.
      lph-filename = iv_filename.
      lph-fileext = iv_fileext.
      lph-guid_name = iv_guid_name.
      lph-numbered_path = iv_numbered_path.
      lph-numbered_file = iv_numbered_file.
      lph-default_type = iv_default_type.
      INSERT lph INTO TABLE part_handling_map_table_ext.
    ENDIF.
  ENDMETHOD.

GET_PART_HANDLING

  METHOD get_part_handling.

    IF iv_relation_type EQ zcl_docx_document=>co_relation_type_afchunk AND
       ( iv_content_type EQ cl_docx_alternativeformatpart=>co_content_type_word OR
         iv_content_type EQ cl_docx_alternativeformatpart=>co_content_type_wordt ).
      READ TABLE part_handling_map_table_ext WITH TABLE KEY content_type = iv_content_type class_name = zcl_openxml_package=>co_class_word INTO rs_part_hndl.
    ELSE.
      CALL METHOD super->get_part_handling
        EXPORTING
          iv_content_type  = iv_content_type
          iv_relation_type = iv_relation_type
        RECEIVING
          rs_part_hndl     = rs_part_hndl.
    ENDIF.

  ENDMETHOD.

Activate class. As last step go to class ZCL_DOCX_DOCUMENT and change its superclass to ZCL_OPENXML_PACKAGE. When prompted keep new methods definition.

By this we have finished minimum necessary steps to be able to use altChunk in ABAP. Now get back to this blog for altChunk explanation and usage in test scenario.

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michael Bagi Pedersen
      Michael Bagi Pedersen

      Hi Pavol,

      Before i start coding in our installation, I would like to ask if this implementation still works?

      In the code is a reference to http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk, but if I write this in a browser, nothing comes up - is this link still active? - or does it matter at all?

      Kind regards,

      Michael

      Author's profile photo Pavol Olejar
      Pavol Olejar
      Blog Post Author

      Hi Michael,

      Yes, this works perfectly. Do not bother with not working links - these links are not representing actual web pages.

      Regards

      Pavol