Сегодня расскажу о небольшом решении по выгрузке результатов анализов 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.