2009 Jul 09 10:06 AM
Hello experts,
I've been searching around to get some code examples to upload a word document and convert it into a PDF file and then store it in unix. I hope one of you can help me, because many explanations and threads exist, but I did not get wiser reading them...
I don't want to use 3rd party tools to do the conversion, but do it directly in SAP with abap coding and if necessary spool processing.
System details:
SAP ECC 6.0 (unicode system)
SAP_ABA 700 0014 SAPKA70014 Cross-Application Component
SAP_BASIS 700 0014 SAPKB70014 SAP Basis Component
Thanks in advance!
Regards,
Danny
2009 Jul 09 10:16 AM
2009 Jul 09 10:26 AM
hi,
use FM CONVERT_OTFSPOOLJOB_2_PDF
example see reports RSTXPDFT4 and RSPO0068
thanks
2009 Jul 09 10:31 AM
Please do not refer to other threads or just copy a function module. i would like to have some example coding to upload a word document and convert it into PDF.
Thanks!
Regards,
Danny
2009 Jul 09 10:35 AM
2009 Jul 09 10:51 AM
Hi,
You can get the spool no from transaction SP01 and later use this spool no to convert the word document to PDF
using the function module CONVERT_OTFSPOOLJOB_2_PDF and give the import parameter as ur spool id.
once the doc gets converted to PDF u can use CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_SAVE_DIALOG
to get the path where the file is to be saved and later give the path to function module GUI_DOWNLOAD to download the file.
or else u can manually execute the following reports:
RSTXPDFT4 (give the spool no. as input)
RSPO0068 (give the word doc with its full path as input)
Hope that helps u
Regards,
Radhika
2023 Jan 11 12:41 AM
vers 0.3 beta
DATA lv_pdf_xstring TYPE xstring.
CALL FUNCTION 'ZHR_CONVERT_WORD_2_PDF'
EXPORTING
i_temp_xstring = lv_xlm_xstring
i_temp_extension = '.docx'
CHANGING
c_pdf_xstring = lv_pdf_xstring.
<br>
I_FILE_PATH TYPE ANY 'C:\Temp\test.docx'
I_TEMP_XSTRING TYPE XSTRING XSTRING DATA
I_TEMP_EXTENSION TYPE ANY '.DOC' '.DOCX' '.DOCM'
I_SAVE_FILE_NAME TYPE ANY if need change name
I_SAVE_DIRECTORY TYPE ANY 'C:\Temp\' if need save
C_PDF_XSTRING TYPE XSTRING XSTRING DATA
FUNCTION zhr_convert_word_2_pdf.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*" IMPORTING
*" REFERENCE(I_FILE_PATH) TYPE ANY OPTIONAL
*" REFERENCE(I_TEMP_XSTRING) TYPE XSTRING OPTIONAL
*" REFERENCE(I_TEMP_EXTENSION) TYPE ANY OPTIONAL
*" REFERENCE(I_SAVE_FILE_NAME) TYPE ANY OPTIONAL
*" REFERENCE(I_SAVE_DIRECTORY) TYPE ANY OPTIONAL
*" CHANGING
*" REFERENCE(C_PDF_XSTRING) TYPE XSTRING OPTIONAL
*"----------------------------------------------------------------------
**********************************************************************
"Info.
"
*"var1.
*"IMPORTING
"i_file_path = 'C:\Temp\test.docx'
"I_SAVE_DIRECTORY = 'C:\Temp\' or ''
**********************************************************************
*"var2.
*"IMPORTING
"i_file_path = ' '
"I_TEMP_XSTRING = lv_xstring
"I_TEMP_EXTENSION = '.docx'
"I_SAVE_FILE_NAME = 'test' / ''
"I_SAVE_DIRECTORY = 'C:\Temp\' or ''
**********************************************************************
" in end we have
" C_PDF_XSTRING OR 'C:\Temp\test.pdf'
**********************************************************************
"|||||||
"->OLE2
INCLUDE ole2incl.
DATA: word TYPE ole2_object,
doc_temp TYPE ole2_object,
doc_pdf TYPE ole2_object
.
"<-OLE2
"|||||||
"->SAVE_ON_PC
TYPES: ty_x_row_type(100) TYPE x.
DATA: lt_bin_data TYPE STANDARD TABLE OF ty_x_row_type,
ls_bin_data LIKE LINE OF lt_bin_data.
DATA: lv_bin_data_len TYPE i.
"<-SAVE_ON_PC
"|||||||
DATA: lv_file_dir TYPE string,
lv_file_name TYPE string,
lv_open_path TYPE string,
lv_save_path TYPE string,
lv_save_dir TYPE string,
lv_time TYPE char8,
lt_ram TYPE TABLE OF string, " WITH HEADER LINE,
lv_ram TYPE string,
lv_index TYPE i,
lv_split TYPE char1
.
DATA lv_postfix TYPE i.
DATA lv_index_wait TYPE i.
DATA lv_file_found_switch TYPE flag.
DATA lv_rc TYPE i .
lv_postfix = 1.
**********************************************************************
**********************************************************************
"проверяем что либо данные либо путь к данным был.
IF sy-uname NE 'CSTSOKOLK'.
CHECK i_temp_xstring IS NOT INITIAL
OR i_file_path IS NOT INITIAL.
IF i_temp_extension IS INITIAL AND i_file_path IS INITIAL.
MESSAGE s298(00) WITH 'se37:ZHR_CONVERT_WORD_2_PDF value:I_TEMP_EXTENSION' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
ENDIF.
**********************************************************************
**********************************************************************
"Получаем имя файла
"lv_file_name
IF i_save_file_name IS NOT INITIAL.
lv_file_name = i_save_file_name.
ELSEIF i_file_path IS NOT INITIAL.
CLEAR:lt_ram[], lv_split.
SPLIT i_file_path AT '\' INTO TABLE lt_ram."разбиваем 'C:\Temp\test.docx' на 'C:' 'Temp' 'test.docx'
READ TABLE lt_ram INTO lv_ram INDEX lines( lt_ram )."берем 'test.docx'
CLEAR:lt_ram[], lv_split.
SPLIT lv_ram AT '.' INTO TABLE lt_ram."разбиваем 'test.docx' на 'test' 'docx'
LOOP AT lt_ram INTO lv_ram.
CHECK sy-tabix NE lines( lt_ram ) OR sy-tabix = 1."первая строка обязательно. последнюю игнорим т.к. она содержит .docx
lv_file_name = lv_file_name && lv_split && lv_ram. "не забываем что сплит был по '.'
lv_split = '.'.
ENDLOOP."LOOP AT lt_ram INTO lv_ram.
CLEAR lv_ram.
ELSE.
* WRITE sy-uzeit TO lv_time USING EDIT MASK '__-__-__'.
* lv_file_name = |{ sy-uname }—{ sy-datum+6(2) }.{ sy-datum+4(2) }.{ sy-datum+0(4) }—{ lv_time }|.
lv_file_name = |{ sy-uname }—{ sy-datum+6(2) }.{ sy-datum+4(2) }.{ sy-datum+0(4) }|.
ENDIF.
**********************************************************************
**********************************************************************
*Получаем
*lv_save_dir и lv_save_path
IF i_save_directory IS NOT INITIAL.
lv_save_dir = i_save_directory.
lv_save_path = lv_save_dir && '\' && lv_file_name.
ELSEIF i_file_path IS NOT INITIAL." из C:\Temp\test.docx в C:\Temp\test.PDF
*=================
"lv_save_path
CLEAR:lt_ram[], lv_split.
SPLIT i_file_path AT '.' INTO TABLE lt_ram."разбиваем 'C:\Temp\test.docx' на 'C:\Temp\test' 'docx'
LOOP AT lt_ram INTO lv_ram.
CHECK sy-tabix NE lines( lt_ram ) OR sy-tabix = 1."первая строка обязательно. последнюю игнорим т.к. она содержит .docx
lv_save_path = lv_save_path && lv_split && lv_ram. "не забываем что сплит был по '.'
lv_split = '.'.
ENDLOOP."LOOP AT lt_ram INTO lv_ram.
*=================
"lv_save_dir "получить Директорию расположения файла
CLEAR:lt_ram[], lv_split.
SPLIT lv_save_path AT '\' INTO TABLE lt_ram."разбиваем 'C:\Temp\test' на 'C:' 'Temp' 'test'
LOOP AT lt_ram INTO lv_ram.
CHECK sy-tabix NE lines( lt_ram ) OR sy-tabix = 1."первая строка обязательно. последнюю игнорим т.к. она содержит file_name
lv_save_dir = lv_save_dir && lv_split && lv_ram. "не забываем что сплит был по '\'
lv_split = '\'.
ENDLOOP."LOOP AT lt_ram INTO lv_ram.
*=================
ENDIF."IF i_save_directory IS NOT INITIAL.
IF lv_save_path IS INITIAL.
"Temporary Directory
cl_gui_frontend_services=>get_temp_directory(
CHANGING temp_dir = lv_save_dir " Temporary Directory
EXCEPTIONS OTHERS = 4 ).
cl_gui_cfw=>flush( EXCEPTIONS OTHERS = 3 ).
IF lv_save_dir IS NOT INITIAL.
lv_save_path = lv_save_dir && '\' && lv_file_name.
ELSE.
lv_save_dir = 'C:\TEMP'.
lv_save_path = 'C:\TEMP\' && lv_file_name.
ENDIF.
ENDIF.
**********************************************************************
**********************************************************************
REPLACE ALL OCCURRENCES OF `\\` IN lv_save_path WITH '\'.
REPLACE ALL OCCURRENCES OF `..` IN lv_save_path WITH '.'.
IF lv_save_path+0(1) EQ '\'.
lv_save_path = '\' && lv_save_path.
ENDIF.
**********************************************************************
**********************************************************************
"lv_open_path "конечный путь файла где лежит наш WORD
IF i_file_path IS NOT INITIAL AND i_temp_xstring IS INITIAL.
lv_open_path = i_file_path. "если файл уже есть
ELSEIF i_temp_xstring IS NOT INITIAL."иначе сохранить DOC
**********************************************************************
*добавление индекса к lv_open_path чтобы не было совпадений
*(чтобы RAM файл не существовал)
DO.
lv_open_path = lv_save_path && '_' && lv_postfix && i_temp_extension .
PERFORM check_file USING lv_open_path CHANGING lv_file_found_switch.
IF lv_file_found_switch IS INITIAL.
EXIT."DO
ENDIF.
ADD 1 TO lv_postfix .
ENDDO."DO.
**********************************************************************
"сохраняем файл из xstring для дальнейшей работы с ним
IF lv_save_path+0(1) NE `\`.
"->SAVE_ON_PC
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = i_temp_xstring
IMPORTING
output_length = lv_bin_data_len
TABLES
binary_tab = lt_bin_data.
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
bin_filesize = lv_bin_data_len
filename = lv_open_path
filetype = 'BIN'
no_auth_check = abap_true
CHANGING
data_tab = lt_bin_data
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
ENDIF.
"<-SAVE_ON_PC
ELSEIF lv_save_path+0(1) EQ `\`.
"->SAVE_ON_SERVER
OPEN DATASET lv_open_path IN BINARY MODE FOR OUTPUT.
IF sy-subrc <> 0.
MESSAGE s811(00) DISPLAY LIKE 'E'.
ELSEIF sy-subrc = 0.
TRANSFER i_temp_xstring TO lv_open_path.
CLOSE DATASET lv_open_path.
ENDIF.
ENDIF."IF lv_save_path+0(1) NE `\`.
"<-SAVE_ON_SERVER
ELSE.
RETURN.
ENDIF."IF i_file_path IS NOT INITIAL.
**********************************************************************
*Запуск конвертации DOC -> PDF
"->OLE2
IF i_file_path IS INITIAL.
lv_save_path = lv_save_path && '_' && lv_postfix && '.PDF'.
ELSE.
lv_save_path = lv_save_path && '_' && '.PDF'.
ENDIF.
CREATE OBJECT word 'Word.Application'.
* CREATE OBJECT word 'Excel.application'.
SET PROPERTY OF word 'Visible' = 0.
CALL METHOD OF word 'Documents' = doc_temp.
CALL METHOD OF doc_temp 'OPEN'
EXPORTING
#1 = lv_open_path
#2 = 0
#12 = 0.
CALL METHOD OF word 'ActiveDocument' = doc_pdf.
CALL METHOD OF doc_pdf 'SaveAs2'
EXPORTING
#1 = lv_save_path
#2 = 17. "PDF
CALL FUNCTION 'FLUSH'.
CALL METHOD OF word 'QUIT'.
* CALL METHOD OF word 'APPCLOSE'.
*->??
CALL METHOD OF doc_pdf 'CLOSE'
EXPORTING
#1 = 0.
CALL METHOD OF doc_temp 'CLOSE'
EXPORTING
#1 = 0.
*<-??
FREE OBJECT word .
FREE OBJECT doc_pdf .
FREE OBJECT doc_temp .
CALL FUNCTION 'FLUSH'.
"<-OLE2
* WAIT UP TO '0.1' SECONDS . "NEED?wathever?
**********************************************************************
"дебаг проверка
DO.
PERFORM check_file USING lv_save_path CHANGING lv_file_found_switch.
IF NOT lv_file_found_switch IS INITIAL.
EXIT.
ELSE.
ADD 1 to lv_index_wait.
WAIT UP TO '0.1' SECONDS.
IF lv_index_wait > 100.
BREAK-POINT."не конвертируется. возможно WORD требует залогинится.
ENDIF.
ENDIF.
ENDDO.
**********************************************************************
"RETURN xstring PDF
IF lv_save_path+0(1) NE `\`.
"->OPEN_xstring_PC
CLEAR lt_bin_data[].
CLEAR lv_index.
CALL METHOD cl_gui_frontend_services=>gui_upload
EXPORTING
filename = lv_save_path "PDF
filetype = 'BIN'
IMPORTING
filelength = lv_index
CHANGING
data_tab = lt_bin_data
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
ENDIF.
CLEAR c_pdf_xstring.
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = lv_index
* FIRST_LINE = 0
* LAST_LINE = 0
IMPORTING
buffer = c_pdf_xstring
TABLES
binary_tab = lt_bin_data
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
"<-OPEN_xstring_PC
ELSEIF lv_save_path+0(1) EQ `\`.
"->OPEN_xstring_SERVER
"PS не тестировал OPEN SERVER вообще
OPEN DATASET lv_open_path IN BINARY MODE FOR OUTPUT.
IF sy-subrc <> 0.
MESSAGE s811(00) DISPLAY LIKE 'E'.
ELSEIF sy-subrc = 0.
CLEAR lv_index.
READ DATASET lv_open_path INTO c_pdf_xstring ACTUAL LENGTH lv_index.
CLOSE DATASET lv_open_path.
ENDIF.
ENDIF.
**********************************************************************
"Очистка мусора
IF c_pdf_xstring IS NOT INITIAL.
IF lv_save_path+0(1) NE `\`.
CALL METHOD cl_gui_frontend_services=>file_delete
EXPORTING
filename = lv_save_path
CHANGING
rc = lv_rc
EXCEPTIONS
file_delete_failed = 1
cntl_error = 2
error_no_gui = 3
file_not_found = 4
access_denied = 5
unknown_error = 6
not_supported_by_gui = 7
wrong_parameter = 8
OTHERS = 9.
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CALL METHOD cl_gui_frontend_services=>file_delete
EXPORTING
filename = lv_open_path
CHANGING
rc = lv_rc
EXCEPTIONS
file_delete_failed = 1
cntl_error = 2
error_no_gui = 3
file_not_found = 4
access_denied = 5
unknown_error = 6
not_supported_by_gui = 7
wrong_parameter = 8
OTHERS = 9.
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ELSE.
DELETE DATASET lv_save_path.
DELETE DATASET lv_open_path.
ENDIF.
ELSE.
BREAK-POINT.
ENDIF."IF lv_save_path IS NOT INITIAL.
ENDFUNCTION.
**********************************************************************
*
*
**********************************************************************
FORM check_file USING uv_path TYPE string CHANGING lv_found TYPE flag.
DATA: lv_eps2filnam TYPE eps2filnam,
lt_dir_list TYPE STANDARD TABLE OF eps2fili,
ls_dir_list LIKE LINE OF lt_dir_list.
DATA: lt_file_table TYPE filetable,
ls_file_table LIKE LINE OF lt_file_table,
lv_count TYPE i,
lv_file_name TYPE string,
lv_file_dir TYPE string.
CLEAR lt_file_table.
lv_found = abap_false.
PERFORM get_file_name_by_path USING uv_path CHANGING lv_file_name."PS! NEED '.doc' or '.pdf' in path
PERFORM get_file_dir_by_path USING uv_path CHANGING lv_file_dir."PS! NEED '.doc' or '.pdf' in path
IF uv_path+0(1) NE `\`.
cl_gui_frontend_services=>directory_list_files(
EXPORTING
directory = lv_file_dir
* filter = '*.*'
* files_only =
* directories_only =
CHANGING
file_table = lt_file_table
count = lv_count
EXCEPTIONS
cntl_error = 1
directory_list_files_failed = 2
wrong_parameter = 3
error_no_gui = 4
not_supported_by_gui = 5
OTHERS = 6
).
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
LOOP AT lt_file_table INTO ls_file_table WHERE filename EQ lv_file_name .
lv_found = abap_true.
ENDLOOP.
ELSE.
lv_eps2filnam = lv_file_dir.
CALL FUNCTION 'EPS2_GET_DIRECTORY_LISTING' " или EPS_GET_DIRECTORY_LISTING
EXPORTING
iv_dir_name = lv_eps2filnam
TABLES
dir_list = lt_dir_list
EXCEPTIONS
invalid_eps_subdir = 1
sapgparam_failed = 2
build_directory_failed = 3
no_authorization = 4
read_directory_failed = 5
too_many_read_errors = 6
empty_directory_list = 7
OTHERS = 8.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
LOOP AT lt_dir_list INTO ls_dir_list WHERE name EQ lv_file_name.
lv_found = abap_true.
ENDLOOP.
ENDIF.
ENDFORM.
FORM get_file_name_by_path USING uv_path TYPE string CHANGING cv_name TYPE string.
"PS! NEED '.doc' or '.pdf' in path
DATA: lt_ram TYPE TABLE OF string,
lv_ram TYPE string.
* CHECK uv_path CS '.'.
SPLIT uv_path AT '\' INTO TABLE lt_ram."разбиваем 'C:\Temp\txt.doc' на 'C:' 'Temp' 'txt.doc'
READ TABLE lt_ram INTO cv_name INDEX lines( lt_ram )."берем 'test.docx'
ENDFORM.
FORM get_file_dir_by_path USING uv_path TYPE string CHANGING cv_dir TYPE string.
"PS! NEED '.doc' or '.pdf' in path
DATA: lt_ram TYPE TABLE OF string,
lv_ram TYPE string,
lv_split TYPE char1.
CLEAR:lt_ram[].
CHECK uv_path CS '.'."NEED
IF uv_path+0(1) EQ '\'.
cv_dir = `\\`.
ENDIF.
SPLIT uv_path AT '\' INTO TABLE lt_ram."разбиваем 'C:\Temp\txt.doc' на 'C:' 'Temp' 'txt.doc'
LOOP AT lt_ram INTO lv_ram.
CHECK lv_ram IS NOT INITIAL.
CHECK NOT lv_ram CS '.'.
cv_dir = cv_dir && lv_split && lv_ram.
lv_split = '\'.
ENDLOOP."LOOP AT lt_ram INTO lv_ram.
cv_dir = cv_dir && `\`.
ENDFORM.
<br>
2025 Jan 17 10:16 AM