source

봄 부팅 앱에서 BIRT

ittop 2023. 10. 9. 23:34
반응형

봄 부팅 앱에서 BIRT

기존의 스프링부트 웹 애플리케이션에서 보고서 기능(기능)을 작성해야 합니다.그 제안은 봄 부츠 웹 앱과 통합할 수 있는 BIRT를 사용하는 것이었습니다.

저는 아래 기사를 찾았고 (http://start.spring.io/) 를 사용하여) 스프링 부트 스타터 프로젝트에서 보고서를 실행할 수 있었습니다.꽤 오래된 이 기사는 제가 모범을 보이는 데 도움이 되었습니다.https://spring.io/blog/2012/01/30/spring-framework-birt .이 기사는 기본적으로 내가 원하는 것이지만 봄 부츠 웹 앱에서 볼 수 있습니다.

과제는 BIRT 뷰어를 사용하여 보고서를 실행하는 것입니다. BIRT 뷰어는 좋은 부가 기능과 함께 제공됩니다. (인쇄, Expet 데이터, PDF, 페이지화 등)

이 기사에서 설명하는 BIRT를 사용한 스프링 부트 예를 찾을 수 없습니다.

제 질문은 다음과 같습니다.

  1. Spring boot web 응용 프로그램에서 보고서를 수행할 수 있는 대안이나 다른 방법이 있습니까?(BIRT와 같은 기능을 처음부터 만들어 휠을 재발명하거나 가능한 경우 웹 애플리케이션과 별도로 보고서 엔진을 실행하는 것은 분명히 원하지 않습니다.)

  2. 오늘날 봄 부팅 웹 애플리케이션에서 BIRT가 작동하고 있으며 이를 수행하는 가장 좋은 방법에 대해 공유하거나 교육할 의향이 있는 사람이 있습니까?(스프링 부트로 JSP 페이지를 작동시키려고 했지만 성공적으로 작동할 수 없었습니다...다른 무엇보다 경험 부족)

누가 좀 도와주시겠습니까?

잘부탁드립니다, 헨크

의 한 예, ,IReportEngine, 디렉토리는 봄 부팅 웹 애플리케이션에서 BIRT를 설정하는 데 가장 어려운 부분입니다.이 예제는 약간의 오류 처리 기능이 있으며 중요한 디렉토리에 대한 경로를 지정하는 환경 변수에 따라 달라집니다.

이 설정의 한 가지 좋은 점은 보고서를 구축하고 생성하기 위한 독립형 ReST API라는 점입니다.부수적인 이점으로 JSP에 전혀 의존하지 않습니다.

도커 컨테이너에서 작동합니다.

원래는 인터페이스 중 일부를 사용하여 재스퍼 리포트와 같은 다른 보고 프레임워크를 시도할 계획이었습니다.

이것은 당신이 요구하는 것과 정확히 일치하지는 않지만, 제 생각에는 특정한 맥락에서는 더 나은 것 같습니다.BIRT 보고서 러너를 이와 같은 애플리케이션으로 사용, 구성 및 배포할 수 있는 유연성이 매우 높습니다.Actian에서 제공하는 미리 패키지된 BIRT Viewer를 사용하지 않습니다.

birt-report-runner-data라고 하는 보고서를 위한 데이터 컨테이너를 만든 다음 로그 및 보고서를 위한 모든 디렉토리를 해당 컨테이너에 저장하고 BIRT 컨테이너에 마운트할 수 있습니다.

주요 구성요소

기본 파일(BirtReportRunnerApplication.java)

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BirtReportRunnerApplication {

    public static void main(String[] args) {
        SpringApplication.run(BirtReportRunnerApplication.class, args);
    }
}

보고서 요청을 수신할 컨트롤러(ReportController.java)

package com.example.core.web.controller;

import com.example.core.model.BIRTReport;
import com.example.core.service.ReportRunner;
import com.example.core.web.dto.ReportRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController("ReportController")
@RequestMapping("/reports")
public class ReportController {

    private Logger logger = LoggerFactory.getLogger(ReportController.class);

    @Autowired
    @Qualifier("birt")
    ReportRunner reportRunner;

    @RequestMapping(value = "/birt", method = RequestMethod.POST)
    public ResponseEntity<byte[]> getBIRTReport(@RequestBody ReportRequest reportRequest) {
        byte[] reportBytes;
        ResponseEntity<byte[]> responseEntity;
        try {
            logger.info("REPORT REQUEST NAME:   " + reportRequest.getReportName());
            reportBytes =
                new BIRTReport(
                    reportRequest.getReportName(),
                    reportRequest.getReportParameters(),
                    reportRunner)
                    .runReport().getReportContent().toByteArray();

            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.parseMediaType("application/pdf"));
            String fileName = reportRequest.getReportName() + ".pdf";
            httpHeaders.setContentDispositionFormData(fileName, fileName);
            httpHeaders.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            responseEntity = new ResponseEntity<byte[]>(reportBytes, httpHeaders, HttpStatus.OK);
        } catch (Exception e) {
            responseEntity = new ResponseEntity<byte[]>(HttpStatus.NOT_IMPLEMENTED);
            return responseEntity;
        }
        return responseEntity;
    }
}

실행할 보고서를 지정하기 위한 보고서 요청 DTO(ReportRequest.java)

package com.example.core.web.dto;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

public class ReportRequest {
    private String reportName;
    private String reportParameters;

    public ReportRequest(@JsonProperty("reportName") String reportName,
                         @JsonProperty("reportParameters") String reportParameters) {
        this.reportName = reportName;
        this.reportParameters = reportParameters;
    }

    public String getReportName() {
        return reportName;
    }

    public String getReportParameters() {
        return reportParameters;
    }

    public void setReportParameters(String reportParameters) {
        this.reportParameters = reportParameters;
    }
}

Report Runner 인터페이스(ReportRunner.java)

package com.example.core.service;

import com.example.core.model.Report;

import java.io.ByteArrayOutputStream;

public interface ReportRunner {

    ByteArrayOutputStream runReport(Report report);
}

대부분의 작업을 수행하는 최대 클래스(BIRTReportRunner.java)

package com.example.core.service;

import com.example.core.model.Report;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.*;
import org.eclipse.core.internal.registry.RegistryProviderFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

@Service
@Qualifier("birt")
public class BIRTReportRunner implements ReportRunner {
    private static final String DEFAULT_LOGGING_DIRECTORY = "defaultBirtLoggingDirectory/";
    private Logger logger = LoggerFactory.getLogger(BIRTReportRunner.class);

    private static String reportOutputDirectory;

    private IReportEngine birtReportEngine = null;

    @Autowired
    private Environment env;

    /**
     * Starts up and configures the BIRT Report Engine
     */
    @PostConstruct
    public void startUp() {
        if(env.getProperty("birt_report_input_dir") == null)
            throw new RuntimeException("Cannot start application since birt report input directory was not specified.");
        try {
            String birtLoggingDirectory = env.getProperty("birt_logging_directory") == null ? DEFAULT_LOGGING_DIRECTORY : env.getProperty("birt_logging_directory");
            Level birtLoggingLevel = env.getProperty("birt_logging_level") == null ? Level.SEVERE : Level.parse(env.getProperty("birt_logging_level"));
            EngineConfig engineConfig = new EngineConfig();
            logger.info("BIRT LOG DIRECTORY SET TO : {}", birtLoggingDirectory);
            logger.info("BIRT LOGGING LEVEL SET TO {}", birtLoggingLevel);
            engineConfig.setLogConfig(birtLoggingDirectory, birtLoggingLevel);

            // Required due to a bug in BIRT that occurs in calling Startup after the Platform has already been started up
            RegistryProviderFactory.releaseDefault();
            Platform.startup(engineConfig);
            IReportEngineFactory reportEngineFactory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
            birtReportEngine = reportEngineFactory.createReportEngine(engineConfig);
        } catch (BirtException e) {
            // TODO add logging aspect and find out how to log a platform startup problem from this catch block, if possible, using the aspect.
            // Possibly rethrow the exception here and catch it in the aspect.
            logger.error("Birt Startup Error: {}", e.getMessage());
        }

        reportOutputDirectory = env.getProperty("birt_temp_file_output_dir");
    }

    /**
     * Shuts down the BIRT Report Engine
     */
    @PreDestroy
    public void shutdown() {
        birtReportEngine.destroy();
        RegistryProviderFactory.releaseDefault();
        Platform.shutdown();
    }

    public File getReportFromFilesystem(String reportName) throws RuntimeException {
        String reportDirectory = env.getProperty("birt_report_input_dir");
        Path birtReport = Paths.get(reportDirectory + File.separator + reportName + ".rptdesign");
        if(!Files.isReadable(birtReport))
            throw new RuntimeException("Report " + reportName + " either did not exist or was not writable.");

        return birtReport.toFile();
    }

    /**
     * This method creates and executes the report task, the main responsibility
     * of the entire Report Service.
     * This method is key to enabling pagination for the BIRT report. The IRunTask run task
     * is created and then used to generate an ".rptdocument" binary file.
     * This binary file is then read by the separately created IRenderTask render
     * task. The render task renders the binary document as a binary PDF output
     * stream which is then returned from the method.
     * <p>
     *
     * @param birtReport the report object created at the controller to hold the data of the report request.
     * @return Returns a ByteArrayOutputStream of the PDF bytes generated by the
     */
    @Override
    public ByteArrayOutputStream runReport(Report birtReport) {

        ByteArrayOutputStream byteArrayOutputStream;
        File rptDesignFile;

        // get the path to the report design file
        try {
            rptDesignFile = getReportFromFilesystem(birtReport.getName());
        } catch (Exception e) {
            logger.error("Error while loading rptdesign: {}.", e.getMessage());
            throw new RuntimeException("Could not find report");
        }

        // process any additional parameters
        Map<String, String> parsedParameters = parseParametersAsMap(birtReport.getParameters());

        byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            IReportRunnable reportDesign = birtReportEngine.openReportDesign(rptDesignFile.getPath());
            IRunTask runTask = birtReportEngine.createRunTask(reportDesign);

            if (parsedParameters.size() > 0) {
                for (Map.Entry<String, String> entry : parsedParameters.entrySet()) {
                    runTask.setParameterValue(entry.getKey(), entry.getValue());
                }
            }
            runTask.validateParameters();

            String rptdocument = reportOutputDirectory + File.separator
                    + "generated" + File.separator
                    + birtReport.getName() + ".rptdocument";
            runTask.run(rptdocument);

            IReportDocument reportDocument = birtReportEngine.openReportDocument(rptdocument);
            IRenderTask renderTask = birtReportEngine.createRenderTask(reportDocument);

            PDFRenderOption pdfRenderOption = new PDFRenderOption();
            pdfRenderOption.setOption(IPDFRenderOption.REPAGINATE_FOR_PDF, new Boolean(true));
            pdfRenderOption.setOutputFormat("pdf");
            pdfRenderOption.setOutputStream(byteArrayOutputStream);
            renderTask.setRenderOption(pdfRenderOption);

            renderTask.render();
            renderTask.close();
        } catch (EngineException e) {
            logger.error("Error while running report task: {}.", e.getMessage());
            // TODO add custom message to thrown exception
            throw new RuntimeException();
        }

        return byteArrayOutputStream;
    }

    /**
     * Takes a String of parameters started by '?', delimited by '&', and with
     * keys and values split by '=' and returnes a Map of the keys and values
     * in the String.
     *
     * @param reportParameters a String from a HTTP request URL
     * @return a map of parameters with Key,Value entries as strings
     */
    public Map<String, String> parseParametersAsMap(String reportParameters) {
        Map<String, String> parsedParameters = new HashMap<String, String>();
        String[] paramArray;
        if (reportParameters.isEmpty()) {
            throw new IllegalArgumentException("Report parameters cannot be empty");
        } else if (!reportParameters.startsWith("?") && !reportParameters.contains("?")) {
            throw new IllegalArgumentException("Report parameters must start with a question mark '?'!");
        } else {
            String noQuestionMark = reportParameters.substring(1, reportParameters.length());
            paramArray = noQuestionMark.split("&");
            for (String param : paramArray) {
                String[] paramGroup = param.split("=");
                if (paramGroup.length == 2) {
                    parsedParameters.put(paramGroup[0], paramGroup[1]);
                } else {
                    parsedParameters.put(paramGroup[0], "");
                }

            }
        }
        return parsedParameters;
    }
}

Report 개체 클래스(Report.java)

package com.example.core.model;

import com.example.core.service.ReportRunner;

import java.io.ByteArrayOutputStream;
import java.util.List;

/**
 * A Report object has a byte representation of the report output that can be
 * used to write to any output stream. This class is designed around the concept
 * of using ByteArrayOutputStreams to write PDFs to an output stream.
 *
 *
 */
public abstract class Report {

    protected String name;
    protected String parameters;
    protected ByteArrayOutputStream reportContent;
    protected ReportRunner reportRunner;

    public Report(String name, String parameters, ReportRunner reportRunner) {
        this.name = name;
        this.parameters = parameters;
        this.reportRunner = reportRunner;
    }

    /**
     * This is the processing method for a Report. Once the report is ran it
     * populates an internal field with a ByteArrayOutputStream of the
     * report content generated during the run process.
     * @return Returns itself with the report content output stream created.
     */
    public abstract Report runReport();

    public ByteArrayOutputStream getReportContent() {
        return this.reportContent;
    }

    public String getName() {
        return name;
    }

    public String getParameters() {
        return parameters;
    }
}

BIRT 개체 클래스(BIRTReport.java)

package com.example.core.model;

import com.example.core.service.ReportRunner;

public class BIRTReport extends Report {

    public BIRTReport(String name, String reportParameters, ReportRunner reportRunner) {
        super(name, reportParameters, reportRunner);
    }

    @Override
    public Report runReport() {
        this.reportContent = reportRunner.runReport(this);
        return this;
    }
}

빌드 파일(build.gradle)

buildscript {
    ext {
        springBootVersion = '1.3.2.RELEASE'
    }
    repositories {
        jcenter()

    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'com.example.simple-birt-runner'
    version = '1.0.0'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

ext {
    springBootVersion = '1.3.0.M5'
}

repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
    compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")


    // BIRT Runtime and ReportEngine dependencies
    // These were pulled from the Actuate download site at http://download.eclipse.org/birt/downloads/ for version 4.5.0
    compile fileTree(dir: 'lib', include: '*.jar')
    /*compile("org.eclipse.birt.runtime:org.eclipse.birt.runtime:4.4.2") {
        exclude group: "org.eclipse.birt.runtime", module: "org.apache.poi"
        exclude group: "org.eclipse.birt.runtime", module: "org.eclipse.orbit.mongodb"
    }*/

    compile("org.springframework.boot:spring-boot-starter-tomcat")

    // include any runtime JDBC driver dependencies here

    testCompile("org.springframework.boot:spring-boot-starter-test")
}

종속성

Birt Viewer lib 디렉토리에 있는 모든 종속성을 가져와 클래스 경로에 놓습니다.외부 종속성의 전체 목록은 다음과 같습니다.

com.ibm.icu_54.1.1.v201501272100.jar
com.lowagie.text_2.1.7.v201004222200.jar
derby.jar
flute.jar
javax.wsdl_1.5.1.v201012040544.jar
javax.xml.stream_1.0.1.v201004272200.jar
javax.xml_1.3.4.v201005080400.jar
net.sourceforge.lpg.lpgjavaruntime_1.1.0.v201004271650.jar
org.apache.batik.bridge_1.6.0.v201011041432.jar
org.apache.batik.css_1.6.0.v201011041432.jar
org.apache.batik.dom.svg_1.6.0.v201011041432.jar
org.apache.batik.dom_1.6.1.v201505192100.jar
org.apache.batik.ext.awt_1.6.0.v201011041432.jar
org.apache.batik.parser_1.6.0.v201011041432.jar
org.apache.batik.pdf_1.6.0.v201105071520.jar
org.apache.batik.svggen_1.6.0.v201011041432.jar
org.apache.batik.transcoder_1.6.0.v201011041432.jar
org.apache.batik.util.gui_1.6.0.v201011041432.jar
org.apache.batik.util_1.6.0.v201011041432.jar
org.apache.batik.xml_1.6.0.v201011041432.jar
org.apache.commons.codec_1.6.0.v201305230611.jar
org.apache.commons.logging_1.1.1.v201101211721.jar
org.apache.lucene.core_3.5.0.v20120725-1805.jar
org.apache.poi_3.9.0.v201405241750.jar
org.apache.xerces_2.9.0.v201101211617.jar
org.apache.xml.resolver_1.2.0.v201005080400.jar
org.apache.xml.serializer_2.7.1.v201005080400.jar
org.eclipse.birt.runtime_4.5.0.jar
org.eclipse.core.contenttype_3.5.0.v20150421-2214.jar
org.eclipse.core.expressions_3.5.0.v20150421-2214.jar
org.eclipse.core.filesystem_1.5.0.v20150421-0713.jar
org.eclipse.core.jobs_3.7.0.v20150330-2103.jar
org.eclipse.core.resources_3.10.0.v20150423-0755.jar
org.eclipse.core.runtime.compatibility_3.2.300.v20150423-0821.jar
org.eclipse.core.runtime_3.11.0.v20150405-1723.jar
org.eclipse.datatools.connectivity.apache.derby.dbdefinition_1.0.2.v201107221459.jar
org.eclipse.datatools.connectivity.apache.derby_1.0.103.v201212070447.jar
org.eclipse.datatools.connectivity.console.profile_1.0.10.v201109250955.jar
org.eclipse.datatools.connectivity.db.generic_1.0.1.v201107221459.jar
org.eclipse.datatools.connectivity.dbdefinition.genericJDBC_1.0.2.v201310181001.jar
org.eclipse.datatools.connectivity.oda.consumer_3.2.6.v201403131814.jar
org.eclipse.datatools.connectivity.oda.design_3.3.6.v201403131814.jar
org.eclipse.datatools.connectivity.oda.flatfile_3.1.8.v201403010906.jar
org.eclipse.datatools.connectivity.oda.profile_3.2.9.v201403131814.jar
org.eclipse.datatools.connectivity.oda_3.4.3.v201405301249.jar
org.eclipse.datatools.connectivity.sqm.core_1.2.8.v201401230755.jar
org.eclipse.datatools.connectivity_1.2.11.v201401230755.jar
org.eclipse.datatools.enablement.hsqldb.dbdefinition_1.0.0.v201107221502.jar
org.eclipse.datatools.enablement.hsqldb_1.0.0.v201107221502.jar
org.eclipse.datatools.enablement.ibm.db2.iseries.dbdefinition_1.0.3.v201107221502.jar
org.eclipse.datatools.enablement.ibm.db2.iseries_1.0.2.v201107221502.jar
org.eclipse.datatools.enablement.ibm.db2.luw.dbdefinition_1.0.7.v201405302027.jar
org.eclipse.datatools.enablement.ibm.db2.luw_1.0.3.v201401170830.jar
org.eclipse.datatools.enablement.ibm.db2.zseries.dbdefinition_1.0.4.v201107221502.jar
org.eclipse.datatools.enablement.ibm.db2.zseries_1.0.2.v201107221502.jar
org.eclipse.datatools.enablement.ibm.db2_1.0.0.v201401170830.jar
org.eclipse.datatools.enablement.ibm.informix.dbdefinition_1.0.4.v201107221502.jar
org.eclipse.datatools.enablement.ibm.informix_1.0.1.v201107221502.jar
org.eclipse.datatools.enablement.ibm_1.0.0.v201401170830.jar
org.eclipse.datatools.enablement.msft.sqlserver.dbdefinition_1.0.1.v201201240505.jar
org.eclipse.datatools.enablement.msft.sqlserver_1.0.3.v201308161009.jar
org.eclipse.datatools.enablement.mysql.dbdefinition_1.0.4.v201109022331.jar
org.eclipse.datatools.enablement.mysql_1.0.4.v201212120617.jar
org.eclipse.datatools.enablement.oda.ws_1.2.6.v201403131825.jar
org.eclipse.datatools.enablement.oda.xml_1.2.5.v201403131825.jar
org.eclipse.datatools.enablement.oracle.dbdefinition_1.0.103.v201206010214.jar
org.eclipse.datatools.enablement.oracle_1.0.0.v201107221506.jar
org.eclipse.datatools.enablement.postgresql.dbdefinition_1.0.2.v201110070445.jar
org.eclipse.datatools.enablement.postgresql_1.1.1.v201205252207.jar
org.eclipse.datatools.enablement.sap.maxdb.dbdefinition_1.0.0.v201107221507.jar
org.eclipse.datatools.enablement.sap.maxdb_1.0.0.v201107221507.jar
org.eclipse.datatools.modelbase.dbdefinition_1.0.2.v201107221519.jar
org.eclipse.datatools.modelbase.derby_1.0.0.v201107221519.jar
org.eclipse.datatools.modelbase.sql.query_1.1.4.v201212120619.jar
org.eclipse.datatools.modelbase.sql_1.0.6.v201208230744.jar
org.eclipse.datatools.sqltools.data.core_1.2.3.v201212120623.jar
org.eclipse.datatools.sqltools.parsers.sql.lexer_1.0.1.v201107221520.jar
org.eclipse.datatools.sqltools.parsers.sql.query_1.2.1.v201201250511.jar
org.eclipse.datatools.sqltools.parsers.sql_1.0.2.v201107221520.jar
org.eclipse.datatools.sqltools.result_1.1.6.v201402080246.jar
org.eclipse.emf.common_2.11.0.v20150512-0501.jar
org.eclipse.emf.ecore.change_2.11.0.v20150512-0501.jar
org.eclipse.emf.ecore.xmi_2.11.0.v20150512-0501.jar
org.eclipse.emf.ecore_2.11.0.v20150512-0501.jar
org.eclipse.equinox.app_1.3.300.v20150423-1356.jar
org.eclipse.equinox.common_3.7.0.v20150402-1709.jar
org.eclipse.equinox.preferences_3.5.300.v20150408-1437.jar
org.eclipse.equinox.registry_3.6.0.v20150318-1503.jar
org.eclipse.help_3.6.0.v20130326-1254.jar
org.eclipse.osgi.services_3.5.0.v20150519-2006.jar
org.eclipse.osgi_3.10.100.v20150529-1857.jar
org.eclipse.update.configurator_3.3.300.v20140518-1928.jar
org.mozilla.javascript_1.7.5.v201504281450.jar
org.w3c.css.sac_1.3.1.v200903091627.jar
org.w3c.dom.events_3.0.0.draft20060413_v201105210656.jar
org.w3c.dom.smil_1.0.1.v200903091627.jar
org.w3c.dom.svg_1.1.0.v201011041433.jar

응용프로그램 속성(application.yml)

birt:
  report:
    output:
      dir: ${birt_temp_file_output_dir}
    input:
      dir: ${birt_report_input_dir}
  logging:
    level: ${birt_logging_level}


server:
  port: 8080
  context-path: /simple-birt-runner


birt:
  logging:
    level: SEVERE

logging:
  level:
    org:
      springframework:
        web: ERROR

실행을 위한 Docker 파일(Docker 파일

FROM java:openjdk-8u66-jre
MAINTAINER Kent O. Johnson <kentoj@gmail.com>

COPY com.example.simple-birt-runner-*.jar /opt/soft/simple-birt-runner.jar

RUN mkdir -p /reports/input \
    && mkdir /reports/output \
    && mkdir -p /reports/log/engine

WORKDIR /opt/soft

CMD java -jar -Xms128M -Xmx4G simple-birt-runner.jar

EXPOSE 8080

이미지 실행을 위한 도커 작성 파일(docker-compose.yml)

simple-birt-runner:
  image: soft/simple-birt-runner-release
  ports:
  - "8090:8080"
  environment:
  - birt_temp_file_output_dir=/reports/output
  - birt_report_input_dir=/reports/input
  - birt_logging_directory=/reports/log/engine
  - birt_logging_level=SEVERE
  volumes_from:
  - birt-report-runner-data

@Kent Johnson의 답변에 대하여.그라들로 프로젝트를 구성하지는 못했지만, 메이븐으로 프로젝트를 구성할 수 있었습니다.아래는 pom.xml 입니다.

    <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>birt-runner</groupId>
<artifactId>com.example.simple-birt-runner</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <!--<scope>provided</scope>-->
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.eclipse.birt.runtime/org.eclipse.birt.runtime -->
    <dependency>
        <groupId>org.eclipse.birt.runtime</groupId>
        <artifactId>org.eclipse.birt.runtime</artifactId>
        <version>4.2.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>



</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Birt Report를 Spring Boot와 함께 사용하기 위해 API를 만들었습니다.이를 사용하려면 새 보고서를 작성하고 올바른 매개 변수를 보내 호출하면 됩니다.링크: https://github.com/devStraub/BirtAPI

코드:

@RestController
@SpringBootApplication
public class BirtReportApplication {

@Value("${reports.relative.path}")
private String reportsPath;
@Value("${images.relative.path}")
private String imagesPath;  
@Value("${temp.files.path}")
private String tempPath;      

private ApplicationContext context;

public static void main(String[] args) {
    SpringApplication.run(BirtReportApplication.class, args);
}

@SuppressWarnings("unchecked")
@PostMapping("/report")
public ResponseEntity<byte[]> generateReport(@RequestBody String json) {
    try {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, String> parametersMap = objectMapper.readValue(json, Map.class);            
        
        EngineConfig config = new EngineConfig();
        config.getAppContext().put("spring", this.context);
        Platform.startup(config);
        IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
        IReportEngine engine = factory.createReportEngine(config);

        IReportRunnable report = engine.openReportDesign(reportsPath + parametersMap.get("report") + ".rptdesign");

        IRunAndRenderTask task = engine.createRunAndRenderTask(report);
        for (Entry<String, String> parametro : parametersMap.entrySet()) {
            task.setParameterValue(parametro.getKey(), parametro.getValue());
        }

        String reportFileName = tempPath + Calendar.getInstance().getTimeInMillis() + ".pdf";
        
        PDFRenderOption options = new PDFRenderOption();
        options.setOutputFormat("pdf");
        options.setOutputFileName(reportFileName);
        task.setRenderOption(options);
        task.run();
        task.close();           

        byte[] relatorioBytes = Files.readAllBytes(Paths.get(reportFileName));

        Files.deleteIfExists(Paths.get(reportFileName));

        return ResponseEntity.ok()
                .header("Content-Type", "application/pdf")
                .body(relatorioBytes);
    } catch (Exception e) {
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }
}

}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.0</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.birt2</groupId>
<artifactId>birt2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
    <java.version>17</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.innoventsolutions.birt.runtime</groupId>
        <artifactId>org.eclipse.birt.runtime_4.8.0-20180626</artifactId>
        <version>4.8.0</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.12.4</version>
    </dependency>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

application.properties:

# Report Properties
reports.relative.path=reports/
images.relative.path=images/

# Temp Files
temp.files.path=temp/

# Postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=****

보고서의 XML 원본을 열고 "version" 속성(2행)을 "3.2.23"으로 수정해야 합니다.이렇게 하지 않으면 보고서에 오류가 표시됩니다.저는 아직도 이 문제를 해결하기 위해 노력하고 있습니다. 보고서 버전을 어떻게 설정할지에 대한 아이디어가 있는 사람이 있다면 좋을 것 같습니다.

내가 도와주고 싶었다.내 연락처: https://devstraub.github.io/myPage/

언급URL : https://stackoverflow.com/questions/32069938/birt-in-spring-boot-app

반응형