воскресенье, 15 апреля 2007 г.

Apex. Добавялем возможность экспорта... CSV, XML

Продолжаем серию статей, демонстрирующую на примерах процесс создания приложений в Oracle Application Express, и сегодня будем развивать приложение, созданное ранее.
Одним из наиболее часто встречающихся требований для приложений является возможность вывода информации в различные форматы электронных документов. В этом примере постараемся добавить возможность экспорта данных в CSV и XML форматы.

Сначала попытаемся экспортировать данные в CSV. Есть несколько вариантов реализации, например:

  • использование стандартной опции "Enable CSV output"
  • использование типа отчета "export: CSV"
Сначала, воспользуемся стандартной опцией. Для этого необходимо зайти в определение страницы:

APEX page definition
После чего - в описание отчета:

APEX report definition
и изменить следующие настройки в разделе "Report Export":

Apex option Report ExportНазначение этих настроек следующее:
  • "Enable CSV output" - задает непосредственную возможность экспорта в CSV
  • "Separator" - задает разделитель значений колонок. Если не задавать значения, то будет использоваться либо запятая, либо точка с запятой в зависимости от текущих NLS настроек.
  • "Enclosed By" - символ, обозначающий начало и конец значения колонки. Если не задан, то используются двойные кавычки.
  • "Link Label" - текст для ссылки, которая будет вызывать диалог для сохранения CSV файла.
  • "Filename" - задает имя для экспортируемого файла. Если не задается, то используется имя региона отчета.
После чего, запустив приложение, можно будет заметить появление нового элемента в отчете "Типы объектов" - "Экспорт в CSV":

APEX witn export to csv

Теперь же, попробуем реализовать экспорт данных отчета через настройку "Report Template" секции "Layout and Pagination" описания отчета. Для того, чтобы отчет экспортировался в CSV, необходимо просто выставить "Report Template" = "export: CSV".

Особенность этой реализации заключается в том, что при запуске такого отчета будет сразу запускаться механизм формирования CSV файла. То есть, при попытке открытия страницы, где располагается такой отчет, сразу появится диалоговое окно в предложением сохранить файл. Для пользователя это будет не всегда удобно, так как ему не всегда необходим экспортированный отчет, а порой достаточно простого вывода отчета в HTML.

Соответственно, чтобы позволять пользователю по желанию экспортировать отчеты, необходимо вынести такой отчет на отдельную страницу и позволять пользователю ее вызывать. Для этого, создаем новую страницу в приложении:

APEX create new page

Выбираем следующие свойства новой страницы:
  • "page type" = "Blank Page"
  • "name" = "MainReportExport"
  • "title" = "MainReportExport"
  • "Breadcrumb" = "- do not use breadcrumbs on page -"
  • "Use Tabs" = "No"
Сразу переходим к редактированию страницы, и добавляем в нее новый регион:

APEX add new region to page

Выбираем следующие свойства региона:
  • "Region Type" = "Report"
  • "Report Implementation" = "SQL Report"
  • "Title" = "Object_Types"
  • "Region Template" = "Reports region"
  • "Display Point" = "Page Template Body (3. items above region content)"
  • "Source":
Select Object_Type, Count(*)
From User_Objects
Group By Object_Type
  • "Report Template" = "export: CSV"

Теперь приложение состоит из двух основных форм "Main", "MainReportExport":

APEX application pagesОсталось только добавить на первую страницу ("Main") средство перехода на только что созданную страницу. Для этого переходим в описание исходной страницы и добавляем в нее кнопку:
  • "region for the button" = ""
  • "position" = ""
  • "button name" = "EXPORT2CSV"
  • "label" = "Экспртировать в CSV"
  • "position" = "Bottom of Region"
  • "alignment" = "left"
  • "branch to page(when button pressed)" = "2" (выбираем из списка созданную ранее страницу)
Результат:

APEX application with export to csv abilityТеперь при нажатии кнопки будет так же формироваться отчет в CSV.

Аналогичным же образом реализуется экспорт и в XML. Необходимо добавить на страницу "MainReportExport" еще один регион, аналогичный тому, который уже был добавлен ранее, за исключением опции "Report Template", которую необходимо будет задать в "export: XML":


Таким образом, мы имеем на одной странице два экспортируемых отчета и нам необходимо иметь возможность запускать какой-то один из них. Для этого добавляем на страницу "MainReportExport" невидимый элемент, задавая который при переходе, мы будем в состоянии регулировать запуск того или иного отчета, расположенного на странице. Задаем элементу следующие параметры:
  • "Item type" = ""
  • "Item name" = "P2_EXP_TYPE"
Корректируем регион экспорта в CSV - "Object_Types" в секции "Conditional Display":
  • "Condition Type" = "Value of Item in Expression 1 = Expression 2"
  • "Expression 1" = "P2_EXP_TYPE"
  • "Expression 2" = "CSV"
Корректируем регион экспорта в XML - "Object_Types_Xml" в секции "Conditional Display":
  • "Condition Type" = "Value of Item in Expression 1 = Expression 2"
  • "Expression 1" = "P2_EXP_TYPE"
  • "Expression 2" = "XML"
Осталось только реализовать заполнение поля P2_EXP_TYPE. Для этого в странице "Main" редактируем описание имеющейся кнопки:


Изменяем следующие свойства:


То есть, при переходе по этой кнопке в страницу отчетов будет отрабатывать CSV отчет. Для XML добавляем еще одну кнопку:
  • "region for the button" = ""
  • "position" = ""
  • "button name" = "EXPORT2XML"
  • "label" = "Экспртировать в XML"
  • "position" = "Bottom of Region"
  • "alignment" = "left"
  • "branch to page(when button pressed)" = "2"
После чего в описании новой кнопки выставляем следующие свойства:


То есть, при переходе через эту кнопку будет отрабатывать экспорт отчета в XML. Главная страница, при этом, примет следующий вид:

APEX application example

Вот, собственно и все. Проверить приложение в работе можно на apex.oracle.com.

10 комментариев:

Анонимный комментирует...

Добрый день.
У меня после апгрейда с 2.0 до 3.0 при экспорте в CSV через стандартную процедуру, данные выходят "крякозябрами". Видимо кодировка не совпадает у базы и приложения. Помогите решить данную проблему. На 2.0 все работало успешно.

Timoshinin Evgeny комментирует...

Привет, Владимир....

Да, наверняка, не совпадают кодировки в БД и mod_plsql (DAD).

Узнать кодировку БД можно так:
Select Property_Value
From Database_Properties
Where Property_Name = 'NLS_CHARACTERSET'

Кодировка в DAD:
UNIX/Linux:
ORACLE_BASE/ORACLE_HOME/Apache/modplsql/conf/dads.conf
Windows:
ORACLE_BASE\ORACLE_HOME\Apache\modplsql\conf\dads.conf
Параметр - PlsqlNLSLanguage.

Попробуйте выставить в DAD кодировку, аналогичную той, что выставлена для БД.

Timoshinin Evgeny комментирует...

В продолжение пред. комментария: Oracle рекомендует выставлять кодировку AL32UTF8 для PlsqlNLSLanguage. Например, "AMERICAN_AMERICA.AL32UTF8".

Анонимный комментирует...

Спасибо, попробую разобраться.
Помогите тогда с еще одной проблемой если это возможно.
Ночером запускаю процедурку проверки данных и расылаю мылом информацию об ошибках юзерам.
На версии 2.0 все работало отлично, а после апгрейда на 3.0, процедура ругается:
ORA-20001: This procedure must be invokedfrom within an application session.
Процедурка примерно такая(email в угловыз скобках, а не в круглых):
procedure Test_mail is
begin
HTMLDB_MAIL.SEND(
'(test@test.com)',
'(test@test.com)',
'тест',
'тест');
HTMLDB_MAIL.PUSH_QUEUE('smtp.test.com',25);
end Test_mail;

То есть когда я на страничке создаю процесс и по кнопке запускаю процедуру, то все работает.
А если я ее из PL*SQL Developera запускаю, то ругается.
Как победить подскажите?
На sql.ru посоветовали воспользоваться wwv_flow_api.set_security_group_id(p_security_group_id=>xxxxxxxxxxxxx);
Я подставил ИД приложения, что то мне не помогло.

Timoshinin Evgeny комментирует...

Я попробовал вызывать эту процедуру без параметров - сообщение об ошибке пропало.

Пример:

Begin
wwv_flow_api.set_security_group_id;
Htmldb_Mail.Send(...);
Htmldb_Mail.Push_Queue('smtp.host.com', 25);
End;


Процедура set_security_group_id выставляет идентификатор рабочей области (workspace ID) в глобальной переменной пакета, что заставляет apex_mail/htmldb_mail "считать", что его(пакет) вызывает авторизованный пользователь.

Анонимный комментирует...

Решпект.
Спасибо огромное, все заработало.

Timoshinin Evgeny комментирует...

:), Рад был помочь....

Unknown комментирует...

Добрый день! Подскажите пожалуйста.
Стоит Oracle Application server, Apex 4, BI Publisher (standalone). Нужна печать форматированого отчета с подписями и т.п. в утвержденной форме в excel.
Проблема заключается в том что при использование прямого селекта из таблицы отчет сохраняется верно, однако, если использовать apex_item, то в сохраняемом отчете пусто. Пожалуйста подскажите в чем может быть проблема? Как можно сохранить отчет в таком случае?

saidmir комментирует...
Этот комментарий был удален автором.
saidmir комментирует...

Привет
Делаю все как все написано. У меня apex 2,2 когда выбираю Report Template = export CSV мне говорит то что надо сразу сохранять хотя кнопку я создал на странице MainReportExport.

Почему так или я не так что то делаю?