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
-
Download download birt development tools http://download.eclipse.org/birt/downloads selected All in one, after installation open BIRT.exe
-
File-> new-> New Report, establishment of a new report, named Car.rptdesign
-
Data set found in the Outline, the new DataSet, fill in OutPut columns
- Year type选Interger
- model type选String
- make type选String
-
Data source found in the Outline, the new key DataSource, choose the drop-down box
Scripted Data Source
,Scripted Data Source
it refers to the data source to get through the script. -
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 |
-
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
-
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 html
or other options
Here a simple Report should be established,
- Code github , the control can be downloaded appreciated java project below
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 chooseScripted Data Source
, not the default option the first one, the first one isCassandra 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;
}
-
Birt里建立的Car.rptdesign这个文件放到java工程的resouces/report里
-
整体流程
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工程里的代码
- 在Birt里打开Car.rptdesign,在Outline里找到Scripts,点Car.rptdesign,然后在右边的窗口里切换到script,在左上放的script下来里找达到initialize,然后输入以下代码
spring=reportContext.getAppContext().get("spring");
var carService=spring.getBean("carService");
如图
- 在Birt里打开Car.rptdesign,在Outline里找到dataset,然后在右边的窗口里切换到script,在左上的script下来里找到open,然后输入以下代码
var carService=spring.getBean("carService");
listdata=carService.getCarsByYear(params["year"]);
count=0;
如图
在左上的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;
如图
运行
通过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/
参考文档
- https://spring.io/blog/2012/01/30/spring-framework-birt
- https://www.eclipse.org/birt/documentation/integrating/reapi.php
- https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-with-mock-environment
Finally put on github Code