Сегодня расскажу о небольшом решении по выгрузке результатов анализов BI в виде отчетов BI Publisher.
Столкнулся с необходимостью подобного на одном из прошлых проектов - было решено использовать в качестве источника данных для отчетности ТОЛЬКО репозиторий Oracle BI.
Соответственно вся отчетность формировалась только с помощью Oracle BI Answers.
Несмотря на архитектурную изящность решения (всего одна точка доступа и модификации представления данных) это приводило к ряду проблем: например, ряд управленческих отчетов нужен был и топ-менеджменту и бухгалтерии. Первые отчетность смотрят через Ipad, вторые через свои компьютеры в Excel и только в Excel (знакомо?).
Выход был найден следующий - разработан пользовательский javascript (через механизм Actions Framework), позволяющий создавать ссылки под/над любым BI анализом на инфопанели, выгружающие этот анализ в виде отчета BI Publisher.
Вы скажете: "Что тут такого? Я и так могу создать Publisher-отчет под любой анализ. А затем поместить ссылку на этот отчет на инфопанели".
Согласен. Так можно. Но подобное решение содержит изъяны:
1) Это некрасиво
2) Если вы поместите отчет BI Publisher на инфопанель как ссылку, то НЕ БУДЕТ ПЕРЕДАВАТЬСЯ контекст параметров! А если использовать отчет BI Publisher как встроенное содержимое (iframe), то получается и вовсе убожество (хотя параметры передадутся)...
Поэтому все-таки мы использовали кастомизацию. Несложную.
1) В файле c:\Middleware\user_projects\domains\bifoundation_domain\servers\bi_server1\tmp\_WL_user\analytics_11.1.1\7dezjl\war\res\b_mozilla\actions\UserScripts.js
(у вас это, естественно, другой путь, но смысл тот же)
была описана новая вызываемая функция USERSCRIPT.BIPReportOpen.
USERSCRIPT._BIPReportOpen = function (b) { var params_dashboardexpr = ""; if (b) { var appliedStates = obips.XMLDOM.selectNodes(b, "//sawsel:appliedStates", saw.xml.commonNamespaces); var unionExpr = XUICreateElement(saw.xml.kSawxNamespace, "expr"); unionExpr.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); unionExpr.setAttribute("xsi:type", "sawx:logical"); unionExpr.setAttribute("op", "and"); for(ii=0; ii<appliedStates.length; ii++) { unionExpr.appendChild(appliedStates[ii]); } if (appliedStates.length == 0) { params_dashboardexpr = "" } else { if (appliedStates.length == 1) { unionExpr = unionExpr.firstChild } params_dashboardexpr = saw.getXmlText(unionExpr); params_dashboardexpr = encodeURIComponent(params_dashboardexpr) } } var BIPReportParams = window.BIPReportParams; var newWindow = BIPReportParams['newWindow']; var xautorun = BIPReportParams['xautorun']; var xdo = BIPReportParams['xdo']; var xf = BIPReportParams['xf']; var xmode = BIPReportParams['xmode']; var xpf = BIPReportParams['xpf']; var xpt = BIPReportParams['xpt']; var xt = BIPReportParams['xt']; var sUrl = "/xmlpserver/servlet/xdo?"; sUrl += "_params_dashboardexpr=" + params_dashboardexpr; sUrl += "&_xautorun=" + xautorun; sUrl += "&_xdo=" + xdo; sUrl += "&_xf=" + xf; sUrl += "&_xmode=" + xmode; sUrl += "&_xpf=" + xpf; sUrl += "&_xpt=" + xpt; sUrl += "&_xt=" + xt; if (newWindow == "true") { obips.launcher.launchNewWindow(sUrl, "_blank", "", { ensureFreshUrl: true }) } else { saw.runThisURL(sUrl) } }; USERSCRIPT.BIPReportOpen = function (z) { var c = document.getElementById("idViewStateDiv"); var a = obips.views.ViewController.getController(c.getAttribute("statePath")); var b = a.getClientStateManager(); if (b._isClientStateXmlLoaded()) { window.BIPReportParams = z; b.getDashboardStateXMLFromServer(2, new obips.Callback(null, USERSCRIPT._BIPReportOpen), true) } }; USERSCRIPT.BIPReportOpen.publish = { parameters: [ new USERSCRIPT.parameter("newWindow", "Launch new window {true|false}", "false"), new USERSCRIPT.parameter("xautorun", "Autorun {true|false}", "true"), new USERSCRIPT.parameter("xdo", "Path to report ( /Samples/Test.xdo )", ""), new USERSCRIPT.parameter("xf", "Output format (html|rtf|pdf|excel...)", "excel"), new USERSCRIPT.parameter("xmode", "Mode", "4"), new USERSCRIPT.parameter("xpf", "Preview false?", ""), new USERSCRIPT.parameter("xpt", "0 - inline, 1 - attachment", "1"), new USERSCRIPT.parameter("xt", "Template name", "Standard")] };
2) Были созданы отчеты BI Publisher для нужны анализов BI. В качестве шаблона использовался "Excel template". Модели данных для этих отчетов базировались на искомых анализах BI.
3) В информационных панелях, содержащих искомые анализы BI, были созданы новые элементы - Action Link, с типом Invoke a Browser Script
(не забывайте очищать кеш браузера, чтобы изменения в UserScripts.js стали доступны)
Для каждого такого элементы были прописаны параметры вызова Publisher отчета:
- следует ли открывать отчет в новом окне;
- путь до отчета;
- формат отчета (excel);
- шаблон отчет и т.д.
Вот и все!
Решение гибкое - позволяет вам самим создавать необходимые форматы выгрузки анализов BI. Размещать их где угодно на информационной панели. И не опасаться потери контекста параметров.
Добрый день,Jack Carver.
ОтветитьУдалитьСпасибо за статью. Но есть вопрос.
Добавил Ваш скрипт, в Excel на странице XDO_METADATA добавил
строки XDO_PARAM_?1?
и XDO_?pDate1?
На странице с отчетом присвоил имя XDO_?pDate1? ячейке.
На странице информ панели, если открыть отчет как встроенное содержимое, то значение параметра в Excel отчете отображается,
а вот если в соответствии с Вашей статьей открывать отчет через Action Link, с типом Invoke a Browser Script, то отчет строится правильно, но вот значение самого параметра не отображается.
Подскажите, плиз, что необходимо сделать?
Здравствуйте, похоже я в суете последних недель (активная сдача проекта!) пропустил ваш комментарий...
ОтветитьУдалитьПростите великодушно!
Я стараюсь рекомендовать самые простые решения (они самые надежные), мне кажется, в вашем случае проще всего создать новый анализ (например, назовите его "Значения параметров"), который бы возвращал только строки со значениями параметров.
И затем следует добавить обращение к этому анализу как новый DataSet в отчете BIPublisher.