ABAP2XLSX实战:从零构建专业Excel报表的完整指南
2026/8/5 8:45:19 网站建设 项目流程

1. 从零开始:为什么要在ABAP里操作Excel?

如果你是一个SAP ABAP开发者,大概率遇到过这样的需求:业务部门需要一份报表,格式复杂,有合并单元格、颜色高亮、公式计算,甚至还要能直接打印。SAP ALV虽然强大,但面对这种“花里胡哨”的格式要求,常常力不从心。传统的做法是什么?用OLE(Object Linking and Embedding)接口,在服务器上调用本地的Microsoft Excel应用程序来生成文件。这个方法我用了好几年,坑也踩了不少:服务器上必须安装Excel,权限配置复杂,进程容易挂起导致内存泄漏,在后台作业(Background Job)中运行更是噩梦。后来,我接触到了ABAP2XLSX,感觉像是打开了一扇新世界的大门。

简单说,ABAP2XLSX是一个开源的ABAP类库,它让你能像在Excel里“编程”一样,用纯ABAP代码生成标准的.xlsx文件。它不依赖任何外部Office组件,直接在应用服务器内存中构建Excel的底层结构(基于Open XML标准),然后打包成一个ZIP格式的.xlsx文件。这意味着,你可以在任何SAP系统(ECC, S/4HANA)上,在任何作业模式(前台、后台)下,稳定、高效地创建复杂的Excel文档。今天,我就结合自己多个项目的实战经验,带你从环境搭建到高级功能,彻底掌握这个利器。

2. 环境准备与核心对象初识

在开始写代码之前,我们得先把“工具”准备好。ABAP2XLSX不是一个SAP标准交付的组件,你需要手动将其导入到你的开发系统。

2.1 获取与导入ABAP2XLSX

最官方的来源是GitHub上的abap2xlsx仓库。通常,你需要下载一个包含所有开发对象的传输请求文件(.sapkg.tpz格式),然后通过事务代码STMSSCC1将其导入你的开发系统。当然,如果你们公司有内部的Git或类似代码管理工具,可能已经集成了。导入成功后,你会在包结构里看到一系列以ZCL_EXCEL_ZCL_XL_开头的类,以及一些相关的类型池和数据字典对象。

这里有个关键点:务必检查导入的版本。ABAP2XLSX仍在活跃开发中,新版本会修复Bug并增加新功能(比如对S/4HANA新语法的更好支持)。你可以查看类ZCL_EXCEL的属性,或者仓库的Release Notes来确认版本。我遇到过因为版本过旧,某些样式属性不生效的问题,排查起来很费时间。

2.2 理解核心类:ZCL_EXCEL

一切的核心是ZCL_EXCEL类。你可以把它想象成整个Excel工作簿在ABAP内存中的“总管”或“容器”。

DATA: lo_excel TYPE REF TO zcl_excel. CREATE OBJECT lo_excel.

创建一个lo_excel对象,就相当于在内存中新建了一个空白的Excel文件。这个对象内部会管理多个工作表(Worksheet)、单元格样式(Style)、字体、边框等一系列资源。

2.3 理解工作表与单元格

有了工作簿,接下来要操作具体的工作表。通过lo_excel对象,你可以获取、添加或激活工作表。

DATA: lo_worksheet TYPE REF TO zcl_excel_worksheet. " 获取默认的第一个工作表(Sheet1) lo_worksheet = lo_excel->get_active_worksheet( ). " 或者创建一个新的工作表并命名 lo_excel->add_new_worksheet( EXPORTING ip_name = '销售数据' ). lo_worksheet = lo_excel->get_worksheet_by_name( ip_name = '销售数据' ).

工作表对象lo_worksheet是你操作的主战场。向单元格写入数据是其最基本的功能:

" 向A1单元格写入文本 lo_worksheet->set_cell( ip_column = 'A' ip_row = 1 ip_value = '客户编号' ). " 向B2单元格写入数字 lo_worksheet->set_cell( ip_column = 'B' ip_row = 2 ip_value = 1000 ). " 向C3单元格写入公式(注意公式以=开头) lo_worksheet->set_cell( ip_column = 'C' ip_row = 3 ip_value = '=SUM(B2:B10)' ).

这里有一个非常重要的细节:ip_value参数是STRING类型,但ABAP2XLSX内部会根据你传入的内容(纯数字、带等号的公式、日期格式的字符串)自动判断单元格的数据类型。如果你想显式控制,可以使用set_cell_formula,set_cell_numeric等方法。

3. 构建一份基础报表:完整流程拆解

理论讲得再多,不如动手做一份报表。假设我们要生成一份简单的销售订单清单,包含订单号、客户名、金额和日期。

3.1 数据准备与结构定义

首先,我们从数据库(比如VBAKVBAP)中获取数据。为了清晰,我们定义一个内表来存放要输出的数据。

TYPES: BEGIN OF ty_sales_data, vbeln TYPE vbeln_va, " 销售订单 kunnr TYPE kunnr, " 客户 name1 TYPE name1, " 客户名称 netwr TYPE netwr_ap, " 净价值 audat TYPE audat, " 创建日期 END OF ty_sales_data. DATA: lt_sales_data TYPE TABLE OF ty_sales_data. " 这里省略数据查询的SELECT语句...

3.2 创建Excel对象并写入表头

初始化Excel对象,并写入固定的表头行。

DATA: lo_excel TYPE REF TO zcl_excel, lo_worksheet TYPE REF TO zcl_excel_worksheet, lv_row TYPE int4. CREATE OBJECT lo_excel. lo_worksheet = lo_excel->get_active_worksheet( ). lo_worksheet->set_title( ip_title = '销售订单清单' ). lv_row = 1. " 从第1行开始 lo_worksheet->set_cell( ip_column = 'A' ip_row = lv_row ip_value = '销售订单号' ). lo_worksheet->set_cell( ip_column = 'B' ip_row = lv_row ip_value = '客户编号' ). lo_worksheet->set_cell( ip_column = 'C' ip_row = lv_row ip_value = '客户名称' ). lo_worksheet->set_cell( ip_column = 'D' ip_row = lv_row ip_value = '订单金额' ). lo_worksheet->set_cell( ip_column = 'E' ip_row = lv_row ip_value = '创建日期' ).

3.3 循环写入数据行并应用简单样式

接下来,我们循环内表,将数据逐行写入。同时,为了让表头更醒目,我们给表头加个粗体并填充背景色。

" 首先,为表头创建一个样式 DATA: lo_style_header TYPE REF TO zcl_excel_style. lo_style_header = lo_excel->add_new_style( ). " 设置字体加粗 lo_style_header->font->bold = abap_true. " 设置填充色为浅灰色(使用RGB颜色) lo_style_header->fill->filltype = zcl_excel_style_fill=>c_fill_solid. lo_style_header->fill->fgcolor-rgb = zcl_excel_style_color=>c_gray. " 将样式应用到表头行(第1行)的A到E列 lo_worksheet->set_style( ip_column_start = 'A' ip_column_end = 'E' ip_row = lv_row ip_style = lo_style_header ). " 写入数据 lv_row = lv_row + 1. " 移动到第2行开始写数据 LOOP AT lt_sales_data INTO DATA(ls_sales). lo_worksheet->set_cell( ip_column = 'A' ip_row = lv_row ip_value = ls_sales-vbeln ). lo_worksheet->set_cell( ip_column = 'B' ip_row = lv_row ip_value = ls_sales-kunnr ). lo_worksheet->set_cell( ip_column = 'C' ip_row = lv_row ip_value = ls_sales-name1 ). " 金额字段,我们希望显示为货币格式 lo_worksheet->set_cell( ip_column = 'D' ip_row = lv_row ip_value = ls_sales-netwr ). " 日期字段,我们希望显示为YYYY-MM-DD格式 lo_worksheet->set_cell( ip_column = 'E' ip_row = lv_row ip_value = ls_sales-audat ). lv_row = lv_row + 1. ENDLOOP.

现在,数据已经写进去了,但金额和日期的格式还是默认的。我们需要为这两列单独设置单元格样式。

3.4 设置数字与日期格式

这是让报表变得专业的关键一步。我们需要创建新的样式,并应用到对应的列上。

DATA: lo_style_currency TYPE REF TO zcl_excel_style, lo_style_date TYPE REF TO zcl_excel_style. " 创建货币格式样式 lo_style_currency = lo_excel->add_new_style( ). " #,##0.00 是Excel的数字格式代码,表示千位分隔符和两位小数 lo_style_currency->number_format->format_code = zcl_excel_style_number_format=>c_format_currency_eur. " 或者直接用 '#,##0.00' " 创建日期格式样式 lo_style_date = lo_excel->add_new_style( ). lo_style_date->number_format->format_code = zcl_excel_style_number_format=>c_format_date_yyyyymmdd. " 或 'YYYY-MM-DD' " 将样式应用到整列(从第2行到最后一行) DATA(lv_last_row) = lv_row - 1. " 因为循环结束后lv_row指向了空行,所以最后一行是lv_row-1 IF lv_last_row > 1. " 应用货币格式到D列 lo_worksheet->set_column_style( ip_column = 'D' ip_from_row = 2 ip_to_row = lv_last_row ip_style = lo_style_currency ). " 应用日期格式到E列 lo_worksheet->set_column_style( ip_column = 'E' ip_from_row = 2 ip_to_row = lv_last_row ip_style = lo_style_date ). ENDIF.

注意set_column_style这个方法在ABAP2XLSX中可能不是标准方法。更常见的做法是在循环写入每个单元格时,直接为那个单元格设置样式。或者,可以先创建一个具有特定格式的样式对象,然后在set_cell方法中通过ip_style参数传入。上面使用set_column_style是为了概念清晰。实际编码中,更推荐在循环内为特定单元格设置样式:

lo_worksheet->set_cell( ip_column = 'D' ip_row = lv_row ip_value = ls_sales-netwr ip_style = lo_style_currency ).

3.5 调整列宽与最终生成文件

数据写好了,格式也设定了,但默认的列宽可能不合适。我们可以让ABAP2XLSX根据内容自动调整,或者手动设置。

" 方法一:自动调整列宽(这是一个比较消耗性能的操作,数据量大时慎用) lo_worksheet->set_auto_filter( ip_range = 'A1:E1' ). " 先设置筛选器,有时能触发更好的自动调整 " ABAP2XLSX的自动调整列宽功能可能不完善,实测效果因版本和内容而异。 " 方法二:手动设置列宽(推荐,更可控) lo_worksheet->set_column_width( ip_column = 'A' ip_width = 15 ). " 订单号列 lo_worksheet->set_column_width( ip_column = 'B' ip_width = 12 ). " 客户号列 lo_worksheet->set_column_width( ip_column = 'C' ip_width = 25 ). " 客户名列 lo_worksheet->set_column_width( ip_column = 'D' ip_width = 15 ). " 金额列 lo_worksheet->set_column_width( ip_column = 'E' ip_width = 12 ). " 日期列

最后,也是最关键的一步,将内存中的Excel对象写入一个真正的.xlsx文件,并供用户下载。

DATA: lv_xlsx_data TYPE xstring. " 1. 将工作簿对象转换为二进制数据(XSTRING) lv_xlsx_data = lo_excel->get_raw_data( ). " 2. 调用函数将XSTRING保存为应用服务器文件,或通过GUI_DOWNLOAD下载 DATA: lv_bytecount TYPE i, lt_raw TYPE solix_tab. " 将XSTRING转换为SOLIX格式(用于下载) lv_bytecount = xstrlen( lv_xlsx_data ). lt_raw = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_xlsx_data ). " 3. 使用GUI_DOWNLOAD弹出下载对话框 DATA: lv_filename TYPE string. lv_filename = '销售订单清单_' && sy-datum && '_' && sy-uzeit && '.xlsx'. CALL FUNCTION 'GUI_DOWNLOAD' EXPORTING filename = lv_filename filetype = 'BIN' TABLES data_tab = lt_raw EXCEPTIONS others = 1. IF sy-subrc <> 0. MESSAGE '文件下载失败' TYPE 'E'. ENDIF.

至此,一份格式规范、带样式的基础销售报表就生成并下载到用户本地了。这个流程是使用ABAP2XLSX的基石,绝大多数需求都是在这个框架上增加“装饰”。

4. 进阶技巧:让报表更专业、更强大

掌握了基础操作,我们来看看如何解决更复杂的业务场景,这些技巧能极大提升报表的可用性和专业性。

4.1 合并单元格与复杂表头

对于多层级的表头,合并单元格是必须的。例如,在“金额”下面再分“本币金额”和“外币金额”。

" 假设第1行是主标题,第2行是子标题 lo_worksheet->set_cell( ip_column = 'D' ip_row = 1 ip_value = '金额信息' ). " 合并D1到E1单元格 lo_worksheet->merge( ip_column_start = 'D' ip_column_end = 'E' ip_row = 1 ip_row_to = 1 ). " 写入子标题 lo_worksheet->set_cell( ip_column = 'D' ip_row = 2 ip_value = '本币金额' ). lo_worksheet->set_cell( ip_column = 'E' ip_row = 2 ip_value = '外币金额' ). " 记得为合并后的主标题单元格设置居中对齐样式 DATA(lo_style_center) = lo_excel->add_new_style( ). lo_style_center->alignment->horizontal = zcl_excel_style_alignment=>c_horizontal_center. lo_worksheet->set_cell( ip_column = 'D' ip_row = 1 ip_value = '金额信息' ip_style = lo_style_center ).

4.2 条件格式与数据条

条件格式能让数据可视化。比如,将金额超过10000的单元格标红。

DATA: lo_conditional_style TYPE REF TO zcl_excel_conditional_formatting, lo_rule TYPE REF TO zcl_excel_conditional_formatting_rule. " 创建一个条件格式对象,作用于D列(金额列)的数据区域 lo_conditional_style = lo_worksheet->add_new_conditional_formatting( ip_range = 'D2:D100' ). " 假设数据在2到100行 " 创建一条规则:单元格值大于10000 CREATE OBJECT lo_rule. lo_rule->type = zcl_excel_conditional_formatting_rule=>c_rule_cellis. lo_rule->operator = zcl_excel_conditional_formatting_rule=>c_operator_greaterthan. lo_rule->formula1 = '10000'. " 为这条规则创建样式(红色填充) DATA(lo_style_highlight) = lo_excel->add_new_style( ). lo_style_highlight->fill->filltype = zcl_excel_style_fill=>c_fill_solid. lo_style_highlight->fill->fgcolor-rgb = zcl_excel_style_color=>c_red. lo_rule->style = lo_style_highlight. " 将规则添加到条件格式中 lo_conditional_style->add_rule( lo_rule ).

数据条(Data Bars)是另一种强大的条件格式,可以生成类似条形图的效果,直观显示数值大小。其创建逻辑与颜色规则类似,但类型需设置为c_rule_databar

4.3 插入图表

在ABAP2XLSX中插入图表相对复杂,但原理是清晰的:你需要定义图表数据源(哪个单元格区域)、图表类型(柱状图、折线图等)以及图表的位置。

DATA: lo_drawing TYPE REF TO zcl_excel_drawing, lo_chart TYPE REF TO zcl_excel_chart. " 1. 创建一个绘图对象,用于承载图表 CREATE OBJECT lo_drawing EXPORTING ip_type = zcl_excel_drawing=>c_drawing_chart. " 2. 设置图表位置(从哪个单元格开始) lo_drawing->position = zcl_excel_drawing=>c_drawing_position_from_cell. lo_drawing->from_row = 10. " 图表左上角位于第10行 lo_drawing->from_col = zcl_excel_common=>convert_column2int( 'G' ). " 第G列 " 3. 创建具体的图表对象(例如柱状图) CREATE OBJECT lo_chart EXPORTING ip_type = zcl_excel_chart=>c_chart_type_column. " 4. 设置图表数据源 " 假设我们要为A列(分类)和D列(数值)创建图表,数据在2-9行 lo_chart->set_source_data( ip_range = `'销售订单清单'!$A$2:$A$9,'销售订单清单'!$D$2:$D$9` ). " 5. 将图表添加到绘图对象,再将绘图对象添加到工作表 lo_drawing->set_chart( lo_chart ). lo_worksheet->add_drawing( lo_drawing ).

图表功能是ABAP2XLSX中比较高级的部分,不同版本间API可能有差异,建议在实际使用时详细查阅对应版本的类方法文档。

4.4 处理大量数据与性能优化

当需要导出成千上万行数据时,性能就成为关键。OLE方式在此场景下几乎不可用,而ABAP2XLSX虽然高效,但也需注意优化。

核心经验一:批量操作,减少交互。避免在循环内频繁调用add_new_style来创建大量相同样式。应该在循环前创建好需要的样式对象,在循环内直接引用。

核心经验二:慎用自动调整列宽set_auto_column_width这类方法需要计算所有单元格内容的长度,数据量巨大时非常耗时。最好根据业务知识手动设置一个合理的固定列宽。

核心经验三:分页与内存管理。对于极端大量的数据(例如数十万行),可以考虑分多个工作表(Sheet)存放,或者分多个Excel文件生成。虽然ABAP2XLSX本身在内存中处理,但单个工作表单元格数量过多,在最终渲染和客户端打开时也可能遇到性能瓶颈或Excel软件限制。

在我的一个项目中,需要导出约50万行数据。我采用了分批处理的方式:每处理1万行,就调用一次lo_excel->get_raw_data( )并暂存到内表,然后清空当前工作表对象,继续处理下一批。最后将所有批次的二进制数据拼接(这需要深入理解ZIP格式,比较复杂),或者直接生成多个文件让用户打包下载。这是一个权衡方案。

5. 实战避坑指南与疑难排查

用了这么久ABAP2XLSX,我也踩过不少坑。这里总结几个最常见的问题和解决方法。

5.1 日期显示为数字而非日期格式

这是新手最容易遇到的问题。你写入了一个日期字段20240520,但在Excel里打开却显示为45405这样的数字。

原因:Excel内部将日期存储为“序列号”(从1900年1月1日开始的天数)。当你传入20240520这样的数字或字符串时,ABAP2XLSX默认将其视为普通数字。

解决:必须为日期单元格显式设置日期格式,并确保传入的值是Excel能识别的日期序列号或格式化的日期字符串。最可靠的方法是使用SAP的日期字段,并利用ABAP2XLSX的转换功能。

DATA: lv_excel_date TYPE zexcel_cell_value. " 或 string " 方法1:使用内置转换(如果类支持) " 先将SAP日期(YYYYMMDD)转换为Excel序列号 CALL METHOD lo_excel->convert_date_to_excel EXPORTING ip_date = ls_sales-audat IMPORTING ep_excel_date = lv_excel_date. lo_worksheet->set_cell( ip_column = 'E' ip_row = lv_row ip_value = lv_excel_date ip_style = lo_style_date ). " 方法2:传入格式化的字符串(更通用) DATA(lv_date_string) = |{ ls_sales-audat+0(4) }-{ ls_sales-audat+4(2) }-{ ls_sales-audat+6(2) }|. lo_worksheet->set_cell( ip_column = 'E' ip_row = lv_row ip_value = lv_date_string ip_style = lo_style_date ).

5.2 中文或其他非ASCII字符乱码

生成的Excel文件打开后,中文字符变成了问号或方块。

原因:字符编码问题。ABAP系统内部是UTF-16,而Excel文件期望的是正确的UTF-8或系统本地编码。

解决:确保在创建Excel对象时,或最终输出时,指定正确的编码。通常,ABAP2XLSX类内部会处理编码转换。如果仍出现乱码,检查以下两点:

  1. 你传入的字符串变量本身在ABAP中是否正确存储了中文(例如,从数据库读取时是否正常)。
  2. 在调用GUI_DOWNLOAD下载时,尝试指定codepage = '4110'(代表UTF-16LE)或'4103'(代表UTF-8),但这对二进制下载模式可能无效。最根本的解决方案是确保lo_excel对象在生成XSTRING时使用了正确的编码,这通常需要检查ABAP2XLSX的版本和配置。

5.3 样式不生效或部分生效

你创建了一个样式并应用到了单元格,但打开Excel后发现只有部分属性(比如字体)生效了,填充色或边框却没有。

排查步骤

  1. 检查样式创建顺序:在ABAP2XLSX中,样式对象需要先被添加到工作簿(lo_excel->add_new_style),然后才能被工作表引用。直接创建一个zcl_excel_style对象而不添加到工作簿,是无效的。
  2. 检查样式属性赋值时机:确保在将样式对象通过set_styleset_cell( ... ip_style = ... )应用到单元格之前,已经完成了所有样式属性(如fill->fgcolor,borders->allborders)的赋值。事后修改样式对象,可能不会同步更新到已应用的单元格。
  3. 检查颜色常量zcl_excel_style_color=>c_red这类常量是预定义的颜色索引。确保你使用的常量是有效的。对于自定义RGB颜色,格式必须是6位十六进制字符串(如'FFFF0000'表示蓝色,注意ABAP2XLSX可能是AARRGGBB格式)。
  4. 版本兼容性:某些较新的样式属性可能在旧的ABAP2XLSX版本中不支持。查看你所用版本的类方法文档或示例代码。

5.4 生成的文件无法在旧版Excel(如2003)中打开

ABAP2XLSX生成的是.xlsx格式,这是基于Open XML的标准,需要Excel 2007及以上版本才能直接打开。如果用户必须使用Excel 2003(.xls格式),则ABAP2XLSX本身无法直接生成。你需要考虑:

  1. 说服用户升级Office。
  2. 使用其他ABAP库(如SOI,但同样问题多)来生成.xls
  3. 在服务器端通过其他工具进行格式转换(不推荐,复杂且不稳定)。

5.5 在后台作业中运行

这是ABAP2XLSX相比OLE最大的优势之一——它可以在后台作业中完美运行。但需要注意:

  • 文件输出路径:在后台作业中,无法通过GUI_DOWNLOAD直接下载到用户前端。你需要将get_raw_data()得到的XSTRING数据,通过OPEN DATASET写入应用服务器的一个临时文件,或者通过SO_NEW_DOCUMENT_ATT_SEND_API1等函数将文件作为邮件附件发送给用户。
  • 资源清理:虽然ABAP2XLSX没有OLE那样的进程残留问题,但在长时间运行的后台作业中,如果循环创建大量Excel对象,也要注意及时清空引用(CLEAR: lo_excel, lo_worksheet),帮助垃圾回收。

6. 超越基础:探索ABAP2XLSX的生态与最佳实践

当你熟练使用核心功能后,可以关注以下方面来提升你的开发效率和代码质量。

6.1 利用封装函数与工具类

很多公司和项目组会基于ABAP2XLSX封装自己的工具类或函数模块。例如,一个Z_EXCEL_OUTPUT类,里面提供了add_header,add_data_table,apply_style_template等方法,将常见的报表生成模式固化下来。积极寻找或参与构建这样的共享工具库,能极大减少重复劳动,保证团队输出Excel格式的一致性。

6.2 模板化生成

对于格式固定、仅数据变化的复杂报表,更高级的做法是“模板化”。即:

  1. 先用Excel手工制作一个完美的模板文件(.xlsx),包含所有格式、公式、图表。
  2. 使用ABAP2XLSX的“读取”功能(ZCL_EXCEL_READER_2007)将这个模板文件读入。
  3. 在代码中定位到模板中的特定单元格或命名区域,用你的业务数据去填充。
  4. 保存为新的Excel文件。

这种方式将“格式设计”和“数据填充”完全分离,业务顾问可以自行调整模板格式,无需开发人员修改代码。ABAP2XLSX同样提供了读取现有Excel文件的能力,值得深入研究。

6.3 与ALV集成

一种常见的模式是:用户先在ALV报表界面筛选、查看数据,然后点击一个按钮,将当前ALV显示的数据(包括排序、筛选后的状态)导出为Excel。这可以通过获取ALV的内表数据lt_outtab,然后传递给ABAP2XLSX处理函数来实现。你甚至可以尝试读取屏幕字段的文本作为Excel的表头,使得导出结果与ALV显示高度一致。

6.4 测试与调试

调试ABAP2XLSX代码,最直观的方式就是查看生成的Excel文件。我习惯在开发时,先将文件保存到前端或应用服务器,然后立刻打开检查。对于复杂的样式或合并单元格问题,有时需要反复调整参数、生成、查看。可以编写一些简单的测试程序,快速验证某个样式属性或方法的效果。

另外,关注ABAP2XLSX的官方GitHub仓库的Issue和更新。社区用户遇到的问题和解决方案,很可能也是你未来会遇到的。参与社区讨论,也是提升技能的好途径。

从被OLE的各种问题折磨,到熟练运用ABAP2XLSX应对各种报表需求,这个工具确实改变了ABAP开发者在处理Excel输出时的体验。它稳定、高效、功能强大,虽然学习曲线初期有点陡峭,但一旦掌握,你就会发现它能实现的报表效果,远超业务部门的想象。关键是,它让这一切都运行在可控的SAP环境内,不再依赖不可靠的外部组件。下次当你接到一个复杂的Excel报表需求时,不妨直接打开SE24,输入ZCL_EXCEL,开始你的创作。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询