SpringBoot integrated Birt

Disclaimer: This article is a blogger original article, welcome to reprint. https://blog.csdn.net/guo_xl/article/details/86080466

demand

BIRT is generally possible to process customer requests to view the report by deploying a Webviewer project alone, but some demand may be customized query based on business rules generate a report, and then schedule a report on the database for customer inquiries via e-mail or report to the customer.

aims

  • The resulting report as a PDF, on the hard disk
  • parameters may be received report
  • report calls Javacode to get the data set

Sample - car report

Develop a report, the contents of the display vehicle year, model, manufacturer. Data are as follows

    static List<Car> cars;
	static{
		Car car1 = new Car();
		car1.setYear("2000");
		car1.setMake("Chevrolet");
		car1.setModel("Corvette");
		Car car2 = new Car();
		car2.setYear("2005");
		car2.setMake("Dodge");
		car2.setModel("Viper");
		Car car3 = new Car();
		car3.setYear("2002");
		car3.setMake("Ford");
		car3.setModel("Mustang GT");
		cars = Arrays.asList(  car1, car2, car3 ) ;
	}

step

  1. Download download birt development tools http://download.eclipse.org/birt/downloads selected All in one, after installation open BIRT.exe

  2. File-> new-> New Report, establishment of a new report, named Car.rptdesign

  3. Data set found in the Outline, the new DataSet, fill in OutPut columns

  • Year type选Interger
  • model type选String
  • make type选String
  1. Data source found in the Outline, the new key DataSource, choose the drop-down box Scripted Data Source, Scripted Data Sourceit refers to the data source to get through the script.

  2. Outline find in the newly established Data set, double-click to find DataSource, DataSource on the newly established association. DataSource Data set refers to the assembled collection of data needed.
    E.g:

DataSource return

userId firstname lastname
1 zhang san
2 At the and

Data set is assembled into

userId name
1 zhang san
2 you
  1. Report Parameters found in the Outline, the establishment of a new parameter for the year, Data type is String, Display type for the Text Box
    Here Insert Picture Description

  2. Body found in Outline, find Rport Items in the Outline, the drag a Table layout to the right side, the box will automatically pop up, choose DataSet DataSet just created, select the binding columns

Preview report, you can choose the birt in window-> preference-> web browser, hook use external web browser, the following options box choose your browser. Then select the drop-down option play flag in the toolbar view report as htmlor other options

Here a simple Report should be established,

  1. Code github , the control can be downloaded appreciated java project below
    Here Insert Picture Description
    the necessary code is as follows:
  • pom.xml
    Note
    a) org.eclipse.birt.runtime: org.eclipse.orbit.mongodb ruled out, otherwise it will start being given
    b) join org.hectorclient:. hector-core when creating Datasource in Birt, a drop-down box to choose Scripted Data Source, not the default option the first one, the first one is Cassandra Scrpted Data Source. I need to join the pack.
<dependency>
	<groupId>org.eclipse.birt.runtime</groupId>
	<artifactId>org.eclipse.birt.runtime</artifactId>
	<version>4.4.2</version>
	<exclusions>
        <exclusion>
            <groupId>org.eclipse.birt.runtime</groupId>
            <artifactId>org.eclipse.orbit.mongodb</artifactId>
        </exclusion>
	</exclusions>
</dependency>
  • BirtEngineFactory
public class BirtEngineFactory implements FactoryBean<IReportEngine>, ApplicationContextAware, DisposableBean {   public IReportEngine getObject(){ 

		EngineConfig config = new EngineConfig();
		
		//config.getAppContext()是个map
		//将ApplicationContext放到map里,key为pring
		config.getAppContext().put("spring", this.context );
		config.setLogConfig( null != this._resolvedDirectory ? this._resolvedDirectory.getAbsolutePath() : null  , this.logLevel);
		try {
			Platform.startup( config );
		}
		catch ( BirtException e ) {
			throw new RuntimeException ( "Could not start the Birt engine!", e) ;
		}

		IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY );
		IReportEngine be = factory.createReportEngine( config );
		this.birtEngine = be ; 
		return be ;
	} 
}
  • BirtConfiguration
public class BirtConfiguration {
	@Value("${birt.log.location}")
	String logLocation;

    //产生FactoryBean<IReportEngine>
    //在使用的依赖IReportEngine注入时候会调用到
	@Bean
	protected BirtEngineFactory engine(){ 
		BirtEngineFactory factory = new BirtEngineFactory() ;  
		//Enable BIRT Engine Logging
		factory.setLogLevel( Level.INFO);
		factory.setLogDirectory( new FileSystemResource(logLocation));
		return factory ; 
	}
}
  • BirtController

Car report is generated by http // 127.0.0.1 / report / car / {searchBy} / {seachValue}, url placeholder in the query conditions and values


@RestController
public class BirtController {
    @Autowired
    BirtReportGenerator birtReportGenerator;

    Logger logger = LoggerFactory.getLogger(BirtController.class);

    @PostMapping("/report/car/{searchBy}/{seachValue}")
    public void test(@PathVariable("searchBy") String searchBy,@PathVariable("seachValue") String searchValue){
        ReportParameter rm=new ReportParameter("car","PDF");
        rm.setParameter(searchBy, searchValue);
        try {
            ByteArrayOutputStream baos=birtReportGenerator.generate(rm);
            FileOutputStream fops = new FileOutputStream("c:/test/carreport_"+System.currentTimeMillis()+".pdf");
            fops.write(baos.toByteArray());
            fops.close();
            baos.close();
        } catch (Exception e) {
            logger.error("Error: " + e.getMessage());
        }
    }
}
  • BirtReportGenerator
public class BirtReportGenerator {
    @Autowired
    private IReportEngine birtEngine ;

    public ByteArrayOutputStream generate(ReportParameter rptParam) throws Exception{
        //ByteArrayOutputStream 底层维护了一个byte[],可以自动扩容
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        IReportRunnable runnable = null;
       ClassPathResource cpr=new ClassPathResource("report/car.rptdesign");
        runnable = birtEngine
                .openReportDesign(cpr.getInputStream());
        IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(runnable);
        runAndRenderTask.setParameterValues(setParameters(runnable, rptParam.getParameter()));

        IRenderOption options =new RenderOption();
        if (rptParam.getFormat().equalsIgnoreCase("pdf")) {
            PDFRenderOption pdfOptions = new PDFRenderOption(options);
            pdfOptions.setOutputFormat("pdf");
            pdfOptions.setOption(IPDFRenderOption.PAGE_OVERFLOW, IPDFRenderOption.FIT_TO_PAGE_SIZE);
            pdfOptions.setOutputStream(baos);
            runAndRenderTask.setRenderOption(pdfOptions);
        }
        runAndRenderTask.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY,
                this.getClass().getClassLoader());
        runAndRenderTask.run();
        runAndRenderTask.close();
        return baos;
    }


    protected HashMap<String, Object> setParameters(IReportRunnable report, Map<String,Object> m) throws Exception {

        HashMap<String, Object> parms = new HashMap<String, Object>();
      
        IGetParameterDefinitionTask task = birtEngine.createGetParameterDefinitionTask(report);
        //拿到birt里所有的parameter定义
        Collection<IParameterDefnBase> params = task.getParameterDefns(true);
        Iterator<IParameterDefnBase> iter = params.iterator();
        while (iter.hasNext()) {
            IParameterDefnBase param = (IParameterDefnBase) iter.next();
            Object val=m.get(param.getName());
            //如果拿到birt的parameter有定义
            if (val!=null) {
                parms.put(param.getName(),val);
            }
        }
        task.close();
        return parms;
    }
  1. Birt里建立的Car.rptdesign这个文件放到java工程的resouces/report里

  2. 整体流程

http//127.0.0.1/report/car/year/2000->
BirtController->BirtReportGenerator->IReportEngine

IReportEngine在factorybean里的getObject()里就将spring的applicationContext对象放到了IReportEngine的config里,代码

EngineConfig config = new EngineConfig();
config.getAppContext().put("spring", this.context );

而这个context是可以在Car.rptdesign的script里使用的

以下介绍Birt的script调用java工程里的代码

  1. 在Birt里打开Car.rptdesign,在Outline里找到Scripts,点Car.rptdesign,然后在右边的窗口里切换到script,在左上放的script下来里找达到initialize,然后输入以下代码
spring=reportContext.getAppContext().get("spring");
var carService=spring.getBean("carService");

如图
Here Insert Picture Description

  1. 在Birt里打开Car.rptdesign,在Outline里找到dataset,然后在右边的窗口里切换到script,在左上的script下来里找到open,然后输入以下代码
var carService=spring.getBean("carService");
listdata=carService.getCarsByYear(params["year"]);
count=0;

如图
Here Insert Picture Description

在左上的script下来里找到fetch,然后输入以下代码

count=0;
if (listdata.size()>count) {
car=listdata.get(count);
row.year=car.getYear();
row.mode=car.getMode();
row.make=car.getMake();
count++;
return true;
}
return false;

如图
Here Insert Picture Description

运行

通过postman来测试
  • 启动Bootstrap工程
  • 代开postman,输入http://127.0.0.1:8080/report/car/year/2000
  • 查看c:/test/ 下会生产carreport_xxxxx.pdf
通过springtest测试
  • 在src/main/test里增加一个测试类
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class DemoApplicationTests {
    @Autowired
    private MockMvc mvc;
    @Test
    public void exampleTest() throws Exception {
        this.mvc.perform(post("/report/car/year/2000")).andExpect(status().isOk())
                .andExpect(content().string("Hello World"));
    }
}

发生异常排除

查看log,log 配置在application.properties里的birt.log.location=c:/logs/

参考文档

Finally put on github Code

Guess you like

Origin blog.csdn.net/guo_xl/article/details/86080466
Recommended