EXCEL上传下载
整理下常用的方法。
CL_EHFND_XLSX
SAP的内置方法,通过解析XLSX中的XML文件,实现高速读取数据,首推。
示例代码
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 | TYPES:
BEGIN OF ty_data,
field1 TYPE string,
field2 TYPE string,
END OF ty_data.
DATA:
lt_data TYPE STANDARD TABLE OF ty_data,
ls_data TYPE ty_data.
" 获取上传文件路径
DATA(l_file) = cl_openxml_helper=>browse_local_file_open(
iv_title = 'Choose'
iv_filename = 'Import.xlsx'
iv_extpattern = '*.xlsx|*.xlsx' ).
TRY.
" 获取文件内容
DATA(l_buffer) = cl_openxml_helper=>load_local_file( l_file ).
" 解析文件
DATA(lo_xlsx) = cl_ehfnd_xlsx=>get_instance( ).
DATA(lo_doc) = lo_xlsx->load_doc( l_buffer ).
DATA(lt_sheet_info) = lo_doc->get_sheets( ).
DATA(lo_sheet) = lo_doc->get_sheet_by_id( lt_sheet_info[ 1 ]-sheet_id ).
CATCH cx_openxml_format
cx_openxml_not_found
cx_openxml_not_allowed.
RETURN.
ENDTRY.
" 获取上传行数
DATA l_row TYPE i.
DATA l_row_last TYPE i.
l_row_last = lo_sheet->get_last_row_number( ).
l_row = 1. " 跳过抬头行
" 逐行处理
WHILE l_row < l_row_last.
l_row = l_row + 1.
CLEAR ls_data.
ls_data-field1 = lo_sheet->get_cell_content( iv_row = l_row iv_column = 1 ).
ls_data-field2 = lo_sheet->get_cell_content( iv_row = l_row iv_column = 2 ).
INSERT ls_data INTO TABLE lt_data.
ENDWHILE.
|
多文本格式处理
有时上传会出现单元格内容丢失的情况,这可能是由于多文本格式引起。SAP标准方法,基本都不支持多文本格式,因此需要增强处理。
下面增强只针对CL_EHFND_XLSX,如果是SAP其他标准类(比如CL_FDT_XL_SPREADSHEET),需要自己另外查找增强点
类CL_EHFND_EXP_XLSX_STRING_UTIL,方法GET_STRING_AT_INDEX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | ...
* Check if index is in bounds of internal table and return it if found
IF lv_index LE lines( mt_strings ).
READ TABLE mt_strings INDEX lv_index REFERENCE INTO lr_s_string.
*{ REPLACE S4DKXXXXXX 1
*/ rv_string = lr_s_string->string.
IF lr_s_string->r IS NOT INITIAL.
" 拼接多格式文本
LOOP AT lr_s_string->r REFERENCE INTO DATA(LR_R).
CONCATENATE rv_string lr_r->string INTO rv_string.
ENDLOOP.
ELSE.
rv_string = lr_s_string->string.
ENDIF.
*} REPLACE
ENDIF.
...
|
封装简化
CL_EHFND_XLSX使用上比其他方法都显得繁琐,不妨写些工具代码来简化。
ZCL_XLSX_IO
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 | CLASS zcl_xlsx_io DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
DATA mo_xlsx TYPE REF TO cl_ehfnd_xlsx .
DATA mo_doc TYPE REF TO if_ehfnd_xlsx_doc .
DATA mo_sheet TYPE REF TO if_ehfnd_xlsx_sheet .
CLASS-METHODS download_smw0_templete
IMPORTING
!i_objid TYPE w3objid
!i_name TYPE string OPTIONAL .
CLASS-METHODS get_smw0_templete
IMPORTING
!i_objid TYPE w3objid
RETURNING
VALUE(r_buffer) TYPE xstring .
CLASS-METHODS replace_sharedstrings
IMPORTING
!it_replace TYPE ANY TABLE
CHANGING
!c_doc TYPE xstring.
CLASS-METHODS get_local_file
IMPORTING
!i_filename TYPE string OPTIONAL
RETURNING
VALUE(r_buffer) TYPE xstring .
CLASS-METHODS import
IMPORTING
!i_filename TYPE string OPTIONAL
!i_skip_row TYPE i DEFAULT 1
CHANGING
!ct_data TYPE ANY TABLE .
CLASS-METHODS export
IMPORTING
!i_filename TYPE string OPTIONAL
!it_data TYPE ANY TABLE .
CLASS-METHODS get_instance
IMPORTING
!i_buffer TYPE xstring OPTIONAL
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_xlsx_io .
CLASS-METHODS get_reader
IMPORTING
!i_filename TYPE string OPTIONAL
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_xlsx_io .
CLASS-METHODS get_writer
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_xlsx_io .
CLASS-METHODS conv
IMPORTING
!dataflow TYPE string
!convexit TYPE string OPTIONAL
!input TYPE data
EXPORTING
!output TYPE data .
METHODS start
IMPORTING
!i_row TYPE i OPTIONAL
!i_column TYPE i OPTIONAL .
METHODS stop .
METHODS row_id
RETURNING
VALUE(r_row) TYPE i .
METHODS column_id
RETURNING
VALUE(r_column) TYPE i .
METHODS has_next_row
RETURNING
VALUE(r_flag) TYPE abap_bool .
METHODS has_next_column
RETURNING
VALUE(r_flag) TYPE abap_bool .
METHODS next_row
IMPORTING
!i_row TYPE i DEFAULT 1 .
METHODS next_column
IMPORTING
!i_column TYPE i DEFAULT 1 .
METHODS read_column
IMPORTING
!i_column TYPE i
EXPORTING
!e_value TYPE data
RETURNING
VALUE(r_value) TYPE string .
METHODS read_next_column
EXPORTING
!e_value TYPE data
RETURNING
VALUE(r_value) TYPE string .
METHODS write_column
IMPORTING
!i_value TYPE data
!i_conv TYPE xfeld DEFAULT abap_false
!i_column TYPE i .
METHODS write_next_column
IMPORTING
!i_value TYPE data
!i_conv TYPE xfeld DEFAULT abap_false .
METHODS save
IMPORTING
!i_filename TYPE string OPTIONAL .
PROTECTED SECTION.
PRIVATE SECTION.
DATA m_row TYPE i.
DATA m_column TYPE i.
DATA m_row_last TYPE i.
DATA m_column_last TYPE i.
ENDCLASS.
CLASS zcl_xlsx_io IMPLEMENTATION.
METHOD column_id.
r_column = m_column.
ENDMETHOD.
METHOD conv.
DATA l_subrc TYPE subrc VALUE 4.
DATA l_value TYPE string.
DATA l_convexit TYPE string.
DATA l_fm_convexit TYPE rs38l_fnam. " 转换例程函数
DESCRIBE FIELD output TYPE DATA(l_type) EDIT MASK DATA(l_mask).
" EDIT MASK取出来的值如:==ALPHA、==MATN1
CLEAR l_convexit.
IF convexit IS SUPPLIED.
l_convexit = convexit.
ELSEIF strlen( l_mask ) > 2.
l_convexit = l_mask+2.
ELSEIF l_type = 'N'. " 如果是NUMC类型,默认ALPHA转换
l_convexit = 'ALPHA'.
ENDIF.
CASE l_type.
WHEN 'D' OR 'T'. " 日期时间格式
l_value = input.
REPLACE ALL OCCURRENCES OF REGEX '[^0-9]' IN l_value WITH ''.
output = l_value.
WHEN OTHERS.
" 检查字段是否有输出转换
IF l_convexit IS INITIAL.
output = input.
ELSE.
TRY.
" EDIT MASK不支持STRING,还是要用CONVEXIT的方法
l_fm_convexit = |CONVERSION_EXIT_{ l_convexit }_{ dataflow }|.
CALL FUNCTION l_fm_convexit
EXPORTING
input = input
IMPORTING
output = output
EXCEPTIONS
OTHERS = 99.
IF sy-subrc <> 0.
output = input. " 转换错误,直接输入
ENDIF.
CATCH cx_root.
output = input.
ENDTRY.
ENDIF.
ENDCASE.
" CONDENSE必须是Character-Like
IF l_type = 'C' OR l_type = 'N' OR l_type = 'g'.
CONDENSE output. " 去除多余空格
ENDIF.
ENDMETHOD.
METHOD download_smw0_templete.
DATA: ls_wwwdatatab TYPE wwwdatatab,
l_rc TYPE sy-subrc,
l_defaultfilename TYPE string,
ls_wwwdata_tab TYPE wwwdatatab,
l_object_name TYPE w3objid,
l_filename TYPE string,
l_default_file_name TYPE string,
l_fullpath TYPE string,
l_down_path TYPE localfile,
ls_wwwdata TYPE wwwdata,
l_path TYPE string.
l_default_file_name = i_name.
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
window_title = '选择本地文件保存路径'
default_file_name = l_default_file_name
default_extension = '*.xlsx'
file_filter = 'EXCEL FILES(*.xlsx)|*.xlsx'
CHANGING
filename = l_filename
path = l_path
fullpath = l_fullpath
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
OTHERS = 5.
IF sy-subrc <> 0.
RETURN.
ENDIF.
SELECT SINGLE *
FROM wwwdata
INNER JOIN tadir
ON wwwdata~objid = tadir~obj_name
INTO CORRESPONDING FIELDS OF ls_wwwdata_tab
WHERE wwwdata~srtf2 = 0
AND wwwdata~relid = 'MI'
AND tadir~pgmid = 'R3TR'
AND tadir~object = 'W3MI'
AND tadir~obj_name = i_objid.
IF sy-subrc <> 0.
MESSAGE |模板文件[{ i_objid }]不存在| TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
l_down_path = l_fullpath.
CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
EXPORTING
key = ls_wwwdata_tab
destination = l_down_path
IMPORTING
rc = l_rc.
IF sy-subrc = 0.
MESSAGE |模板下载成功| TYPE 'S'.
ELSE.
MESSAGE |模板下载失败| TYPE 'S'.
ENDIF.
ENDMETHOD.
METHOD export.
DATA lo_tabledescr TYPE REF TO cl_abap_tabledescr.
DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
lo_tabledescr ?= cl_abap_typedescr=>describe_by_data( it_data ).
lo_structdescr ?= lo_tabledescr->get_table_line_type( ).
" 获取内表信息
DATA(lt_component) = lo_structdescr->get_components( ).
" 深度结构处理太麻烦,不考虑了,有需要可以自己调整
DELETE lt_component WHERE type IS NOT INSTANCE OF cl_abap_elemdescr.
IF lt_component IS INITIAL.
MESSAGE '导出失败' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
DATA(lo_writer) = zcl_xlsx_io=>get_instance( ).
lo_writer->start( ). " 准备写入
" 写入抬头文本行
lo_writer->next_row( ).
LOOP AT lt_component INTO DATA(ls_component).
lo_writer->write_next_column( ls_component-name ).
ENDLOOP.
" 写入数据行
LOOP AT it_data ASSIGNING FIELD-SYMBOL(<ls_data>).
lo_writer->next_row( ).
LOOP AT lt_component INTO ls_component.
FIELD-SYMBOLS <fs_field> TYPE any.
ASSIGN COMPONENT ls_component-name OF STRUCTURE <ls_data> TO <fs_field>.
IF <fs_field> IS ASSIGNED.
lo_writer->write_next_column( <fs_field> ).
UNASSIGN <fs_field>.
ELSE.
lo_writer->next_column( ).
ENDIF.
ENDLOOP.
ENDLOOP.
" 导出到本地
lo_writer->save( i_filename = i_filename ).
ENDMETHOD.
METHOD get_instance.
ro_instance = NEW #( ).
TRY.
ro_instance->mo_xlsx = cl_ehfnd_xlsx=>get_instance( ).
IF i_buffer IS SUPPLIED.
ro_instance->mo_doc = ro_instance->mo_xlsx->load_doc( iv_file_data = i_buffer ).
ELSE.
ro_instance->mo_doc = ro_instance->mo_xlsx->create_doc( ).
ENDIF.
DATA(lt_sheet_info) = ro_instance->mo_doc->get_sheets( ).
ro_instance->mo_sheet = ro_instance->mo_doc->get_sheet_by_id( lt_sheet_info[ 1 ]-sheet_id ).
CATCH
cx_openxml_format
cx_openxml_not_found
cx_openxml_not_allowed.
CLEAR ro_instance.
ENDTRY.
ENDMETHOD.
METHOD get_local_file.
DATA l_filename TYPE string.
IF i_filename IS NOT INITIAL.
l_filename = i_filename.
ELSE.
l_filename = cl_openxml_helper=>browse_local_file_open(
iv_title = 'Choose'
iv_filename = 'Import.xlsx'
iv_extpattern = '*.xlsx|*.xlsx' ).
ENDIF.
CHECK l_filename IS NOT INITIAL.
TRY.
r_buffer = cl_openxml_helper=>load_local_file( l_filename ).
CATCH cx_openxml_not_found.
CLEAR r_buffer.
ENDTRY.
ENDMETHOD.
METHOD get_reader.
DATA(l_buffer) = zcl_xlsx_io=>get_local_file( i_filename ).
ro_instance = zcl_xlsx_io=>get_instance( i_buffer = l_buffer ).
ENDMETHOD.
METHOD get_smw0_templete.
DATA: lt_mime TYPE STANDARD TABLE OF w3mime,
ls_id TYPE wwwdataid,
ls_key TYPE wwwdatatab.
ls_key-relid ='MI'.
ls_key-objid = i_objid.
CALL FUNCTION 'WWWDATA_IMPORT'
EXPORTING
key = ls_key
TABLES
mime = lt_mime
EXCEPTIONS
wrong_object_type = 1
import_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE |模板[{ i_objid }]获取失败| TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
SELECT SINGLE value FROM wwwparams
WHERE relid = @ls_key-relid
AND objid = @ls_key-objid
AND name EQ 'filesize'
INTO @DATA(l_param).
DATA l_length TYPE i.
l_length = l_param.
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = l_length
IMPORTING
buffer = r_buffer
TABLES
binary_tab = lt_mime
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR r_buffer.
ENDIF.
ENDMETHOD.
METHOD get_writer.
ro_instance = get_instance( ).
ENDMETHOD.
METHOD has_next_column.
r_flag = xsdbool( m_column_last > m_column ).
ENDMETHOD.
METHOD has_next_row.
r_flag = xsdbool( m_row_last > m_row ).
ENDMETHOD.
METHOD import.
DATA lr_data TYPE REF TO data.
FIELD-SYMBOLS <fs_data> TYPE any.
FIELD-SYMBOLS <fs_field> TYPE any.
" 构造工作区
CREATE DATA lr_data LIKE LINE OF ct_data[].
ASSIGN lr_data->* TO <fs_data>.
CHECK <fs_data> IS ASSIGNED.
DATA(l_buffer) = get_local_file( i_filename = i_filename ).
CHECK l_buffer IS NOT INITIAL.
DATA(lo_reader) = zcl_xlsx_io=>get_instance( i_buffer = l_buffer ).
CHECK lo_reader IS NOT INITIAL.
" 准备读取
lo_reader->start( ).
" 跳过抬头行
DO i_skip_row TIMES.
lo_reader->next_row( ).
ENDDO.
" 读取数据行
WHILE lo_reader->has_next_row( ) = abap_true.
lo_reader->next_row( ).
CLEAR <fs_data>.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_data> TO <fs_field>.
IF <fs_field> IS ASSIGNED.
<fs_field> = lo_reader->read_next_column( ).
UNASSIGN <fs_field>.
ELSE.
EXIT.
ENDIF.
ENDDO.
INSERT <fs_data> INTO TABLE ct_data.
ENDWHILE.
ENDMETHOD.
METHOD next_column.
m_column = m_column + i_column.
ENDMETHOD.
METHOD next_row.
m_row = m_row + i_row.
CLEAR m_column.
m_column_last = mo_sheet->get_last_column_number_in_row( m_row ).
ENDMETHOD.
METHOD read_column.
r_value = mo_sheet->get_cell_content( iv_row = m_row
iv_column = i_column ).
IF e_value IS SUPPLIED.
me->conv(
EXPORTING
dataflow = 'INPUT'
input = r_value
IMPORTING
output = e_value
).
ENDIF.
ENDMETHOD.
METHOD read_next_column.
next_column( ).
r_value = read_column( m_column ).
IF e_value IS SUPPLIED.
me->conv(
EXPORTING
dataflow = 'INPUT'
input = r_value
IMPORTING
output = e_value
).
ENDIF.
ENDMETHOD.
METHOD row_id.
r_row = m_row.
ENDMETHOD.
METHOD save.
DATA l_filename TYPE string.
IF i_filename IS NOT INITIAL.
l_filename = i_filename.
ELSE.
l_filename = cl_openxml_helper=>browse_local_file_save(
iv_title = 'Save as'
iv_filename = 'Export.xlsx'
iv_extpattern = '*.xlsx|*.xlsx' ).
ENDIF.
CHECK l_filename IS NOT INITIAL.
TRY.
cl_openxml_helper=>store_local_file(
im_file_name = l_filename
im_data = mo_doc->save( ) ).
CATCH
cx_openxml_format
cx_openxml_not_found
cx_openxml_not_allowed
cx_dynamic_check
INTO DATA(lx_openxml).
MESSAGE lx_openxml->get_longtext( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
METHOD start.
m_row_last = mo_sheet->get_last_row_number( ).
m_row = i_row.
m_column = i_column.
ENDMETHOD.
METHOD stop.
m_row = m_row_last.
IF m_row > 0.
m_column_last = mo_sheet->get_last_column_number_in_row( m_row ).
m_column = m_column_last.
ENDIF.
ENDMETHOD.
METHOD write_column.
DATA l_value TYPE string.
IF i_conv = abap_true.
me->conv(
EXPORTING
dataflow = 'OUTPUT'
input = i_value
IMPORTING
output = l_value
).
ELSE.
l_value = i_value.
ENDIF.
mo_sheet->set_cell_content( iv_row = m_row
iv_column = i_column
iv_value = l_value ).
ENDMETHOD.
METHOD write_next_column.
next_column( ).
write_column( i_column = m_column
i_conv = i_conv
i_value = i_value ).
ENDMETHOD.
METHOD replace_sharedstrings.
" 程序要求IT_REPLACE至少两列,代码会将左列内容替换为右列内容
CHECK it_replace IS NOT INITIAL.
CHECK c_doc IS NOT INITIAL.
FIELD-SYMBOLS <fs_replace_t> TYPE ANY TABLE.
FIELD-SYMBOLS <fs_replace> TYPE any.
FIELD-SYMBOLS <fs_from> TYPE any.
FIELD-SYMBOLS <fs_to> TYPE any.
TRY.
DATA(lo_doc) = cl_xlsx_document=>load_document( c_doc ).
DATA(lo_workbook_part) = lo_doc->get_workbookpart( ).
DATA(lo_sharedstrings_part) = lo_workbook_part->get_sharedstringspart( ).
DATA(l_sharedstrings_xml) = lo_sharedstrings_part->get_data( ).
DATA(l_sharedstrings_str) = cl_openxml_helper=>xstring_to_string( l_sharedstrings_xml ).
ASSIGN it_replace TO <fs_replace_t>.
LOOP AT <fs_replace_t> ASSIGNING <fs_replace>.
ASSIGN COMPONENT 1 OF STRUCTURE <fs_replace> TO <fs_from> .
ASSIGN COMPONENT 2 OF STRUCTURE <fs_replace> TO <fs_to> .
IF <fs_from> IS ASSIGNED AND <fs_to> IS ASSIGNED.
IF <fs_from> IS NOT INITIAL.
REPLACE ALL OCCURRENCES OF <fs_from> IN l_sharedstrings_str WITH <fs_to> IN CHARACTER MODE.
ENDIF.
ENDIF.
UNASSIGN <fs_from>.
UNASSIGN <fs_to>.
ENDLOOP.
l_sharedstrings_xml = cl_openxml_helper=>string_to_xstring( l_sharedstrings_str ).
lo_sharedstrings_part->feed_data( l_sharedstrings_xml ).
c_doc = lo_doc->get_package_data( ).
CATCH cx_openxml_not_found
cx_openxml_format
cx_openxml_not_allowed
INTO DATA(lx_openxml).
MESSAGE lx_openxml->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
CATCH cx_root INTO DATA(lx_root).
MESSAGE lx_root->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
|
示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | TYPES:
BEGIN OF ty_data,
field1 TYPE string,
field2 TYPE string,
END OF ty_data.
DATA lt_data TYPE STANDARD TABLE OF ty_data.
lt_data = VALUE #(
( field1 = 'A1' field2 = 'B1' )
( field1 = 'A2' field2 = 'B2' )
).
" 导出
zcl_xlsx_io=>export( lt_data ).
" 导入
CLEAR lt_data.
zcl_xlsx_io=>import( CHANGING ct_data = lt_data ).
|
文本替换
对于固定模板文件,不妨直接替换里面的文本内容
示例代码
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 | DATA(l_buffer) = zcl_xlsx_io=>get_smw0_templete( CONV #( sy-tcode ) ). " 获取SMW0模板文件
TRY.
DATA(lo_doc) = cl_xlsx_document=>load_document( l_buffer ).
DATA(lo_workbook_part) = lo_doc->get_workbookpart( ).
DATA(lo_sharedstrings_part) = lo_workbook_part->get_sharedstringspart( ).
" 直接替换即可
" 也试过解析XML文件,但富文本格式难以处理
DATA(l_sharedstrings_xml) = lo_sharedstrings_part->get_data( ).
LOOP AT lt_replace INTO DATA(ls_replace).
DATA(l_from) = cl_openxml_helper=>string_to_xstring( ls_replace-from ).
IF l_from IS NOT INITIAL.
DATA(l_to) = cl_openxml_helper=>string_to_xstring( ls_replace-to ).
REPLACE ALL OCCURRENCES OF l_from IN l_sharedstrings_xml WITH l_to IN BYTE MODE.
ENDIF.
CLEAR l_from.
CLEAR l_to.
ENDLOOP.
lo_sharedstrings_part->feed_data( l_sharedstrings_xml ). " 回写
l_buffer = lo_doc->get_package_data( ). " 获取替换后的文件
CATCH cx_openxml_not_found
cx_openxml_format
cx_openxml_not_allowed
INTO DATA(lx_openxml).
MESSAGE lx_openxml->get_text( ) TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
|
ABAP2XLSX
第三方工具,通过解析XLSX中的XML文件,实现高速读取数据。相比CL_EHFND_XLSX,提供了更齐全的样式设置。
https://github.com/abap2xlsx/abap2xlsx/releases
XLSX WORKBANCH
第三方工具,类似SMARTFORMS,预先设置好EXCEL模板与输入参数,随后可在程序中直接调用获取,适合导出特定格式的需求。
TEXT_CONVERT_XLS_TO_SAP
该方法可将EXCEL内容直接映射到ABAP内表中。
示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | TYPES:
BEGIN OF ty_data,
field1 TYPE string,
field2 TYPE string,
END OF ty_data.
TYPES tt_data TYPE STANDARD TABLE OF ty_data.
DATA lt_data TYPE tt_data.
DATA lt_raw TYPE truxs_t_text_data.
CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
EXPORTING
i_line_header = abap_false
i_tab_raw_data = lt_raw
i_filename = 'C:\import.xls'
TABLES
i_tab_converted_data = lt_data
EXCEPTIONS
conversion_failed = 1
OTHERS = 2.
|
ALSM_EXCEL_TO_INTERNAL_TABLE
该方法可获取EXCEL单元格内容,处理灵活。
示例代码
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 | TYPES:
BEGIN OF ty_data,
field1 TYPE string,
field2 TYPE string,
END OF ty_data.
TYPES tt_data TYPE STANDARD TABLE OF ty_data.
DATA lt_data TYPE tt_data.
DATA ls_data TYPE ty_data.
DATA lt_intern TYPE STANDARD TABLE OF alsmex_tabline.
DATA ls_intern TYPE alsmex_tabline.
CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = 'C:\import.xls'
i_begin_col = 1
i_begin_row = 2 " 跳过首行
i_end_col = 2
i_end_row = 9999
TABLES
intern = lt_intern
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
SORT lt_intern BY row col.
LOOP AT lt_intern INTO ls_intern.
AT NEW row.
CLEAR ls_data.
ENDAT.
CASE ls_intern-col.
WHEN '0001'.
ls_data-field1 = ls_intern-value.
WHEN '0002'.
ls_data-field2 = ls_intern-value.
WHEN OTHERS.
ENDCASE.
AT END OF row.
INSERT ls_data INTO TABLE lt_data.
ENDAT.
ENDLOOP.
|
OLE
上古工具,建议放弃
DOI
没用过,不懂