[ABAP] Odczyt pliku z archiwum do stringa

Posted on February 17, 2012, under SAP.

Ostatnio rozwiązywałam problem odczytu zdjęcia pracownika zapisanego w kartotece pracowniczej. Takie zdjęcie przechowywane jest w postaci Archive Linku i o ile ściągniecie go na dysk nie stanowi problemu (jest kilka modułów funkcyjnych, które do tego służą) to odczytanie go w sposób zrozumiały dla edytora tekstu, jakim jest MS Word już nie jest takie proste. Do zapisu dowolnych plików do formatu .doc korzystamy z dedykowanej aplikacji opartej na zapisie żądanego dokumentu w języku HTML (który jest bardzo zrozumiały dla MS Word), zatem problem ograniczył się do ściągnięcia zdjęcia w formacie akceptowalnym dla tagu IMG – w postaci inline. Dzięki temu nie musimy zapisywać oddzielnie obrazków, linkować ich do pliku i martwić się, czy na pewno zawsze będą w lokalizacji, w której je zapisaliśmy. W zapisie obrazka inline, nasze zdjęcie jest zapisane w postaci ciągu znaków w treści dokumentu HTML.

Konkretniej – będziemy konwertować obrazki z postaci binarnej do stringa o podstawie 64bitowej. Taką konwersję dla dowolnego pliku można zrobić np. w takim edytorze. Po wczytaniu i przekonwertowaniu obrazka w takim edytorze otrzymamy ciąg znaków, który możemy wstawić w HTMLowy tag IMG:

<img src=”data:image/jpeg;base64,CIĄG_ZNAKÓW_OBRAZKA” height=”100″ width=”100″/>

Aby powyższy ciąg znaków otrzymać dla dokumentu zapisanego w archiwum wykorzystamy cztery moduły funkcyjne:

1. Pobieramy listę dokumentów przypisanych do pracownika – wykorzystujemy do tego funkcję ARCHIV_CONNECTINFO_GET_META. Ważne, żeby w parametrze object_id podać numer pracownika i na końcu gwiazdkę (*) np. ’10000021*’

  CALL FUNCTION 'ARCHIV_CONNECTINFO_GET_META'
    EXPORTING
      object_id    = lv_objid
      ar_object    = ''
      sap_object   = 'PREL'
    IMPORTING
      number       = lv_number_hits
    TABLES
      connect_info = lt_hit_table
    EXCEPTIONS
      OTHERS       = 1.

2. Tabela lt_hit_table zawiera wszystkie dokumenty przypisane do osoby. Nas interesują zdjęcia ( pole ar_object w tabeli = HRICOLFOTO). Szukamy wybranego wpisu (ja go zapisałam do ls_hit_table) i dla niego wywołujemy kolejną funkcję – ARCHIVEOBJECT_GET_TABLE, która pobiera plik binarnie do tabelki:

    doc_type = ls_hit_table-ar_object.
    CALL FUNCTION 'ARCHIVOBJECT_GET_TABLE'
    EXPORTING
      archiv_id                = ls_hit_table-archiv_id
      document_type            = doc_type
      archiv_doc_id            = ls_hit_table-arc_doc_id
    TABLES
      binarchivobject          = binary_tab
    EXCEPTIONS
      error_archiv             = 1
      error_communicationtable = 2
      error_kernel             = 3
      OTHERS                   = 4.

3. Obliczamy długość pliku (raczej mało elegancko):

  length = LINES( binary_tab ).
  length = length * 1024.

4. Wywołujemy funkcję SCMS_BINARY_TO_XSTRING, która stworzy nam jeden ciąg bajtów w postaci xtsringa z tabelki binarnej:

  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
    EXPORTING
      input_length = length
      first_line   = 0
      last_line    = 0
    IMPORTING
      buffer       = lv_pic_xstring
    TABLES
      binary_tab   = binary_tab
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.

5. Teraz wystarczy tylko zakodować wynik do postaci stringa o podstawie 64bitowej:

  CALL FUNCTION 'SSFC_BASE64_ENCODE'
    EXPORTING
      bindata                  = lv_pic_xstring
    IMPORTING
      b64data                  = lv_picture
    EXCEPTIONS
      ssf_krn_error            = 1
      ssf_krn_noop             = 2
      ssf_krn_nomemory         = 3
      ssf_krn_opinv            = 4
      ssf_krn_input_data_error = 5
      ssf_krn_invalid_par      = 6
      ssf_krn_invalid_parlen   = 7
      OTHERS                   = 8.

W zmiennej lv_picture mamy ciąg znaków, który możemy wkleić w tag img.