cancel
Showing results for 
Search instead for 
Did you mean: 

Extract data from PDF to SAP

0 Kudos

Hi all,

I have created an Offline form in sfp Transaction and emailed successfully .

And now that Receiver has sent me the form with the filled pdf form to my outlook id ( bcas my mail id is being configured in SMTP) .

Now I want to Update a table with that filled values in the received pdf..

1) What r all the steps should i follow now?

2) What for guided procedures or workflow?

3) Do i have the option to receive the mail to my Business workplace inbox instead my personal mail id?

i went thru all the related threads in this topic. But could not get the Idea..

If someone knows please suggest me ..

Thank you.

Rgrds.

Edited by: Deepa K on Feb 25, 2008 1:30 PM

View Entire Topic
Former Member
0 Kudos

Hi Deepa,

I got the same requirement from my customer and i do it .

The solution below works in ABAP Stack of an ECC5 .

First The smtp server of the ABAP Stack has been configure to receive mail.

Then i develop an ABAP Object to process the inbound mail ( this object is based on standard interface IF_INBOUND_EXIT_BCS ) .

You can found sample code of processing inbound mail in SDN .

In this abap object i retrieve the PDF file in attachment and process it ( extract data and update database ) . To extract data and process it i use IXML SAP object

If you need code do not hesitate i can give you .

Hope this help you .

Regards.

0 Kudos

hi,

Thanks for ur reply

can i have the code to get more idea....

Rgrds.

Edited by: Deepa K on Mar 31, 2008 1:44 PM

Former Member
0 Kudos

Hi Deepa,

Do you sample code to do it ?

0 Kudos

yes.. can i have the sample code..

Regards.

Former Member
0 Kudos

Hi,

When you create an abap object based on standard interface IF_INBOUND_EXIT_BCS you will got 2 method .

First here is the attributes i define in my object , all are Private instance attributes.

XML_DOCUMENT type ref to IF_IXML_DOCUMENT.

CONVERTER type ref to CL_ABAP_CONV_IN_CE,

ATTACHEMENT_ATTRIBUTES type BCSS_DBPA,

ATTACHEMENT_FILE type BCSS_DBPC ,

BINARY_FILE Type XSTRING,

FORMXML Type STRING,

PDF_FORM_DATA Type XSTRING ,

XML_NODE Type Ref To IF_IXML_NODE,

XML_NODE_VALUE Type STRING.

Set this code in method CREATE_INSTANCE


* Check if the singleton instance has already
* been created.
IF instance is INITIAL.
  CREATE OBJECT instance.
ENDIF.

* Return the iTE nstance.
ro_ref = instance.

The other method is where the mail will be process

here is a sample code for method PROCESS_INBOUND


* Data definition :

  DATA : pdf_line    TYPE solix  .

  DATA : nb_att(10) TYPE n.

  DATA w_part TYPE int4 .

  FIELD-SYMBOLS : <pdf_line> TYPE solix.

** Set return code so no other Inbound Exit will be done.
  e_retcode = if_inbound_exit_bcs=>gc_terminate.
  TRY .

* Get the email document that was sent.
      mail = io_sreq->get_document( ).

* Get number of attachement in the mail 
* If number is lower than 2 that means no attachement to the mail
      nb_att = mail->get_body_part_count( ) - 1.

      CHECK nb_att GT 0.

      CLEAR w_part.

* Process each document
      DO nb_att TIMES.
        w_part  = sy-index + 1 .
        CLEAR xml_document .
* Get attachement attributes
        attachement_attributes =
           mail->get_body_part_attributes( im_part = w_part ).

        IF attachement_attributes-doc_type IS INITIAL.
          DATA w_pos TYPE i .
          FIND '.' IN attachement_attributes-filename
            IN CHARACTER MODE MATCH OFFSET w_pos.
          ADD 1 TO w_pos.
          attachement_attributes-doc_type =
             attachement_attributes-filename+w_pos.
        ENDIF.

* Get the attachement
        attachement_file = mail->get_body_part_content( w_part ).

* If attachement is not a binary one ,
* transform it to binary.
        IF attachement_attributes-binary IS INITIAL.
          CALL FUNCTION 'SO_SOLITAB_TO_SOLIXTAB'
            EXPORTING
              ip_solitab  = attachement_file-cont_text
            IMPORTING
              ep_solixtab = attachement_file-cont_hex.
        ENDIF.

* Convert the attachement file into an xstring.

        CLEAR binary_file.
        LOOP AT attachement_file-cont_hex ASSIGNING <pdf_line>.
          CONCATENATE binary_file <pdf_line>-line
             INTO binary_file IN BYTE MODE.
        ENDLOOP.

        TRANSLATE attachement_attributes-doc_type TO UPPER CASE.

* Process the file depending on file extension 
* Only XML and PDF file is allow

        CASE attachement_attributes-doc_type  .
          WHEN 'PDF'.
* Process an interactive form
            me->process_pdf_file( ).
          WHEN 'XML'.
* Process XML data
            me->process_xml_file( input_xstring = binary_file ).
          WHEN OTHERS.
* Nothing to do , process next attachement
        ENDCASE.
    CATCH zcx_pucl003 .
  ENDTRY.

As you can see i add several specific method to my object in order to make the code more clear.

Here is the code for all the specifics methods

PROCESS_PDF_FILE


  TRY.
* Extract the Data of the PDF as a XSTRING stream
      me->process_form( pdf = binary_file ).

      me->process_xml_file( input_xstring = pdf_form_data ).

    CATCH zcx_pucl003 INTO v_exception.
      RAISE EXCEPTION v_exception.
  ENDTRY.

PROCESS_FORM with inbound parameter PDF type XSTRING


  DATA :
     l_fp          TYPE REF TO if_fp ,
     l_pdfobj      TYPE REF TO if_fp_pdf_object .
TRY.

* Get a reference to the form processing class.

      l_fp = cl_fp=>get_reference( ).

* Get a reference to the PDF Object class.

      l_pdfobj = l_fp->create_pdf_object( ).

* Set the pdf in the PDF Object.

      l_pdfobj->set_document( pdfdata = pdf ).

* Set the PDF Object to extract data the Form data.

      l_pdfobj->set_extractdata( ).

* Execute call to ADS
      l_pdfobj->execute( ).

* Get the PDF Form data.
      l_pdfobj->get_data( IMPORTING formdata = pdf_form_data ).

    CATCH cx_fp_runtime_internal
          cx_fp_runtime_system
          cx_fp_runtime_usage.
  ENDTRY.

PROCESS_XML_FILE with inbound parameter INPUT_XSTRING type XSTRING.


  TRY.
      me->create_xml_document( input_xstring = input_xstring ).

      me->process_xml( ).

    CATCH ZCX_PUCL003 INTO v_exception.
      RAISE EXCEPTION v_exception.

  ENDTRY.

CREATE_XML_DOCUMENT with inbound parameter INPUT_XSTRING type XSTRING.


  DATA :
     l_ixml        TYPE REF TO if_ixml,
     streamfactory TYPE REF TO if_ixml_stream_factory ,
     istream       TYPE REF TO if_ixml_istream,
     parser        TYPE REF TO if_ixml_parser.

  DATA: parseerror TYPE REF TO if_ixml_parse_error,
        str        TYPE string,
        i          TYPE i,
        count      TYPE i,
        index      TYPE i.

DATA :

* Convert the xstring form data to string so it can be
* processed using the iXML classes.

  TRY.

      converter = cl_abap_conv_in_ce=>create( input = input_xstring ).

      converter->read( IMPORTING data = formxml ).

* Get a reference to iXML object.
      l_ixml = cl_ixml=>create( ).

* Get iStream object from StreamFactory

      streamfactory = l_ixml->create_stream_factory( ).

      istream = streamfactory->create_istream_string( formxml ).

* Create an XML Document class that will be used to process the XML
      xml_document = l_ixml->create_document( ).

* Create the Parser class
      parser = l_ixml->create_parser( stream_factory = streamfactory
                                      istream        = istream
                                      document       = xml_document ).
* Parse the XML
      parser->parse( ).

      IF sy-subrc NE 0
        AND parser->num_errors( ) NE 0.

        count = parser->num_errors( ).
        index = 0.
        WHILE index < count.
          parseerror = parser->get_error( index = index ).
          str = parseerror->get_reason( ).
          index = index + 1.
        ENDWHILE.
        EXIT.
      ENDIF.


    CATCH cx_parameter_invalid_range
          cx_sy_codepage_converter_init
          cx_sy_conversion_codepage
          cx_parameter_invalid_type.
  ENDTRY.

Method PROCESS_XML


  DATA v_formname TYPE fpname.

* For each node of the XML file you want to retrieve the value 
* Then use the specific method PROCESS_NODE .

* Find Node where System Id is store
  CLEAR : xml_node ,
          xml_node_value.

  TRY.
      me->process_node( node_name     = 'SYSID' ).
      CHECK NOT xml_node_value IS INITIAL.

      CASE xml_node_value.
        WHEN sy-sysid.
* Search for Form name.
          me->process_node( node_name = 'FORM_NAME').
          CHECK NOT xml_node_value IS INITIAL.
          v_formname = xml_node_value.
          ...
          ...
        WHEN OTHERS.
      ENDCASE.
      CATCH cx_root.
  ENDTRY.

Method PROCESS_NODE with inbound parameter NODE_NAME type STRING


  CLEAR : xml_node , xml_node_value .

  xml_node = xml_document->find_from_name( name = node_name ).

  IF xml_node IS INITIAL.
* Missing one node in the form, nothing will be done
      RAISE EXCEPTION TYPE ....
  ELSE.
    xml_node_value = xml_node->get_value( ).
  ENDIF.

Hope this help you .

Best regards

Bertrand

Former Member
0 Kudos

Hello Bertrand,

First of all i would like to thank you for the information. It was very helpful for me while writing code for extracting data from PDF. The only question i have and need your help is regarding node name.

In method process_node it's mentioned to pass node_name = 'SYSID' but it didn't return anything to me. What should be the value for SYSID and FORM_NAME? I tried passing value as 'DEV' and 'ZVENDOR_OFFLINE' but it didn't worked. Please help and reply ASAP !!!.

Thanks in Advance.

Regards,

Nilesh.

Former Member
0 Kudos

Hi Nilesh

Node name in the code is a sample name corresponding to a field i got in my form .

In my form i add 2 field with the corresponding value of SAP SysID and Formname because first i got several forms and i made the code for all of them

The node with SAP SysId value allow me to check if the form has been generated by the current system in order to prevent error with testing environment.

So you should replace it with your own field name you want to retrieve .

Hope this help you .

Former Member
0 Kudos

Hi Bertrand,

Many thanks for your inputs. It helped me in extracting data from PDF.

Regards,

Nilesh