业务需求:对财务凭证报表打印。
报表要求:在报表左右分屏显示,右侧为凭证抬头信息,凭证号可点击,在左侧展示smartforms对应的pdf 预览,工具栏添加正常打印按钮,可选中多个凭证,打印对应凭证行项目信息。
实现思路:对容器进行上下拆分,上 为 html top 信息 下进行左右拆分,左为PDF容器,又为ALV 容器;,初始PDF为首条凭证,通过ALV单击事件,重新读取凭证信息生成PDF展示;打印按钮与pdf输出 共用逻辑,其中判断是直接打印还是pdf输出。
实际问题:在单击凭证时,重新读取到凭证信息生成PDF,通过再次调用PDF 输出方法,发现屏幕没有更新,各种重置容器,重置类发现还是没有刷新,认知是没有刷新,所以百度查询某个提示说SAP GUI PDF 不支持刷新,就没往这个思路走了。
框架调整:由于其他系统有类似案例,所以直接参考使用,其思路为,首先调用ALV 屏幕,容器不指定实现,将打印功能封装在函数组,在单击凭证后调用函数,函数包含data数据转换otf数据,并且直接调用在函数组内创建的显示屏幕;
该框架实现结果为:初始界面只有ALV,点击凭证左侧为PDF,右侧为ALV,且PDF可刷新,但是参考案例菜单栏是没有功能按钮的,此处有打印按钮,在选择数据点击打印时发现,该框架ALV不会被打印覆盖,跳转到了打印预览界面,但是展示内容还是ALV
点击按钮
此处弹出框,是PC未下载PDF 阅读器,可参考使用adobe acrobat reader dc,若是提示语言包没有,可以搜索下载对应版本的语言包,打补丁即可,在系统设置PDF默认使用改软件打开即可,由于环境限制没有下载,在业务顾问电脑直接测试
此处导致刷新和打印按钮都没了,由于功能设计是 提交/审批流程 ,提交是不需要PDF预览的,在pdf界面可以打印,但是就是会出现前面所说问题,工具已经转换,但是容器ALV仍在
ALV 屏幕,直接使用空容器实例化 grid
CREATE OBJECT g_alv_grid
EXPORTING
i_parent = g_docking_container.
PDF 屏幕
全局定义,此处不分开贴写了
DATA: gcl_pdf_container TYPE REF TO cl_gui_docking_container.
DATA: gcl_pdf_viewer TYPE REF TO cl_gui_html_viewer.
DATA: gv_pdf_filesize TYPE i.
DATA: gt_pdf_lines TYPE rcl_bag_tline.
DATA: ls_pdf_lines TYPE tline.
DATA: lv_content TYPE xstring.
DATA: lt_pdf_data TYPE STANDARD TABLE OF x255.
DATA: lv_url(255).
FIELD-SYMBOLS <fs_pdf_lines_x> TYPE x.
IF gcl_pdf_container IS INITIAL.
CREATE OBJECT gcl_pdf_container
EXPORTING
side = cl_gui_docking_container=>dock_at_left
* extension = 9999
ratio = 61
repid = sy-repid
dynnr = '9000'.
CREATE OBJECT gcl_pdf_viewer
EXPORTING
parent = gcl_pdf_container.
ENDIF.
CLEAR: lt_pdf_data.
CLEAR: lv_url.
CLEAR: lv_content.
* convert pdf to xstring string
LOOP AT gt_pdf_lines INTO ls_pdf_lines .
ASSIGN ls_pdf_lines TO <fs_pdf_lines_x> CASTING.
CONCATENATE lv_content <fs_pdf_lines_x> INTO lv_content IN BYTE MODE.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_content
TABLES
binary_tab = lt_pdf_data.
ENDLOOP.
CALL METHOD gcl_pdf_viewer->load_data
EXPORTING
size = gv_pdf_filesize
type = 'APPLICATION'
subtype = 'PDF'
IMPORTING
assigned_url = lv_url
CHANGING
data_table = lt_pdf_data.
CALL METHOD gcl_pdf_viewer->show_data
EXPORTING
url = lv_url.
所以按照需求回归到初始拆分显示思路,参照容器显示ALV刷新逻辑,思路还是往刷新方向走,所以直接去实现类 gcl_pdf_viewer 里直接去找
发现该方法DO_REFRESH和对应描述有点感觉
所以尝试加入代码使用,配合容器和show_data 的方法
DATA: ls_pdf_lines TYPE tline,
lv_content TYPE xstring,
lt_pdf_data TYPE STANDARD TABLE OF x255,
lv_url(255).
FIELD-SYMBOLS <fs_pdf_lines_x> TYPE x.
IF gcl_pdf_viewer IS BOUND.
ELSE.
CREATE OBJECT gcl_pdf_viewer
EXPORTING
parent = g_container_2.
ENDIF.
LOOP AT gt_pdf_lines INTO ls_pdf_lines .
ASSIGN ls_pdf_lines TO <fs_pdf_lines_x> CASTING.
CONCATENATE lv_content <fs_pdf_lines_x> INTO lv_content IN BYTE MODE.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_content
TABLES
binary_tab = lt_pdf_data.
ENDLOOP.
CALL METHOD gcl_pdf_viewer->load_data
EXPORTING
size = gv_pdf_filesize
type = 'APPLICATION'
subtype = 'PDF'
IMPORTING
assigned_url = lv_url
CHANGING
data_table = lt_pdf_data.
CALL METHOD gcl_pdf_viewer->show_data
EXPORTING
url = lv_url
in_place = 'X'.
CALL METHOD gcl_pdf_viewer->do_refresh.
其实按照数据逻辑,应该把生成URL 前面的所有步骤都放入数据转换PDF 的逻辑里,不过此处没有调整了,之前找过来的代码就直接使用了
转pdf逻辑
全局定义
DATA: gcl_pdf_viewer TYPE REF TO cl_gui_html_viewer.
DATA: gv_pdf_filesize TYPE i.
DATA: gt_pdf_lines TYPE rcl_bag_tline.
FORM frm_set_pdf TABLES pt_data LIKE gt_data[].
DATA:lt_print TYPE STANDARD TABLE OF zfis0090a,
lt_otf TYPE tsfotf.
*--数据整理
PERFORM frm_print_data TABLES pt_data lt_print.
"CALL FUNCTION 'ZFM_FI_PRINT'
" EXPORTING
" iv_smartform_name = 'ZFIF0063'
" iv_approve = 'X'
" iv_title = gv_gui_title
" iv_lines = 'X'
" TABLES
" t_print = lt_print.
""it_tsfotf = lt_otf.
*--打印输出
PERFORM frm_call_smartform TABLES lt_print[] lt_otf[].
*--数据转换
PERFORM frm_convert_otf TABLES lt_otf.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CALL_SMARTFORM
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LT_PRINT[] text
*----------------------------------------------------------------------*
FORM frm_call_smartform TABLES pt_print STRUCTURE zfis0090a
pt_otf TYPE tsfotf.
DATA: lv_spld TYPE usr01-spld.
DATA:fm_name TYPE rs38l_fnam,
control TYPE ssfctrlop,
output_options TYPE ssfcompop,
job_output_info TYPE ssfcrescl.
CLEAR:pt_otf[].
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
formname = 'ZFIF0063'
* VARIANT = ' '
* DIRECT_CALL = ' '
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.
* CONTROL-NO_DIALOG = 'X'.
* CONTROL-PREVIEW = 'X'.
* CONTROL-DEVICE = 'PRINTER'.
* OUTPUT_OPTIONS-TDDEST = 'ZPRT'.
* OUTPUT_OPTIONS-TDNOPRINT = 'X'.
IF sy-ucomm NE 'PRINT'.
PERFORM frm_get_printer CHANGING lv_spld.
SELECT SINGLE padest patype
INTO (output_options-tddest, output_options-tdprinter)
FROM tsp03d
WHERE name = lv_spld.
control-no_dialog = 'X'.
control-getotf = 'X'.
output_options-tdnoprev = 'X'.
ENDIF.
CALL FUNCTION fm_name
EXPORTING
control_parameters = control
output_options = output_options
IMPORTING
job_output_info = job_output_info
TABLES
it_tab = pt_print[]
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.
ELSE.
pt_otf[] = job_output_info-otfdata.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CONVERT_OTF
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LT_OTF text
*----------------------------------------------------------------------*
FORM frm_convert_otf TABLES pt_otf TYPE tsfotf.
CLEAR:gv_pdf_filesize,gt_pdf_lines.
CALL FUNCTION 'CONVERT_OTF'
EXPORTING
format = 'PDF'
IMPORTING
bin_filesize = gv_pdf_filesize
TABLES
otf = pt_otf[]
lines = gt_pdf_lines
EXCEPTIONS
err_max_linewidth = 1
err_format = 2
err_conv_not_possible = 3
OTHERS = 4.
ENDFORM.
其中smartforms 转PDF 的时候要输出otf,所以打印函数参数需要把 取消对话和输出OTF
control-no_dialog = 'X'.
control-getotf = 'X'.