лениво компилировать JasperReports .jrxml в .jasper - PullRequest
2 голосов
/ 24 ноября 2008

Я использую отчеты Jasper с классом JasperReportsMultiFormatView , предоставляемым средой Spring. Этот класс заботится о компиляции исходных файлов .jrxml в их скомпилированный формат .jasper при создании контекста приложения Spring.

Однако этот процесс компиляции действительно замедляет время запуска приложения. Возможно ли, чтобы отчеты лениво компилировались, а не компилировались во время запуска, то есть отчет компилируется только при первом запросе?

Если это невозможно, альтернативные предложения о том, как я могу сократить / исключить время составления отчета, будут приветствоваться. Конечно, я мог бы потребовать, чтобы скомпилированные отчеты были проверены в SVN вместе с файлами .jrxml, но это только вопрос времени, прежде чем кто-то (скорее всего я) забудет.

Ура, Don

Ответы [ 2 ]

8 голосов
/ 30 ноября 2008

Я, как и вы, начал с вспомогательных классов Spring для Jasper Reports, но быстро отказался от них как слишком грубых и негибких, что необычно для Spring. Как будто они были добавлены как запоздалая мысль.

Большая проблема, с которой я столкнулся, заключалась в том, что после того, как они были скомпилированы, для добавления новых версий требовался отскок сервера приложений. В моем случае я искал решение, с помощью которого я мог бы поменять их на диске, и они перекомпилировали бы, во многом как обычная работа JSP (если вы не отключите эту функцию, как это делают многие производственные сайты).

В качестве альтернативы я хотел иметь возможность хранить файлы jrxml в базе данных или удаленно запускать отчеты (например, через интерфейс веб-служб JasperServer). Классы Spring просто сделали практически невозможным реализацию таких функций.

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

Первое, что вам нужно, это компилятор отчетов Jasper. Это отвечает за компиляцию файла jrxml в объект JasperDesign. Есть несколько реализаций этого, но вам нужна JRJdtCompiler. Вы можете создать и внедрить это в контексте приложения Spring. Избегайте других, таких как компилятор BeanShell, поскольку запуск отчета в виде большого скрипта BeanShell не очень быстрый и не эффективный (я понял это непросто, прежде чем стал лучше).

Вам нужно будет включить файлы jar для JRJdtCompiler. Я думаю, что полный Jasper Reports dist включает эту банку. Это продукт затмения.

Вы можете хранить JasperDesign где угодно (HttpSession, контекст сервлета или любой другой). Метод fillReport () является основным, который вас интересует. Он создает объект JasperPrint, который является экземпляром отчета о выполнении. Параметры просто передаются в виде карты.

Теперь, чтобы создать версию в HTML, PDF и т. Д., Вам нужно ее экспортировать. Для этого вы используете классы, такие как JRHtmlExporter и JRPdfExporter. Они требуют определенных параметров. Самое сложное - это экспортер HTML, потому что HTML явно не включает изображения. Jasper включает в себя класс ImageServlet, который извлекает их из сеанса (куда их поместил JRHtmlExporter), но вы должны точно настроить конфигурацию как экспортера HTML, так и сервлета изображения, и трудно сказать, где вы идете не так. *

Я не помню специфику этого, но есть пример всего этого в Jasper Reports Definition Guide , который я настоятельно рекомендую вам получить, если вы вообще тратите время с этим товар. Это довольно дешево на 50 долларов США. Вы также можете получить годовую подписку, но за 18 с лишним месяцев, которые я видел, я не видел ни одного изменения. Просто купите новую версию, когда она выйдет, если она вам нужна (что, вероятно, вам не понадобится).

Надеюсь, это поможет.

1 голос
/ 30 января 2013

Отчет компилируется при первом запуске, для подтверждения этого поставьте точку останова в конечном защищенном методе AbstractJasperReportsView JasperReport loadReport (Resource resource).

Однако вышеприведенная запись верна: вам нужно расширить JasperReportsMultiFormatView, если вы хотите обеспечить какой-либо конкретный процесс компиляции.

Отличный пример динамической компиляции здесь: http://javanetspeed.blogspot.com/2013/01/jasper-ireport-with-java-spring-and.html

import net.sf.jasperreports.engine.JasperReport;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView;

public class DynamicJasperReportsMultiFormatView extends JasperReportsMultiFormatView {

private static final Logger LOG = Logger.getLogger(DynamicJasperReportsMultiFormatView.class);

/**
 * The JasperReport that is used to render the view.
 */
private JasperReport jasperReport;

/**
 * The last modified time of the jrxml resource file, used to force compilation.
 */
private long jrxmlTimestamp;

@Override
protected void onInit() {
    jasperReport = super.getReport();

    try {
        String url = getUrl();
        if (url != null) {
            jrxmlTimestamp = getApplicationContext().getResource(url).getFile().lastModified();
        }
    } catch (Exception e) {
        e = null;
    }
}

@Override
protected JasperReport getReport() {
    if (this.isDirty()) {
        LOG.info("Forcing recompilation of jasper report as the jrxml has changed");
        this.jasperReport = this.loadReport();
    }
    return this.jasperReport;
}

/**
 * Determines if the jrxml file is dirty by checking its timestamp.
 *
 * @return true to force recompilation because the report xml has changed, false otherwise
 */
private boolean isDirty() {
    long curTimestamp = 0L;
    try {
        String url = getUrl();
        if (url != null) {
            curTimestamp = getApplicationContext().getResource(url).getFile().lastModified();
            if (curTimestamp > jrxmlTimestamp) {
                jrxmlTimestamp = curTimestamp;
                return true;
            }
        }
    } catch (Exception e) {
        e = null;
    }
    return false;
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...