cancel
Showing results for 
Search instead for 
Did you mean: 

Error opening pdf in email

Former Member
0 Kudos

I am trying to email a smartform as pdf. But getting the error that File cannot be opened as it is damaged and cannot be repaired.

I am getting the otf data from Smartform FM. Then convert it to pdf. And then sending it through SO_NEW_DOCUMENT_ATT_SEND_API1. Attached is my code. I don't know what I am doing wrong. I first tried to send it directly through smartform email parameters. It didn't work. I also tried other functions for OTF to PDF conversions. But always getting the same error . I've also checked SCOT for SMTP node setup. The o/p format for smartforms is PDF.

Has anybody ever succeeded in getting the good pdf from smart form in the email ? Any idea what I am doing wrong ?

V_FORMNAME = 'ZSD_DAILY_SHEET_DB'.

call function 'SSF_FUNCTION_MODULE_NAME'
exporting
formname = v_formname
importing
fm_name = fm_name
exceptions
no_form = 1
no_function_module = 2
others = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

w_ctrlop-getotf = 'X'.
w_ctrlop-no_dialog = 'X'.
w_compop-tdnoprev = 'X'.

CALL FUNCTION fm_name
  EXPORTING
   CONTROL_PARAMETERS         = w_ctrlop
   OUTPUT_OPTIONS             = w_compop
   USER_SETTINGS              = 'X'
   VTITLE                     = SY-TITLE
   VDATE                      = P_DATE
   VDATE2                     = SY-DATUM
IMPORTING
   JOB_OUTPUT_INFO            = w_return
  TABLES
    I_DAILY                    = it_daily
    I_MONTHLY                  = it_monthly
    I_YEARLY                   = it_yearly
EXCEPTIONS
   FORMATTING_ERROR           = 1
   INTERNAL_ERROR             = 2
   SEND_ERROR                 = 3
   USER_CANCELED              = 4
   OTHERS                     = 5
          .
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

i_otf[] = w_return-otfdata[].

CALL FUNCTION 'CONVERT_OTF'
EXPORTING
format = 'PDF'
max_linewidth = 132
IMPORTING
bin_filesize = v_len_in
TABLES
otf = i_otf
lines = i_tline
EXCEPTIONS
err_max_linewidth = 1
err_format = 2
err_conv_not_possible = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

* Convert PDF from 132 to 255.
LOOP AT i_tline.
* Replacing space by ~
TRANSLATE i_tline USING ' ~'.
CONCATENATE w_buffer i_tline INTO w_buffer.
ENDLOOP.

* Replacing ~ by space
TRANSLATE w_buffer USING '~ '.
DO.
i_record = w_buffer.
* Appending 255 characters as a record
APPEND i_record.
SHIFT w_buffer LEFT BY 255 PLACES.
IF w_buffer IS INITIAL.
EXIT.
ENDIF.
ENDDO.

Refresh: i_reclist,
i_objtxt,
i_objbin,
i_objpack.
clear w_objhead.

* Object with PDF.
i_objbin[] = i_record[].
DESCRIBE TABLE i_objbin LINES v_lines_bin.
* Object with main text of the mail.
i_objtxt = 'Find attached the Daily Dashboard Sheet.'.
APPEND i_objtxt.
i_objtxt = 'Regards,'.
APPEND i_objtxt.
i_objtxt = 'Dummy.
APPEND i_objtxt.
DESCRIBE TABLE i_objtxt LINES v_lines_txt.

* Document information.
w_doc_chng-obj_name = 'Smartform'.
w_doc_chng-expiry_dat = sy-datum + 10.
w_doc_chng-obj_descr = 'Smart form output'.
w_doc_chng-sensitivty = 'F'. "Functional object
w_doc_chng-doc_size = v_lines_txt * 255.
* Pack to main body as RAW.
* Obj. to be transported not in binary form
CLEAR i_objpack-transf_bin.
* Start line of object header in transport packet

i_objpack-head_start = 1.
* Number of lines of an object header in object packet
i_objpack-head_num = 0.
* Start line of object contents in an object packet
i_objpack-body_start = 1.
* Number of lines of the object contents in an object packet
i_objpack-body_num = v_lines_txt.
* Code for document class
i_objpack-doc_type = 'RAW'.
APPEND i_objpack.

* Packing as PDF.
i_objpack-transf_bin = 'X'.
i_objpack-head_start = 1.
i_objpack-head_num = 0.
i_objpack-body_start = 1.
i_objpack-body_num = v_lines_bin.
i_objpack-doc_type = 'PDF'.
i_objpack-obj_name = 'Smartform'.
i_objpack-obj_descr = 'Dashboard Sheet'.
i_objpack-doc_size = v_lines_bin * 255.
APPEND i_objpack.
* Document information.
CLEAR i_reclist.

* e-mail receivers.
i_reclist-receiver = p_mail.
i_reclist-express = 'X'.
i_reclist-rec_type = 'U'. "Internet address
APPEND i_reclist.
* Sending mail.
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
EXPORTING
document_data = w_doc_chng
put_in_outbox = 'X'
TABLES
packing_list = i_objpack
object_header = w_objhead
contents_bin = i_objbin
contents_txt = i_objtxt
receivers = i_reclist
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

Edited by: Arbaab Rahim on Sep 15, 2008 2:41 PM

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

A PDF document includes parts that are binary and may include any character.

So when you translate space to '' and then back again in your conversion to 255 character long fields, it is possible you are converting back more than you originally set - in other words, you are replacing some '' characters in the PDF with spaces that should really be left as '~'. This will result in a corrupt PDF.

It is possible to convert the length to 255 without using this unreliable "trick" - the following code is one way to do this:


DATA:
          t_bin         LIKE  solisti1 OCCURS 0 WITH HEADER LINE,
          l_lines       TYPE i,
          l_len         TYPE i,
          l_text(1000)  TYPE c,
          l_text2(1000) TYPE c,
          l_doc_size(12) TYPE c.

* Create the PDF attachment (convert to 255 char fields)
  CLEAR l_text.
  LOOP AT t_pdf.
    IF sy-tabix = 1.
      l_text = t_pdf.
      l_len = 134.
      CONTINUE.
    ENDIF.
    l_text+l_len(134) = t_pdf.
    l_len = l_len + 134.
    IF l_len > 255.
      t_bin   = l_text+0(255).
      l_text  = l_text+255.
      l_len = l_len - 255.
      APPEND t_bin.
    ENDIF.
  ENDLOOP.
  IF l_len > 0.
    IF l_len > 255.
      t_bin   = l_text+0(255).
      l_text  = l_text+255.
      l_len = l_len - 255.
      APPEND t_bin.
    ENDIF.
    IF l_len > 0.
      t_bin = l_text.
      APPEND t_bin.
    ENDIF.
 ENDIF.

Note that this assumes 134 characters for the input - not 132 - this is what the function 'CONVERT_OTF_2_PDF' returns - the extra 2 characters are the format field in the internal table - the conversion treats the whole 134 as a single field. If the function you use is also doing this, it may also corrupt your PDF.

Also note that this method of conversion to match the email attachment format is only relevant when using functions like 'SO_NEW_DOCUMENT_ATT_SEND_API1' to send the email. If you are using the CL_BCS based email sending, then you need a routine that casts the T_PDF data into the right data format - there is a SAP function module that does this.

Andrew

Former Member
0 Kudos

Thanks Andrew for your response.

I took your suggestion and used CL_BCS class to send the document. But it is sending a blank pdf to the email address. Only the form template is displayed without any data. Can you pleae tell me what I am doing wrong ?

This is what I did.

1. Convert_OTF

2.SCMS_XSTRING_TO_BINARY

Then did the following using methods.

send_request = cl_bcs=>create_persistent( ).

document = cl_document_bcs=>create_document( i_type = 'PDF'

i_hex = v_pdf_content

i_length = v_pdf_size

i_subject = 'Test Message' ).

send_request->set_document( document ).

recipient = cl_cam_address_bcs=>create_internet_address(

i_address_string = p_mail ).

send_request->add_recipient( i_recipient = recipient ).

sent_to_all = send_request->send( i_with_error_screen = 'X' ).

COMMIT WORK.

Former Member
0 Kudos

The code I used with BCS added the PDF as an attachment rather than as the main document.


DATA:    ZATT_BIN_TYPE  TYPE  SOODK-OBJTP,
             ZATT_BIN             TYPE  SOLIX_TAB. 
             ZATT_BIN_DESC  TYPE  SOOD-OBJDES.

      call method cl_document_bcs=>create_document
        exporting
          i_type    = ztype
          i_subject = l_desc
          i_text    = ztext
        receiving
          result    = l_doc.

        call method l_doc->add_attachment
          exporting
            i_attachment_type    = zatt_bin_type     "PDF
            i_attachment_subject = zatt_bin_desc   "Filename.pdf
            i_att_content_hex    = zatt_bin.

      call method l_obj->set_document
        exporting
          i_document = l_doc.

Before adding the attachment, the following code was used to convert it to the format of zatt_bin table:


  TYPES pdf_raw             TYPE x LENGTH 268.
  FIELD-SYMBOLS <pdf_bin>   TYPE pdf_raw.
  DATA: pdf_lines           TYPE TABLE OF tline,
        BEGIN OF content_in,
           line             TYPE tline,
           dummy            TYPE tline,
        END OF content_in,
        content_out         TYPE solix,
        line_width_src      TYPE i,
        pos_out             TYPE i,
        pos_in              TYPE i,
        len_out             TYPE i.

* convert the sapscript(OTF) into PDF data
  CALL FUNCTION 'CONVERT_OTF_2_PDF'
* EXPORTING
*   USE_OTF_MC_CMD               = 'X'
*   ARCHIVE_INDEX                =
   IMPORTING
     bin_filesize                 = w_size
    TABLES
      otf                          = t_otf_data
      doctab_archive               = w_doctab_archive
      lines                        = pdf_lines
   EXCEPTIONS
     err_conv_not_possible        = 1
     err_otf_mc_noendmarker       = 2
     OTHERS                       = 3.


* Following conversion code copied from FM SX_OBJECT_CONVERT_OTF_PDF
* Cast to binary type and adjust table line length
  DESCRIBE FIELD content_in-line LENGTH line_width_src IN BYTE MODE.
  REFRESH zatt_bin.
  CLEAR content_out.
  pos_out = 0.
  LOOP AT pdf_lines INTO content_in-line.
    ASSIGN content_in TO <pdf_bin> CASTING.
    MOVE <pdf_bin> TO content_out-line+pos_out.
    ADD line_width_src TO pos_out.
    WHILE pos_out >= 255.
      APPEND content_out TO zatt_bin.
      CLEAR content_out.
      SUBTRACT 255 FROM pos_out.
      IF pos_out > 0.
        pos_in = line_width_src - pos_out.
        MOVE <pdf_bin>+pos_in TO content_out-line.
      ENDIF.
    ENDWHILE.
  ENDLOOP.
  IF pos_out > 0.
    APPEND content_out TO zatt_bin.
  ENDIF.

Note that above has been copied from a couple of different places, and I may have missed some data declarations etc. Should give an idea of what I have used though. Hope it helps.

Andrew

Former Member
0 Kudos

Rahim,

in the FM, SO_NEW_DOCUMENT_ATT_SEND_API1 give COMMIT_WORK = 'X'.

The following code works for me. Try this.


*"--------------------------------------------------------------------*
*                      START-OF-SELECTION EVENT                       *
*"--------------------------------------------------------------------*
START-OF-SELECTION.

*" Read the HFA records into internal table............................
  SELECT *
    FROM zhfa
    INTO TABLE t_zhfa
   WHERE zz_vin6 IN s_vin6.
  IF sy-subrc NE 0.
    MESSAGE text-002 TYPE 'W'.

  ENDIF.                               " IF SY-SUBRC NE 0

  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname                 = 'YH1145_HFA1'
*   VARIANT                  = ' '
*   DIRECT_CALL              = ' '
   IMPORTING
     fm_name                  = w_name
   EXCEPTIONS
     no_form                  = 1
     no_function_module       = 2.


    w_control-getotf = 'X'.
    w_control-no_dialog = 'X'.
    w_output-tdnoprev = 'X'.
    LOOP AT t_zhfa INTO fs_zhfa.
      CALL FUNCTION '/1BCDWB/SF00000457'
        EXPORTING
*   ARCHIVE_INDEX              = ARCHIVE_INDEX
*   ARCHIVE_INDEX_TAB          = ARCHIVE_INDEX_TAB
*   ARCHIVE_PARAMETERS         = ARCHIVE_PARAMETERS
         control_parameters         = w_control
*   MAIL_APPL_OBJ              = MAIL_APPL_OBJ
*   MAIL_RECIPIENT             = MAIL_RECIPIENT
*   MAIL_SENDER                = MAIL_SENDER
         output_options             = w_output
         user_settings              = 'X'
          fs_zhfa                    = fs_zhfa
       IMPORTING
*   DOCUMENT_OUTPUT_INFO       = DOCUMENT_OUTPUT_INFO
         job_output_info            = w_return
*   JOB_OUTPUT_OPTIONS         = JOB_OUTPUT_OPTIONS
       EXCEPTIONS
         formatting_error           = 1
         internal_error             = 2
         send_error                 = 3
         user_canceled              = 4.

*" w_return-otfdata holds the smartform OTF data.................
    append lines of w_return-otfdata to t_otf.
    ENDLOOP.

*" t_otf is the OTF data.........................................
*" t_line is the PDF data.......................................
    CALL FUNCTION 'CONVERT_OTF'
     EXPORTING
       format                      = 'PDF'
       max_linewidth               = 132
*   ARCHIVE_INDEX               = ' '
*   COPYNUMBER                  = 0
*   ASCII_BIDI_VIS2LOG          = ' '
*   PDF_DELETE_OTFTAB           = ' '
     IMPORTING
       bin_filesize                = w_filesize
*   BIN_FILE                    = BIN_FILE
      TABLES
        otf                         = t_otf
        lines                       = t_line
     EXCEPTIONS
       err_max_linewidth           = 1
       err_format                  = 2
       err_conv_not_possible       = 3
       err_bad_otf                 = 4.

    LOOP AT t_line.
      CONCATENATE w_string t_line INTO w_string.
    ENDLOOP.
*" convert the 132 line character to 255 character ..................
    DO.
      t_attach = w_string.
      APPEND t_attach.
      SHIFT w_string LEFT BY 255 PLACES.
      IF w_string IS INITIAL.
        EXIT.
      ENDIF.
    ENDDO.

    t_objbin[] = t_attach[].
*" body of the mail..................................................
    CLEAR t_message. REFRESH t_message.
    t_message = 'This is a mail from SAP ECC6'.
    APPEND t_message.
    t_message = 'Thanks and Regards'.
    APPEND t_message.
    t_message = 'Indu'.
    APPEND t_message.
    DESCRIBE TABLE t_message LINES w_msg.

*"
    w_docdata-obj_name = 'SAPRPT'.
    w_docdata-expiry_dat = sy-datum + 10.
    w_docdata-obj_descr = 'Smartform mail from Indu'.
    w_docdata-sensitivty = 'F'.
    w_docdata-doc_size = w_msg * 255.
    w_docdata-obj_langu = sy-langu .

*" type of the mail send: packing_list.........................
    CLEAR t_packing_list. REFRESH t_packing_list.
    t_packing_list-transf_bin = space.
    t_packing_list-head_start = 1.
    t_packing_list-head_num = 0.
    t_packing_list-body_start = 1.
    t_packing_list-body_num = w_msg.
    t_packing_list-doc_type = 'RAW'.
    APPEND t_packing_list.

    t_packing_list-transf_bin = 'X'.
    DESCRIBE TABLE t_objbin LINES w_objbin.
*" doc_size = (lines in pdf table) * 255......................
    t_packing_list-doc_size = w_objbin * 255.
    t_packing_list-body_num = w_objbin.
    t_packing_list-doc_type = 'PDF'.
    t_packing_list-obj_name = 'smart'.
    t_packing_list-obj_descr = 'test'.
    APPEND t_packing_list.

    CLEAR t_receivers.
    t_receivers-receiver = '<email id>'.
    t_receivers-rec_type = 'U'.
    APPEND t_receivers.


    CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
      EXPORTING
        document_data                    = w_docdata
       put_in_outbox                    = 'X'
       sender_address                   = sender
*   SENDER_ADDRESS_TYPE              = 'B'
       commit_work                      = 'X'
* IMPORTING
*   SENT_TO_ALL                      = SENT_TO_ALL
*   NEW_OBJECT_ID                    = NEW_OBJECT_ID
*   SENDER_ID                        = SENDER_ID
      TABLES
        packing_list                     = t_packing_list
*   OBJECT_HEADER                    = OBJECT_HEADER
       contents_bin                     = t_objbin
       contents_txt                     = t_message
*   CONTENTS_HEX                     = CONTENTS_HEX
*   OBJECT_PARA                      = OBJECT_PARA
*   OBJECT_PARB                      = OBJECT_PARB
        receivers                        = t_receivers
     EXCEPTIONS
       too_many_receivers               = 1
       document_not_sent                = 2
       document_type_not_exist          = 3
       operation_no_authorization       = 4
       parameter_error                  = 5
       x_error                          = 6
       enqueue_error                    = 7.
    IF sy-subrc NE 0.
      WRITE:/ 'Error When Sending the File', sy-subrc.
    ELSE.
      WRITE:/ 'Mail sent'.
    ENDIF.
    SUBMIT rsconn01 USING SELECTION-SET 'INT' AND RETURN.
    CALL FUNCTION 'SO_DEQUEUE_UPDATE_LOCKS'.
  ELSEIF p_fax EQ 'X'.