Zum Inhalt springen

PDF anzeigen in Fiori Elements List Report mit OData v2 und einer Custom Action

Immer wieder ist es gefordert in klassischen Fiori List Reports Dokumente (oft PDFs) anzuzeigen. Über OData v4 ist dies auch nicht wirklich schwer umzusetzen, da es die Möglichkeit gibt Felder über Edm.Stream zu deklarieren. Über den Stream Support zeigt Fiori Elements die Dateien dann entweder als Link oder Vorschau an. Ist man aber noch auf einem 7.40 Release unterwegs bzw. hat man da schon mit anderen Herausforderungen zu kämpfen.

  1. OData-Service selbst implementieren (natürlich v2)
  2. Fiori-Elements Custom Action implementieren um den PDF-Absprung zu ermöglichen

OData-Service implementieren

Klassisch über SEGW in meinem Fall eine eigene Entität z.B. Document mit den entsprechenden Schlüsselfeldern die für die Anzeige des Dokuments wichtig sind. Zudem ein Feld ContentType, welches den Typ der Datei definiert.

Der Content Typ wird dann über eine Redefinition der Methode define in der mpc_ext-Implementierung als solcher definiert.

super->define( ).

DATA(lo_entity_type) = model->get_entity_type( iv_entity_name = 'Document' ) ).
IF lo_entity_type IS BOUND.
      DATA(lo_property) = lo_entity_type->get_property( iv_property_name = 'ContentType' ).
      lo_property->set_as_content_type( ).
ENDIF.

Um sich den Inhalt des angeforderten PDFs zu holen muss in der dpc_ext-Implementierung die Methode get_stream des Interfaces /iwbep/if_mgw_appl_srv_runtime redefiniert werden. Dort wird dann die Logik des PDF-Inhaltes ermittelt und als xString zurückgegeben. Geht natürlich auch für andere MIME-Typen. Wichtig am Ende ist der Header-Hinweis content-disposition mit dem Wert inline, damit das PDF embedded angezeigt werden kann und nicht heruntergeladen wird.

DATA ls_stream TYPE ty_s_media_resource.
DATA lv_pdf_content TYPE xstring.

"Logik zur Ermittlung PDF-Inhalt

ls_stream-value = lv_pdf_content.
ls_stream-mime_type = 'application/pdf'.
copy_data_to_ref( EXPORTING is_data = ls_stream
                            CHANGING  cr_data = er_stream ).


set_header( is_header = VALUE #( name = 'Content-Disposition' value = 'inline; filename=' && |Test.pdf| ) ).

Fiori-Elements Custom Action implementieren

Geht einfach über VSCode und das Guided Development.

Der Guide ist auch relativ einfach im Endeffekt wird die Seite (List Report oder Object Page) ausgewählt, Text und Position des Buttons festgelegt und der Name für die zu rufenden Funktion in der Controller Extension definiert.

Am Ende des Ganzen hat man seine eigene Custom Action zur Ausprogrammierung zur Verfügung (ListReportExt.controller.js).

Darin kann man jetzt den PDF-Aufruf über das PDF Viewer-Control implementieren.

customDocument: function(oEvent) {

var item = oEvent.getSource().getParent().getParent().getSelectedItem();
var path = item.getBindingContext().getPath();
var model = oEvent.getSource().getParent().getParent().getModel();
var obj = model.getProperty(path);
var keyfield1 = obj.Keyfield1; //Selektiertes Schlüsselfeld 
var keyfield2 = obj.Keyfield2; //Selektiertes Schlüsselfeld 
            
var oPdfViewer = new PDFViewer();
this.getView().addDependent(oPdfViewer);
var sServiceURL = this.getView().getModel().sServiceUrl;
var sSource = sServiceURL + "/documentSet(Keyfield1='"+ keyfield1 +"',Begda='"+ keyfield2 +"')/$value";
oPdfViewer.setSource(sSource);
oPdfViewer.setTitle( "PDF");
oPdfViewer.open();

}

Ergebnis beim Klick auf PDF anzeigen. Es öffnet sich ein Beispiel-PDF:

In meiner Anforderung war noch ein vorgeschaltetes Popup notwendig, welches es ermöglichen sollte einen Zeitraum auszuwählen bevor das PDF angezeigt wurde. Dafür musste noch ein eigenes Dialog-Fragment erstellt werden. Bei Interesse kann dieses Beispiel noch in einem weiteren Beitrag vorgestellt werden basierend auf diesem Beitrag.

Facebooktwitterpinterestlinkedinmail
Published inFiori ElementsoDataSAP EntwicklungSAP UI

Sei der Erste der einen Kommentar abgibt

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert