В российских проектах для выгрузки в EXCEL применяется разработка ZWWW в большинстве случаев. Но она имеет несколько проблем как с быстродействием, так и с тем, что используется технология OLE. Основное неудобство на мой взгляд, это не возможность получить документ в фоне, и, например, сразу отправить его как вложение в письме и т.д.
Данную проблему можно решить используя другую разработку под названием ABAP2XLSX. Однако, из-за редкого использования многие не считают, что применяя ее невозможно использовать ранее сохраненные шаблоны. Это не так.
Рассмотрим небольшой пример в котором получим шаблон из репозитория состоящего из одного листа:
1. Скопируем этот лист со всем оформлением в новый.
2. Сохраним документ с двумя листами на локальный компьютер.
Все это делается уже готовыми методами, кроме создания копии листа. Поэтому для начала сделаем новый класс, унаследованный от исходного zcl_excel.
Нам потребуется создать один новый метод. Назовем его COPY_WORKSHEET.
Реализация очень проста:
Создаем страницу;
Kлонируем Страницу, которую подаем на вход метода как образец;
Прописываем новую страницу в документ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
" " DATA lo_worksheet TYPE REF TO zcl_excel_worksheet. CREATE OBJECT lo_worksheet EXPORTING ip_excel = me ip_title = 'TMP NAME' EXCEPTIONS OTHERS = 1. "Скопируем данные со страницы шаблона в новую SYSTEM-CALL OBJMGR CLONE io_worksheet_templ TO lo_worksheet. "Присвоим временное имя, что бы исключить ошибку в документе из-за одинаковых названий листов lo_worksheet->set_title( ip_title = |{ cl_system_uuid=>create_uuid_x16_static( ) }| ). "Добавим страницу в книгу me->worksheets->add( lo_worksheet ). ro_worksheet_new = lo_worksheet. |
Метод для копирования создан.
Приступим к программе. Первым делом необходимо получить шаблон из SMW0 и на его основе создать объект ранее созданного класса.
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 |
START-OF-SELECTION. "Получим файл из Репозитария DATA: mime TYPE STANDARD TABLE OF w3mime WITH HEADER LINE. DATA lv_bytelen TYPE i. DATA lv_lines TYPE i. DATA lv_value_len TYPE wwwparams-value. CONSTANTS lc_template_name TYPE W3OBJID VALUE 'ZMM_PASH_TMP'. IMPORT mime FROM DATABASE wwwdata(mi) ID lc_template_name. DESCRIBE TABLE mime[] LINES lv_lines. CALL FUNCTION 'WWWPARAMS_READ' EXPORTING relid = 'MI' objid = lc_template_name name = 'filesize' IMPORTING value = lv_value_len EXCEPTIONS OTHERS = 1. lv_bytelen = lv_value_len. CALL METHOD cl_rswad_convert=>w3mime_to_xstring( EXPORTING i_bytelen = lv_bytelen i_t_table = mime[] IMPORTING e_xstring = DATA(lv_xstring) ). |
Файл в переменной lv_xstring. Его можно получить откуда угодно. Получение из SMW0 - частный случай.
Для создания объекта нашего класса будем использовать метод LOAD интерфейса zif_excel_reader. Создатели данной разработки предусмотрели возможность того, что её будут дорабатывать, и есть возможность подать свой тип в параметр iv_zcl_excel_classname .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
" Создадим файл на основе шаблона DATA: lo_excel TYPE REF TO zcl_excel_test_pash, "zcl_excel, lo_reader TYPE REF TO zif_excel_reader. DATA: lo_worksheet TYPE REF TO zcl_excel_worksheet. DATA: lo_drawing TYPE REF TO zcl_excel_drawing. DATA lo_converter TYPE REF TO zcl_excel_converter. CREATE OBJECT lo_reader TYPE zcl_excel_reader_2007. TRY. lo_excel ?= lo_reader->load( i_excel2007 = lv_xstring iv_zcl_excel_classname = 'ZCL_EXCEL_TEST_PASH' i_use_alternate_zip = space ). CATCH zcx_excel. EXIT. ENDTRY. " Получим активную страницу которую и будем копировать "У нас в шаблоне она одна, но можно сделать много и использовать их по своему желанию DATA(lo_worksheet_templ) = lo_excel->get_active_worksheet( ). lo_worksheet = lo_excel->copy_worksheet( lo_worksheet_templ ). lo_worksheet->set_title( ip_title = 'Новая Страница 1' ). |
Также мы можем брать стиль ячейки из шаблона и применять его для других ячеек. Очень удобно хранить разные варианты сложного форматирования. В дальнейшем, консультант сам может их менять в формуляре без разработчика. Можно создать отдельный лист и хранить на нем все стили. После использования удалять его.
Возьмем стиль Ячейки A1 и применим его на ячейки B2 B3.
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 |
lo_worksheet->get_cell( EXPORTING ip_column = 'A' ip_row = '1' IMPORTING ep_rc = DATA(lv_rc) ep_style = DATA(lo_style) ep_guid = DATA(lv_guid) ep_formula = DATA(lo_formula) ). lo_worksheet->set_cell_style( EXPORTING ip_column = 'B' ip_row = '2' ip_style = lv_guid ). lo_worksheet->set_cell_style( EXPORTING ip_column = 'B' ip_row = '3' ip_style = lv_guid ). |
Сохраним получившийся документ на локальном компьютере.
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 |
*Сохранение в локальной папке DATA lo_writer TYPE REF TO zif_excel_writer. DATA lv_output_data TYPE xstring. CREATE OBJECT lo_writer TYPE zcl_excel_writer_2007. DATA(lv_xstring_out) = lo_writer->write_file( lo_excel ). DATA(lt_output_data) = cl_bcs_convert=>xstring_to_solix( iv_xstring = lv_xstring_out ). DESCRIBE TABLE lt_output_data LINES lv_lines. DATA(lv_bytecount) = xstrlen( lv_xstring_out ). "Выберем каталог DATA lv_path TYPE string. CONSTANTS lc_save_file_name TYPE string VALUE 'DEMO_XLSX.XLSX'. cl_gui_frontend_services=>directory_browse( EXPORTING window_title = 'Выбор каталога' * initial_folder = CHANGING selected_folder = lv_path EXCEPTIONS cntl_error = 1 error_no_gui = 2 not_supported_by_gui = 3 OTHERS = 4 ). cl_gui_cfw=>flush( ). CHECK lv_path IS NOT INITIAL. IF lv_path CA '/'. REPLACE REGEX '([^/])\s*$' IN lv_path WITH '$1/' . ELSE. REPLACE REGEX '([^\\])\s*$' IN lv_path WITH '$1\\'. ENDIF. cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = lv_bytecount filename = |{ lv_path }{ lc_save_file_name }| filetype = 'BIN' CHANGING data_tab = lt_output_data ). |
У меня был такой исходный шаблон:
Выходной документ
Лайк!
строчку “SYSTEM-CALL OBJMGR CLONE io_worksheet_templ TO lo_worksheet.” стоило бы подробней прокомментировать