用于读取Excel文件并转换为内部表的程序,原理就是用gui_upload先上传数据,然后转换为二进制处理
- GUI_UPLOAD函数限制:
- 默认情况下,GUI_UPLOAD函数可以处理的最大文件大小约为2GB
- 但实际大小会受到系统内存限制影响
- 对于大文件,建议分批读取
- cl_fdt_xl_spreadsheet类限制:
- 这个类处理Excel文件时的内存消耗较大
- 建议处理文件大小不超过10MB
- 对于更大的文件,可能会出现内存溢出(MEMORY_NO_MORE_PAGING)错误
- 系统内存限制:
- 受系统可用内存限制
- 受用户会话内存限制
- 受系统参数限制(如ztta/max_memreq_MB)
接下来是完整代码,至于限制文件大小,实测,公司服务器50M的excel100万条数据都可以处理
代码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
*&---------------------------------------------------------------------* *& Report ZRED0984 *&---------------------------------------------------------------------* *& *& 功能描述:Excel文件数据读取程序 *& 将Excel文件内容读取到ABAP内表中 *&---------------------------------------------------------------------* REPORT ZRED0984. " 断点,用于调试 BREAK-POINT. "-------------------------------------------------------------------- " 数据声明部分 "-------------------------------------------------------------------- DATA: lv_filename TYPE string, " 存储文件名 lt_records TYPE solix_tab, " 存储二进制数据的内表 lv_headerxstring TYPE xstring, " 存储xstring格式的文件内容 lv_filelength TYPE i. " 存储文件长度 " 屏幕参数:文件选择 PARAMETERS p_fil TYPE rlgrap-filename. "-------------------------------------------------------------------- " 文件上传处理 "-------------------------------------------------------------------- " 将参数值赋给文件名变量 lv_filename = p_fil. " 使用GUI_UPLOAD函数读取文件 CALL FUNCTION 'GUI_UPLOAD' EXPORTING filename = lv_filename " 文件名 filetype = 'BIN' " 以二进制格式读取 IMPORTING filelength = lv_filelength " 返回文件长度 header = lv_headerxstring " 返回文件头信息 TABLES data_tab = lt_records " 返回二进制数据 EXCEPTIONS file_open_error = 1 file_read_error = 2 no_batch = 3 gui_refuse_filetransfer = 4 invalid_type = 5 no_authority = 6 unknown_error = 7 bad_data_format = 8 header_not_allowed = 9 separator_not_allowed = 10 header_too_long = 11 unknown_dp_error = 12 access_denied = 13 dp_out_of_memory = 14 disk_full = 15 dp_timeout = 16 OTHERS = 17. " 检查文件上传是否成功 IF sy-subrc <> 0. MESSAGE '文件上传失败' TYPE 'E'. ENDIF. " 检查文件大小(限制为10MB) IF lv_filelength > 10485760. MESSAGE '文件大小超过限制(10MB)' TYPE 'E'. ENDIF. "-------------------------------------------------------------------- " 数据转换处理 "-------------------------------------------------------------------- " 声明字段符号,用于动态内表 FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE. " 将二进制数据转换为xstring格式 CALL FUNCTION 'SCMS_BINARY_TO_XSTRING' EXPORTING input_length = lv_filelength " 文件长度 IMPORTING buffer = lv_headerxstring " 转换后的xstring数据 TABLES binary_tab = lt_records " 二进制数据表 EXCEPTIONS failed = 1 OTHERS = 2. " 检查转换是否成功 IF sy-subrc <> 0. MESSAGE '数据转换失败' TYPE 'E'. ENDIF. "-------------------------------------------------------------------- " Excel数据处理 "-------------------------------------------------------------------- " 声明Excel对象引用 DATA: lo_excel_ref TYPE REF TO cl_fdt_xl_spreadsheet. TRY. " 创建Excel对象实例 lo_excel_ref = NEW cl_fdt_xl_spreadsheet( document_name = lv_filename xdocument = lv_headerxstring ). CATCH cx_fdt_excel_core. MESSAGE 'Excel文件处理失败' TYPE 'E'. ENDTRY. " 获取Excel中的所有工作表名称 lo_excel_ref->if_fdt_doc_spreadsheet~get_worksheet_names( IMPORTING worksheet_names = DATA(lt_worksheets) ). " 检查是否存在工作表 IF lt_worksheets IS INITIAL. MESSAGE 'Excel文件中没有找到工作表' TYPE 'E'. ENDIF. "-------------------------------------------------------------------- " 数据提取处理 "-------------------------------------------------------------------- " 读取第一个工作表 READ TABLE lt_worksheets INTO DATA(lv_woksheetname) INDEX 1. IF sy-subrc = 0. " 从工作表获取数据到动态内表 DATA(lo_data_ref) = lo_excel_ref->if_fdt_doc_spreadsheet~get_itab_from_worksheet( lv_woksheetname ). " 将动态内表数据赋给字段符号 ASSIGN lo_data_ref->* TO <lt_data>. " 检查数据是否成功读取 IF <lt_data> IS INITIAL. MESSAGE '工作表中没有数据' TYPE 'W'. ENDIF. ENDIF. " 释放内存占用 FREE: lo_excel_ref, lt_records. " 断点,用于调试 BREAK-POINT. |


