SAP-ABAP:SAP 简单报表输出开发系列(共6篇) 第五篇:SAP 报表多格式输出:Excel/PDF 批量导出功能实现

SAP 简单报表输出开发系列(共6篇)

第五篇:SAP 报表多格式输出:Excel/PDF 批量导出功能实现

报表开发完成后,业务用户通常会提出"能否导出Excel做二次分析?"或"能否生成PDF发给领导审批?"的需求。标准ALV自带导出Excel功能,但格式较为简单;有时需要按固定模板填充数据,生成对账单、订单确认函等;甚至需要直接将ALV内容转为PDF文件。本文将详解标准ALV导出增强自定义Excel模板填充PDF文件生成三类常用输出方式的实现代码,满足业务端离线归档、二次编辑的实际需求。


一、标准ALV的Excel导出(开箱即用)

1.1 功能说明

使用REUSE_ALV_GRID_DISPLAY标准函数时,工具栏上默认就有"导出Excel"按钮(图标为绿色表格)。用户点击后,系统会将当前ALV显示的内容导出为.XLS文件(实际为HTML格式,可被Excel打开)。无需额外代码。

局限

  • 格式为HTML,不是原生.XLSX
  • 无法自定义多Sheet页、合并单元格等复杂样式。
  • 大数据量导出可能较慢。

1.2 增强导出选项(添加"本地文件"按钮)

通过设置参数i_save = 'A''X',可以让用户保存变式,同时导出格式可选择"Excel 2007(*.xlsx)"(取决于系统版本和补丁)。新版SAP GUI支持导出真正的.XLSX

abap 复制代码
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
    i_save = 'A'   " 'A' = 允许保存布局;'X' = 强制保存布局
    ...

用户点击工具栏中的"电子表格"按钮,在弹出的对话框中选择"Excel 2007(*.xlsx)"即可。


二、自定义Excel模板填充(OLE / ABAP2XLSX)

当需要生成固定格式的订单确认函、采购合同、对账单时,标准导出无法满足。此时可以使用OLE自动化 操作Excel,或使用开源库ABAP2XLSX(推荐)。

2.1 方案选择

方案 优点 缺点
OLE 系统自带,无需额外安装 速度慢,依赖前端Excel,稳定性差
ABAP2XLSX 快速,纯ABAP生成.xlsx,支持模板填充 需手动导入ZCL_EXCEL等类库
PDF生成(后续章节) 格式固定,不可编辑 不适合二次编辑

推荐:使用ABAP2XLSX(可在GitHub获取SAP标准"XLSX Workbench"或自行集成)。本文给出OLE示例(因为系统通用)和ABAP2XLSX简单示例。

2.2 OLE方式:将内表数据填充到预设模板

假设已有一个Excel模板文件(服务器路径或上传到SMW0),需要将数据写入指定单元格。

abap 复制代码
DATA: lo_excel TYPE ole2_object,
      lo_workbook TYPE ole2_object,
      lo_sheet TYPE ole2_object,
      lo_cell TYPE ole2_object.

" 创建Excel对象
CREATE OBJECT lo_excel 'EXCEL.APPLICATION'.
lo_excel-visible = 1.   " 设为1可看到Excel界面,0为后台

" 打开模板文件
CALL METHOD OF lo_excel 'Workbooks' = lo_workbook.
CALL METHOD OF lo_workbook 'Open'
  EXPORTING
    #1 = 'C:\TEMPLATE\order_template.xlsx'.

" 获取第一个工作表
CALL METHOD OF lo_workbook 'Worksheets' = lo_sheet
  EXPORTING
    #1 = 1.

" 写入单元格(第3行,第2列)
CALL METHOD OF lo_sheet 'Cells' = lo_cell
  EXPORTING
    #1 = 3
    #2 = 2.
SET PROPERTY OF lo_cell 'Value' = lv_order_no.

" 保存为新文件
CALL METHOD OF lo_workbook 'SaveAs'
  EXPORTING
    #1 = 'C:\OUTPUT\order_output.xlsx'.

" 关闭并释放内存
CALL METHOD OF lo_workbook 'Close'.
CALL METHOD OF lo_excel 'Quit'.
FREE OBJECT lo_cell; FREE OBJECT lo_sheet; FREE OBJECT lo_workbook; FREE OBJECT lo_excel.

注意:OLE方式需要在应用服务器上安装Excel,且性能较差,适合小规模、轻量使用。

2.3 ABAP2XLSX方式(生产环境推荐)

ABAP2XLSX是一个开源库,可直接在ABAP中生成.xlsx文件。需先导入类ZCL_EXCEL等。以下为填充内表到Excel的示例。

abap 复制代码
DATA: lo_excel TYPE REF TO zcl_excel,
      lo_worksheet TYPE REF TO zcl_excel_worksheet,
      lv_row TYPE i.

" 创建Excel对象
lo_excel = NEW zcl_excel( ).
lo_worksheet = lo_excel->get_active_worksheet( ).
lo_worksheet->set_title( '订单报表' ).

" 设置标题行
lv_row = 1.
lo_worksheet->set_cell( ip_row = lv_row ip_column = 1 ip_value = '订单号' ).
lo_worksheet->set_cell( ip_row = lv_row ip_column = 2 ip_value = '金额' ).

" 填充数据
LOOP AT lt_ekko INTO ls_ekko.
  lv_row = lv_row + 1.
  lo_worksheet->set_cell( ip_row = lv_row ip_column = 1 ip_value = ls_ekko-ebeln ).
  lo_worksheet->set_cell( ip_row = lv_row ip_column = 2 ip_value = ls_ekko-netwr ).
ENDLOOP.

" 生成文件并下载
DATA: lv_xlsx TYPE xstring,
      lv_filename TYPE string.
lv_xlsx = lo_excel->get_file( ).
lv_filename = 'order_export.xlsx'.
cl_gui_frontend_services=>gui_download(
  EXPORTING
    bin_filesize = xstrlen( lv_xlsx )
    filename     = lv_filename
    filetype     = 'BIN'
  CHANGING
    data_tab     = lt_xls_content ).   " 需将xstring转换为内表

实际使用时,需将xstring切分成256字节块放入内表,调用gui_download。可参考标准函数SCMS_XSTRING_TO_BINARY


三、PDF文件生成(从ALV输出或自定义布局)

3.1 场景分析

PDF通常用于打印或发送审批。可以通过两种方式生成:

  • 使用标准函数REUSE_ALV_GRID_DISPLAY的打印功能,用户可以点击打印然后选择"Adobe PDF"打印机,生成PDF。
  • 程序化生成PDF :调用SAP_CONVERT_TO_PDF_FORMATTED或使用Smart Forms/PDF表单。

3.2 将ALV内表数据转为PDF(使用函数SAP_CONVERT_TO_PDF_FORMATTED

该函数可以将一个内部的HTML或ABAP列表输出转换为PDF。最简单的做法是先将数据输出到列表(WRITE),然后捕捉列表内容转为PDF。

abap 复制代码
DATA: lt_list TYPE TABLE OF abaplist,
      lv_pdf TYPE xstring,
      lv_len TYPE i.

" 将ALV内表数据输出到列表(需要调用REUSE_ALV_GRID_DISPLAY的变体?)
" 更简单:用DISPLAY报表的LIST输出,再转换。下面示例为直接写列表。

NEW-PAGE PRINT OFF.   " 不弹出打印对话框
LOOP AT lt_ekko INTO ls_ekko.
  WRITE: / ls_ekko-ebeln, ls_ekko-netwr.
ENDLOOP.
" 获取列表内容
SUBMIT REPORT... EXPORTING LIST TO MEMORY... 复杂,建议使用函数模块。

" 推荐方法:使用函数模块 CONVERT_ABAPSPOOLJOB_TO_PDF
DATA: lv_spoolid TYPE tsp01-rqident.
CALL FUNCTION 'CONVERT_ABAPSPOOLJOB_TO_PDF'
  EXPORTING
    src_spoolid = lv_spoolid
  IMPORTING
    pdf_byte    = lv_pdf.

但这种方法需要先产生Spool,较麻烦。

3.3 简单方式:调用标准函数SAP_CONVERT_TO_XLSX的PDF变体?实际上无直接内表转PDF。

更常用的生产做法:使用Smart Form或Adobe Form设计好模板,将数据传入并生成PDF。以下以Smart Form为例:

abap 复制代码
DATA: lv_fm_name TYPE rs38l_fnam,
      lv_pdf TYPE xstring.

" 获取Smart Form函数名
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
  EXPORTING
    formname = 'ZSMART_PURCHASE_ORDER'
  IMPORTING
    fm_name  = lv_fm_name.

" 调用Smart Form生成PDF
CALL FUNCTION lv_fm_name
  EXPORTING
    control_parameters = VALUE ssfctrlop( no_dialog = 'X'
                                          preview   = '' )   " 不预览,直接输出
    ...                " 业务数据参数
  IMPORTING
    document_data      = DATA(ls_doc_data)
  EXCEPTIONS
    ...

" 从智能表单获取PDF
DATA lt_pdf TYPE TABLE OF tline.
CALL FUNCTION 'SSF_GET_PDF'
  EXPORTING
    control_parameters = VALUE ssfctrlop( no_dialog = 'X' )
    document_data      = ls_doc_data
  IMPORTING
    pdf_bytes          = lv_pdf.

然后通过cl_gui_frontend_services=>gui_downloadlv_pdf保存为.pdf文件。


四、完整示例:ALV报表附加"导出PDF"按钮

在ALV工具栏上增加自定义按钮"导出PDF",点击后生成PDF并下载。

4.1 注册工具栏按钮

使用REUSE_ALV_GRID_DISPLAY的回调函数I_CALLBACK_PF_STATUS_SET设置自定义按钮。

abap 复制代码
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
    i_callback_pf_status_set = 'FRM_SET_PF_STATUS'   " 设置工具栏
    ...

FRM_SET_PF_STATUS中增加按钮:

abap 复制代码
FORM frm_set_pf_status USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'STANDARD' EXCLUDING rt_extab.
  " 增加按钮 'EXPORT_PDF'
  DATA: lt_fcode TYPE TABLE OF sy-ucomm,
        ls_fcode LIKE LINE OF lt_fcode.
  ls_fcode = 'EXPORT_PDF'.
  APPEND ls_fcode TO lt_fcode.
  SET PF-STATUS 'STANDARD' EXCLUDING lt_fcode.   " 实际上是包含,需用另外方式
  " 正确:SE41中维护状态,或动态添加较复杂。简单起见,使用预定义状态。
ENDFORM.

更简单:在标准状态中已经包含"打印"按钮,用户可通过"打印→PDF打印机"生成PDF。无需自定义。

4.2 通过用户命令触发PDF生成

注册回调I_CALLBACK_USER_COMMAND

abap 复制代码
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
  EXPORTING
    i_callback_user_command = 'FRM_USER_COMMAND'
    ...

FRM_USER_COMMAND中判断:

abap 复制代码
FORM frm_user_command USING r_ucomm LIKE sy-ucomm
                            rs_selfield TYPE slis_selfield.
  IF r_ucomm = 'EXPORT_PDF'.
    PERFORM f_export_to_pdf.
  ENDIF.
ENDFORM.

4.3 生成PDF并下载

abap 复制代码
FORM f_export_to_pdf.
  DATA: lv_pdf TYPE xstring,
        lt_pdf_table TYPE TABLE OF tline.

  " 方法:调用SAP标准函数将内表转为PDF(借助打印)
  DATA: lv_lists TYPE TABLE OF abaplist.
  " 首先将内表内容输出到列表(隐藏)
  SUBMIT z_my_report ...  " 不能递归调用自身。因此需专门写一个函数生成列表。
  " 或者使用函数模块 'DISPLAY_REPORT' 获取列表。
  " 较复杂,此处省略具体实现。
  " 推荐:使用Smart Form或Adobe Form重新生成PDF。

  " 简单演示:通过调用打印功能(需要用户交互)不是纯后台。
ENDFORM.

鉴于生成PDF代码较长,项目中建议使用Smart FormAdobe Form,将ALV数据传入,生成PDF并提供下载按钮。


五、总结与最佳实践

导出方式 适用场景 实现难度 推荐度
标准ALV导出 简单数据导出,无需复杂样式 极低(免费功能) ⭐⭐⭐⭐⭐
ABAP2XLSX 模板填充、多Sheet、样式丰富 中等(需导入库) ⭐⭐⭐⭐⭐
OLE 临时使用,不推荐生产 ⭐⭐
Smart Form PDF 固定格式的打印版文档 中等(设计表单) ⭐⭐⭐⭐
直接内表转PDF 无模板的简单PDF 高(需捕获列表) ⭐⭐

建议

  • 对于日常报表,标准ALV导出Excel已满足80%需求。
  • 若需要固定对账单样式,使用ABAP2XLSX (Excel)或Smart Form(PDF)。
  • 尽量避免在生产系统中使用OLE,因为性能差且不稳定。

下一篇将介绍报表权限管控与性能测试,确保报表在生产环境安全、稳定运行。

📌 下篇预告:《SAP 报表权限管控与性能测试:上线前收尾工作全指南》

作者 :你的SAP学习伙伴

版本记录:2026年6月

💬 你更习惯用哪种方式导出Excel?遇到过导出乱码或格式错乱的问题吗?欢迎留言交流。

相关推荐
凯尔萨厮1 小时前
Hibernate(学习笔记)
笔记·学习·hibernate
lunzi_08261 小时前
【学习笔记】《Python编程 从入门到实践》第5章:if语句、条件测试与列表处理实战
笔记·python·学习
仙俊红1 小时前
rocketmq学习
大数据·学习·rocketmq
unicrom_深圳市由你创科技1 小时前
一套仓库管理多站点:性能优化与搜索友好全链路指南
性能优化
子一!!1 小时前
spring基础学习
java·学习·spring
tedcloud1231 小时前
codegraph部署教程:构建代码库语义分析环境
服务器·人工智能·word·excel
呼Lu噜2 小时前
生命周期模型概述(软考教材版)
学习·软件工程
吾爱神器2 小时前
多个EXCEL工作表格合并数据列比对工具
excel·数据合并·数据对比·数据比对·excel数据合并·excel数据对比
吃好睡好便好3 小时前
矩阵旋转的计算
学习·线性代数·算法·矩阵