1. *& Copia pirata de Report RSPO_TEST_MERGE_PDF_FILES
  2.  
  3. report z_xx_prg_merge_pdf_files.
  4.  
  5. types: begin of t_fileinfo,
  6.          filename type string,
  7.          data     type xstring,
  8.          len      type i,
  9.        end of t_fileinfo.
  10.  
  11. types: begin of t_displayoption,
  12.          page_mode    type i,
  13.          page_layout  type i,
  14.          hide_toolbar type i,
  15.          hide_menubar type i,
  16.        end of t_displayoption.
  17.  
  18. types t_fileinfotab type standard table of t_fileinfo with key filename.
  19.  
  20. data: pdf_merger type ref to cl_rspo_pdf_merge.
  21. data: ex        type ref to cx_rspo_pdf_merge, lv_ex_txt type string.
  22.  
  23. data: gt_pdffiles type t_fileinfotab.
  24. data: gt_display type t_displayoption.
  25.  
  26. data: merged_document type xstring.
  27. data: rc    type i value 0, lnum type i value 0, p_sel type i value 1.
  28. data: docindex type i value 0, errordoc type xstring.
  29.  
  30. data: text1 type string, error_text type string.
  31. data: answer type c value '1'.
  32.  
  33. selection-screen begin of block b01 WITH FRAME.
  34.   PARAMETERS: p_dir type text255 OBLIGATORY DEFAULT '/SAPINTERFACES/NASA/Enviados',
  35.               p_mask type text50 OBLIGATORY default '1EG*.*'.
  36.  
  37. SELECTION-SCREEN end of block b01.
  38.  
  39. selection-screen begin of block opts with frame title title4.
  40.  
  41. parameters: dir  radiobutton group sele default 'X',
  42.             file radiobutton group sele.
  43.  
  44. selection-screen skip.
  45.  
  46. selection-screen end of block opts.
  47.  
  48. selection-screen begin of block params with frame title title1.
  49.  
  50. selection-screen begin of block pagemode with frame title title2.
  51.  
  52. parameters: none    radiobutton group pmod default 'X',
  53.             outline radiobutton group pmod,
  54.             thumbs  radiobutton group pmod,
  55.             fullscr radiobutton group pmod,
  56.             oc      radiobutton group pmod,
  57.             attachm radiobutton group pmod.
  58. selection-screen skip.
  59.  
  60. selection-screen end of block pagemode.
  61.  
  62. selection-screen begin of block layout with frame title title3.
  63.  
  64. parameters: single radiobutton group plyt default 'X',
  65.             column radiobutton group plyt,
  66.             tcoll  radiobutton group plyt,
  67.             tcolr  radiobutton group plyt,
  68.             tpagl  radiobutton group plyt,
  69.             tpagr  radiobutton group plyt.
  70. selection-screen skip.
  71.  
  72. selection-screen end of block layout.
  73.  
  74. parameters: p_hd_tb as checkbox default ' ',
  75.             p_hd_mb as checkbox default ' ',
  76.             p_hd_pc as checkbox default 'X'.
  77. selection-screen skip.
  78.  
  79. selection-screen end of block params.
  80.  
  81. at SELECTION-SCREEN OUTPUT.
  82.  
  83.     loop at SCREEN.
  84.         check screen-name np '*P_DIR*' and
  85.               screen-name np '*P_MASK*'.
  86.         screen-input = 0.
  87.         screen-invisible = 1.
  88.         modify screen.
  89.  
  90.     endloop.
  91.  
  92. initialization.
  93.   title1 = 'Acrobat Reader display options for merged PDF'(001). "#EC TEXT_DIFF
  94.   title2 = 'Page Mode'(002).                             "#EC TEXT_DIFF
  95.   title3 = 'Page Layout'(003).                           "#EC TEXT_DIFF
  96.   title4 = 'Select option of PDF files'(005).            "#EC TEXT_DIFF
  97.  
  98. end-of-selection.
  99.  
  100.   text1 = 'Select input directory'(004).                 "#EC TEXT_DIFF
  101.  
  102. * Exception should be catched. Kernel must support PDF merge.
  103.   try.
  104.       create object pdf_merger.
  105.     catch cx_rspo_pdf_merge into ex.
  106.       lv_ex_txt = ex->get_text( ).
  107.       write: / lv_ex_txt color col_negative.
  108.       rc = 1.
  109.       return.
  110.  
  111.   endtry.
  112.  
  113. * Get selection option for PDF files
  114.   if dir = 'X'.
  115.     p_sel = 1.
  116.   endif.
  117.  
  118.   if file = 'X'.
  119.     p_sel = 0.
  120.   endif.
  121.  
  122.   perform get_pdffiles using p_sel changing gt_pdffiles lnum.
  123.  
  124.   if lnum = 0.
  125.     write: / 'No files specified, leaving program.'(006) color col_total.
  126.     exit.
  127.   endif.
  128.  
  129.   describe table gt_pdffiles lines sy-tabix.
  130.   write: / 'Number of PDF Files:'(007), sy-tabix color col_total.
  131.  
  132. * Get display options of merged PDF: page mode
  133.   if none = 'X'.
  134.     gt_display-page_mode = 0.
  135.   endif.
  136.   if outline = 'X'.
  137.     gt_display-page_mode = 1.
  138.   endif.
  139.   if thumbs = 'X'.
  140.     gt_display-page_mode = 2.
  141.   endif.
  142.   if fullscr = 'X'.
  143.     gt_display-page_mode = 3.
  144.   endif.
  145.   if oc = 'X'.
  146.     gt_display-page_mode = 4.
  147.   endif.
  148.   if tpagl = 'X'.
  149.     gt_display-page_mode = 5.
  150.   endif.
  151.   if attachm = 'X'.
  152.     gt_display-page_mode = 5.
  153.   endif.
  154.  
  155. * Get display options of merged PDF: page layout
  156.   if single = 'X'.
  157.     gt_display-page_layout = 0.
  158.   endif.
  159.   if column = 'X'.
  160.     gt_display-page_layout = 1.
  161.   endif.
  162.   if tcoll = 'X'.
  163.     gt_display-page_layout = 2.
  164.   endif.
  165.   if tcolr = 'X'.
  166.     gt_display-page_layout = 3.
  167.   endif.
  168.   if tpagl = 'X'.
  169.     gt_display-page_layout = 4.
  170.   endif.
  171.   if tpagr = 'X'.
  172.     gt_display-page_layout = 5.
  173.   endif.
  174.  
  175. * Get display options of merged PDF: hide toolbar
  176.   if p_hd_tb = 'X'.
  177.     gt_display-hide_toolbar = 1.
  178.   else.
  179.     gt_display-hide_toolbar = 0.
  180.   endif.
  181.  
  182. * Get display options of merged PDF: hide menubar
  183.   if p_hd_mb = 'X'.
  184.     gt_display-hide_menubar = 1.
  185.   else.
  186.     gt_display-hide_menubar = 0.
  187.   endif.
  188.  
  189. * Return code should be checked: Only 0 means success
  190.   perform merge_pdfs using gt_pdffiles gt_display changing pdf_merger merged_document error_text docindex errordoc rc.
  191.   if rc = 0.
  192.     perform put_merged_file using merged_document.
  193.   else.
  194.     write: / 'Error: merge_pdfs returns '(008), rc, ' : ', error_text color col_negative.
  195.     write: / 'Failed document index '(009), docindex.
  196.  
  197. * Download failing document to check
  198.     call function 'POPUP_TO_CONFIRM'
  199.       exporting
  200.         titlebar              = 'Ungültige PDF-Datei'(010)
  201.         text_question         = 'Soll die PDF-Datei, die den Fehler verursacht, gespeichert werden?'(011)
  202.         text_button_1         = 'Ja'(014)
  203.         text_button_2         = 'Nein'(015)
  204.         default_button        = '1'
  205.         display_cancel_button = ' '
  206.       importing
  207.         answer                = answer
  208.       exceptions
  209.         others                = 0.
  210.  
  211.     if answer = '1'.
  212.       perform put_failed_file using errordoc.
  213.     endif.
  214.   endif.
  215.  
  216.  
  217. form put_merged_file using merged_document type xstring.
  218.  
  219.   data: bin_tab type standard table of tabl1024.
  220.   data: lo_gui type ref to cl_gui_frontend_services.
  221.   data: path     type string, fullpath type string.
  222.   data: length type i.
  223.   data: filter type string, uact type i, name type string.
  224.  
  225.   create object lo_gui.
  226.  
  227.   call function 'SCMS_XSTRING_TO_BINARY'
  228.     exporting
  229.       buffer        = merged_document
  230.     importing
  231.       output_length = length
  232.     tables
  233.       binary_tab    = bin_tab.
  234.  
  235.   call method lo_gui->file_save_dialog
  236.     exporting
  237.       default_extension = 'pdf'
  238.       default_file_name = 'merged.pdf'
  239.       file_filter       = filter
  240.     changing
  241.       filename          = name
  242.       path              = path
  243.       fullpath          = fullpath
  244.       user_action       = uact.
  245.   if uact = lo_gui->action_cancel.
  246.     exit.
  247.   endif.
  248.  
  249.   lo_gui->gui_download( exporting
  250.                           filename = fullpath
  251.                           filetype = 'BIN'
  252.                           bin_filesize = length
  253.                         changing
  254.                           data_tab = bin_tab ).
  255.  
  256. endform.
  257.  
  258. form put_failed_file using document type xstring.
  259.  
  260.   data: bin_tab type standard table of tabl1024.
  261.   data: lo_gui type ref to cl_gui_frontend_services.
  262.   data: path     type string, fullpath type string.
  263.   data: length type i.
  264.   data: filter type string, uact type i, name type string.
  265.  
  266.   create object lo_gui.
  267.  
  268.   call function 'SCMS_XSTRING_TO_BINARY'
  269.     exporting
  270.       buffer        = document
  271.     importing
  272.       output_length = length
  273.     tables
  274.       binary_tab    = bin_tab.
  275.  
  276.   call method lo_gui->file_save_dialog
  277.     exporting
  278.       default_extension = 'pdf'
  279.       default_file_name = 'failure.pdf'
  280.       file_filter       = filter
  281.     changing
  282.       filename          = name
  283.       path              = path
  284.       fullpath          = fullpath
  285.       user_action       = uact.
  286.  
  287.   if sy-subrc <> 0.
  288.     if sy-msgid is initial or sy-msgty is initial.
  289.       message e022(po) with sy-subrc.
  290.     else.
  291.       message id sy-msgid type sy-msgty number sy-msgno
  292.               with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  293.     endif.
  294.   endif.
  295.  
  296.   if uact = lo_gui->action_cancel.
  297.     exit.
  298.   endif.
  299.  
  300.   lo_gui->gui_download( exporting
  301.                           filename = fullpath
  302.                           filetype = 'BIN'
  303.                           bin_filesize = length
  304.                         changing
  305.                           data_tab = bin_tab
  306.                         exceptions
  307.                           file_write_error          = 1
  308.                           no_batch                  = 2
  309.                           gui_refuse_filetransfer   = 3
  310.                           invalid_type              = 4
  311.                           no_authority              = 5
  312.                           unknown_error             = 6
  313.                           header_not_allowed        = 7
  314.                           separator_not_allowed     = 8
  315.                           filesize_not_allowed      = 9
  316.                           header_too_long           = 10
  317.                           dp_error_create           = 11
  318.                           dp_error_send             = 12
  319.                           dp_error_write            = 13
  320.                           unknown_dp_error          = 14
  321.                           access_denied             = 15
  322.                           dp_out_of_memory          = 16
  323.                           disk_full                 = 17
  324.                           dp_timeout                = 18
  325.                           file_not_found            = 19
  326.                           dataprovider_exception    = 20
  327.                           control_flush_error       = 21
  328.                           not_supported_by_gui      = 22
  329.                           error_no_gui              = 23
  330.                           others                    = 24 ).
  331.  
  332.   if sy-subrc <> 0.
  333.     if sy-msgid is initial or sy-msgty is initial.
  334.       message e022(po) with sy-subrc.
  335.     else.
  336.       message id sy-msgid type sy-msgty number sy-msgno
  337.               with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  338.     endif.
  339.   endif.
  340.  
  341. endform.
  342.  
  343. form get_pdffiles using p_sel changing pt_files type t_fileinfotab lnum type i.
  344.  
  345.   data lo_gui type ref to cl_gui_frontend_services.
  346.   data lv_file_path type string.
  347.   data lt_files type filetable.
  348.   data l_data type xstring.
  349.   data wa_fil type t_fileinfo.
  350.   data lt_data type standard table of rspolpbi.
  351.   data lv_browse_rc type i.
  352.  
  353.   create object lo_gui.
  354. *
  355. *  if p_sel = 1.
  356. *
  357. *    lo_gui->directory_browse( exporting window_title = text1
  358. *                              changing selected_folder = lv_file_path ).
  359. *    if sy-subrc <> 0.
  360. *      if sy-msgid is initial or sy-msgty is initial.
  361. *        message e022(po) with sy-subrc.
  362. *      else.
  363. *        message id sy-msgid type sy-msgty number sy-msgno
  364. *                 with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  365. *      endif.
  366. *
  367. *      return.
  368. *    endif.
  369. *
  370. *    lo_gui->directory_list_files( exporting directory = lv_file_path
  371. *                                            filter = '*.pdf'
  372. *                                            files_only = abap_true
  373. *                                  changing  file_table = lt_files
  374. *                                            count      = lnum
  375. *                                  exceptions cntl_error                  = 1
  376. *                                             directory_list_files_failed = 2
  377. *                                             wrong_parameter             = 3
  378. *                                             error_no_gui                = 4
  379. *                                             not_supported_by_gui        = 5 ).
  380. *
  381. *    if sy-subrc <> 0.
  382. *      if sy-msgid is initial or sy-msgty is initial.
  383. *        message e022(po) with sy-subrc.
  384. *      else.
  385. *        message id sy-msgid type sy-msgty number sy-msgno
  386. *                 with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  387. *      endif.
  388. *
  389. *      return.
  390. *    endif.
  391. *
  392. *  else.
  393. *
  394. *    lo_gui->file_open_dialog( exporting
  395. *                                window_title = text1
  396. *                                multiselection = abap_true
  397. *                              changing
  398. *                                file_table     = lt_files
  399. *                                rc             = lv_browse_rc
  400. *                              exceptions
  401. *                                file_open_dialog_failed = 1
  402. *                                cntl_error              = 2
  403. *                                error_no_gui            = 3
  404. *                                not_supported_by_gui    = 4
  405. *                                others                  = 5 ).
  406. *
  407. *  endif.
  408. *
  409. *  if sy-subrc <> 0.
  410. *    if sy-msgid is initial or sy-msgty is initial.
  411. *      message e022(po) with sy-subrc.
  412. *    else.
  413. *      message id sy-msgid type sy-msgty number sy-msgno
  414. *              with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  415. *    endif.
  416. *
  417. *    return.
  418. *  endif.
  419. data: l_name type EPS2FILNAM,
  420.       t_tab_01   TYPE STANDARD TABLE OF EPS2FILI.
  421. l_name = p_dir.
  422. CALL FUNCTION 'EPS2_GET_DIRECTORY_LISTING'
  423.   EXPORTING
  424.     iv_dir_name                  = l_name
  425.    FILE_MASK                    = '*.*'
  426. * IMPORTING
  427. *   DIR_NAME                     =
  428. *   FILE_COUNTER                 =
  429. *   ERROR_COUNTER                =
  430.   tables
  431.     dir_list                     = t_tab_01
  432.  EXCEPTIONS
  433.    INVALID_EPS_SUBDIR           = 1
  434.    SAPGPARAM_FAILED             = 2
  435.    BUILD_DIRECTORY_FAILED       = 3
  436.    NO_AUTHORIZATION             = 4
  437.    READ_DIRECTORY_FAILED        = 5
  438.    TOO_MANY_READ_ERRORS         = 6
  439.    EMPTY_DIRECTORY_LIST         = 7
  440.    OTHERS                       = 8.
  441.  
  442. delete t_tab_01 where name np p_mask.
  443.  
  444.  
  445.  
  446. *  loop at lt_files into data(wa).
  447.   loop at t_tab_01 into data(wa).
  448.     refresh lt_data.
  449.     clear wa_fil.
  450.  
  451.     if p_sel = 1.
  452.       concatenate p_dir '/' wa-name into wa_fil-filename.
  453.     else.
  454.       move wa-name to wa_fil-filename.
  455.       lnum = lnum + 1.
  456.     endif.
  457.      wa_fil-len = wa-SIZE.
  458.  
  459. *    lo_gui->gui_upload( exporting filename = wa_fil-filename
  460. *                                  filetype = 'BIN'
  461. *                        importing filelength = wa_fil-len
  462. *                        changing  data_tab = lt_data
  463. *                        exceptions
  464. *                                  file_open_error         = 1
  465. *                                  file_read_error         = 2
  466. *                                  no_batch                = 3
  467. *                                  gui_refuse_filetransfer = 4
  468. *                                  invalid_type            = 5
  469. *                                  no_authority            = 6
  470. *                                  unknown_error           = 7
  471. *                                  bad_data_format         = 8
  472. *                                  header_not_allowed      = 9
  473. *                                  separator_not_allowed   = 10
  474. *                                  header_too_long         = 11
  475. *                                  unknown_dp_error        = 12
  476. *                                  access_denied           = 13
  477. *                                  dp_out_of_memory        = 14
  478. *                                  disk_full               = 15
  479. *                                  dp_timeout              = 16
  480. *                                  not_supported_by_gui    = 17
  481. *                                  error_no_gui            = 18
  482. *                                  others                  = 19 ).
  483. data: lv_buffer type rspolpbi.
  484.         OPEN DATASET  wa_fil-filename FOR INPUT IN binary MODE.
  485. *          ENCODING DEFAULT WITH SMART LINEFEED IGNORING CONVERSION ERRORS.
  486.  
  487.         IF sy-subrc <> 0.
  488.            message e022(po) with sy-subrc.
  489.           CONTINUE.
  490.         ENDIF.
  491.  
  492.         DO.
  493.           READ DATASET wa_fil-filename INTO lv_buffer-data.
  494.  
  495.           IF sy-subrc <> 0.
  496.             EXIT.
  497.           ENDIF.
  498.  
  499.           APPEND lv_buffer TO lt_data.
  500.  
  501.         ENDDO.
  502.  
  503.  
  504.  
  505. *    if sy-subrc <> 0.
  506. *      if sy-msgid is initial or sy-msgty is initial.
  507. *        message e022(po) with sy-subrc.
  508. *      else.
  509. *        message id sy-msgid type sy-msgty number sy-msgno
  510. *                with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  511. *      endif.
  512. *
  513. *      return.
  514. *    endif.
  515.  
  516.     perform table2xstring tables lt_data
  517.                           using  wa_fil-data
  518.                                  wa_fil-len.
  519.  
  520.     write: / wa(50) color col_normal, 'Len', wa_fil-len.
  521.     append wa_fil to pt_files.
  522.  
  523.  
  524.   endloop.
  525.     lnum = lines( pt_files ).
  526.   write: / 'Number of PDF files:'(007), lnum.
  527.  
  528. endform.
  529.  
  530. form table2xstring tables pt_data structure rspolpbi
  531.                    using  p_data type xstring
  532.                           p_len type i.
  533.  
  534.   data l_rest type i.
  535.   data l_chunk type i.
  536.  
  537.   l_rest = p_len.
  538. CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
  539.   EXPORTING
  540.     input_length       = p_len
  541. *   FIRST_LINE         = 0
  542. *   LAST_LINE          = 0
  543.  IMPORTING
  544.    BUFFER             = p_data
  545.   tables
  546.     binary_tab         = pt_data
  547.  EXCEPTIONS
  548.    FAILED             = 1
  549.    OTHERS             = 2
  550.           .
  551. IF sy-subrc <> 0.
  552. * Implement suitable error handling here
  553. ENDIF.
  554.  
  555. *  clear p_data.
  556. *  loop at pt_data into data(wa).
  557. *    if l_rest < 128.
  558. *      l_chunk = l_rest.
  559. *    else.
  560. *      l_chunk = 128.
  561. *    endif.
  562. *
  563. *    concatenate p_data wa-data(l_chunk) into p_data in byte mode.
  564. *    subtract l_chunk from l_rest.
  565. *  endloop.
  566.  
  567. endform.
  568.  
  569. form merge_pdfs using pt_files type t_fileinfotab
  570.                       pt_display_options type t_displayoption
  571.                 changing pdf_merger type ref to cl_rspo_pdf_merge
  572.                          merged_document
  573.                          error_text
  574.                          docindex
  575.                          errordoc
  576.                          rc.
  577.  
  578.   data: wa type line of t_fileinfotab.
  579.   data: i type i value 1.
  580.  
  581. * Add documents to attribut table of PDF merger
  582.   loop at pt_files into wa.
  583.  
  584.     rc = 0.
  585.  
  586.     if p_hd_pc = 'X'.
  587.        pdf_merger->check_document( exporting document = wa-data importing error_text = error_text rc = rc ).
  588.     endif.
  589.  
  590.     if rc = 0.
  591.        pdf_merger->add_document( wa-data ).
  592.     else.
  593.        write: / 'Error for document number '(012), i, ' : ', error_text color col_negative.
  594.        write: / 'Document will not be merged'(013).
  595.     endif.
  596.  
  597.     i = i + 1.
  598.  
  599.   endloop.
  600.  
  601.   rc = 0.
  602.  
  603. * Display options for merged PDF are optional. A built-in default is used if not specified.
  604.   if pt_display_options-page_mode <> 0.
  605.     pdf_merger->set_page_mode( pt_display_options-page_mode ).
  606.   endif.
  607.  
  608.   if pt_display_options-page_layout <> 0.
  609.     pdf_merger->set_page_layout( pt_display_options-page_layout ).
  610.   endif.
  611.  
  612.   if pt_display_options-hide_menubar <> 0.
  613.     pdf_merger->set_hide_menubar( pt_display_options-hide_menubar ).
  614.   endif.
  615.  
  616.   if pt_display_options-hide_toolbar <> 0.
  617.     pdf_merger->set_hide_toolbar( pt_display_options-hide_toolbar ).
  618.   endif.
  619.  
  620. * Call kernel method to do the merge of the specified files.
  621.   pdf_merger->merge_documents( importing merged_document = merged_document rc = rc ).
  622.  
  623. * Get index of failed document
  624.   if rc <> 0.
  625.     pdf_merger->get_err_doc_index( importing index = docindex ).
  626.     pdf_merger->get_document( exporting index = docindex importing document = errordoc ).
  627.     pdf_merger->get_last_error_text( changing error_text = error_text ).
  628.   endif.
  629.  
  630.   clear pdf_merger.
  631.  
  632. endform.
  633.