5.5.1.4. JasperReport-шаблоны (.jrxml)¶
JasperReport-шаблон — zip-архив с разметкой отчёта и, при необходимости, со скомпилированными скриптлетами и собственными библиотеками. В отличие от остальных форматов, логика шаблона пишется на Java: подстановки и агрегаты вычисляются выражениями Jasper, а более сложные вычисления выносятся в скриптлет.
Шаблоны редактируются в Jaspersoft® Studio 6.20 и хранятся в базе данных вместе с остальными печатными формами.
5.5.1.4.1. Состав архива¶
Содержимое |
Назначение |
|---|---|
|
Главный файл шаблона. Имя фиксировано и задаётся константой
|
прочие |
Подотчёты, подключаемые из главного файла. |
|
Скомпилированные скриптлеты. Ищутся и в корне архива, и в каталоге
|
|
Собственные библиотеки шаблона. Перед заполнением распаковываются рядом с архивом и добавляются в загрузчик классов скриптлетов. |
Скомпилированный шаблон кэшируется: при повторном построении отчёта компиляция
.jrxml не выполняется.
5.5.1.4.2. Скриптлеты¶
Скриптлет объявляется в шаблоне и вызывается через параметр
$P{<имя скриптлета>_SCRIPTLET}:
<jasperReport name="detail" scriptletClass="SpelloutScriptlet">
<scriptlet name="Spellout" class="SpelloutScriptlet"/>
...
<textFieldExpression>
<![CDATA[$P{Spellout_SCRIPTLET}.numberToStrRu($V{nQtyBase})]]>
</textFieldExpression>
</jasperReport>
Класс скриптлета загружается отдельным загрузчиком, родителем которого выступает загрузчик сервера приложений. Поэтому скриптлету доступны библиотеки самого сервера, а не только те, что лежат в архиве шаблона.
5.5.1.4.3. Пропись чисел и сумм¶
Для прописи в загрузчике сервера лежат две библиотеки: ru.bitec:numbertostr
(пропись числа) и com.github.javadev:moneytostr (пропись денежной суммы,
вызывается через обёртку ru.bitec.numbertostr.MoneyToStr).
Метод |
Результат |
|---|---|
|
Число прописью набором правил локали по умолчанию:
|
|
Число прописью женским родом:
|
|
Денежная сумма:
|
Параметры MoneyToStr.spellout:
Параметр |
Значения |
|---|---|
|
|
|
|
|
|
5.5.1.4.3.1. Точность¶
Библиотека печатает то значение, которое ей передали: величина не округляется
и не подгоняется под точность double. Ограничение ровно одно — словарь
разрядов, которым она располагает:
дробная часть длиннее одиннадцати знаков округляется (
HALF_UP): для более мелких разрядов слов нет, последний — «стомиллиардная»;число, у которого целая часть достигла 1018, печатается цифрами целиком: словарь разрядов кончился, а смешивать цифры и слова в одной строке нельзя.
5.5.1.4.3.2. Что передавать на вход¶
Warning
Передача числа, прошедшего через double, искажает пропись: дробное значение
в double хранится приближённо, и это приближение читается словами.
new BigDecimal("12345678.9") двенадцать миллионов … восемь целых девять десятых
new BigDecimal(12345678.9) двенадцать миллионов … восемь целых девяносто
миллиардов тридцать семь стомиллиардных
Библиотека такой вход не вычищает и печатает ровно то значение, которое получила. По цифрам в форме расхождение не видно — там число выглядит правильно, расходится только пропись.
Точность сохраняется при следующих условиях:
колонка в базе — точный десятичный тип (
numeric), неdouble precisionи неreal, и в запросе шаблона она не приводится к плавающему типу;поле и итоговая переменная объявлены как
java.math.BigDecimal, неjava.lang.Double;значение передаётся в скриптлет напрямую, без
new BigDecimal(...)вокруг него.
<field name="nqtybase" class="java.math.BigDecimal"/>
<variable name="nQtyBase" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{nqtybase}]]></variableExpression>
</variable>
Note
Функция макроязыка NumberToStrRUS(attr) из TXT-
и Excel-шаблонов — независимая реализация внутри
сервера. Она работает только с целыми числами: дробное значение приводит
к ошибке построения отчёта.
5.5.1.4.4. Пример¶
Скриптлет:
import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;
import ru.bitec.numbertostr.NumberToStr;
import java.math.BigDecimal;
import java.util.Locale;
public class SpelloutScriptlet extends JRDefaultScriptlet {
public String numberToStrRu(BigDecimal npSum) throws JRScriptletException {
return NumberToStr.spellout(new Locale("ru"), npSum);
}
}
Шаблон — итог по количеству прописью:
<scriptlet name="Spellout" class="SpelloutScriptlet"/>
<field name="nqtybase" class="java.math.BigDecimal"/>
<variable name="nQtyBase" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{nqtybase}]]></variableExpression>
</variable>
<textField>
<textFieldExpression>
<![CDATA["Итого: " + $P{Spellout_SCRIPTLET}.numberToStrRu($V{nQtyBase})]]>
</textFieldExpression>
</textField>
Результат для итога 8816.22:
Итого: восемь тысяч восемьсот шестнадцать целых двадцать две сотых
See also
Отчеты — хранение шаблонов, запуск построения, события строителя отчётов.
ru.bitec.gtk.core.report.CoreReportBuilder— построение отчёта из прикладного кода.