BIRT 一般是可以通过单独部署一个Webviewer的工程来处理客户的report查看请求.但是有些需求可能是根据业务规则定制查询条件生成report,然后定期生成report放在数据库里,供客户查询或是report通过邮件发给客户。
开发一个report,内容显示车辆的年份,型号,厂商。数据如下
static List 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 ) ;
}
下载download birt开发工具 http://download.eclipse.org/birt/downloads 选All in one,安装后打开BIRT.exe
File->new->New Report , 新建立一个report,命名为Car.rptdesign
在Outline里找到Data set,新建DataSet,在OutPut columns填入
在Outline里找到Data source,新键DataSource,在下拉框里选Scripted Data Source
,Scripted Data Source
是指通过script来获取到数据源。
在Outline里找到刚刚建立Data set,双击找到DataSource,关联上刚刚建立的DataSource。Data set 是指从DataSource来组装出需要的数据集合。
例如:
DataSource 返回
userId | firstname | lastname |
---|---|---|
1 | zhang | san |
2 | Li | si |
Data set 则组装成
userId | name |
---|---|
1 | zhang san |
2 | Li si |
在Outline里找到Report Parameters,新建立一个参数为year,Data type为String,Display type为Text Box
在Outline里找到Body,在Outline里找到Rport Items里,拖动一个Table到右侧的layout里,会自动弹出对话框,DataSet选刚才的建立的DataSet,选中binding columns
预览report,可以在birt里选window->preference->web browser,勾上use external web browser ,在下面的选项框里选你的浏览器。然后在工具栏里选择播放标志的下拉选
view report as html
或其它的选项
到这里一个简单的Report就建立好了
Scripted Data Source
,不要默认选第一个,第一个是Cassandra Scrpted Data Source
.就需要加入这个包。
org.eclipse.birt.runtime
org.eclipse.birt.runtime
4.4.2
org.eclipse.birt.runtime
org.eclipse.orbit.mongodb
public class BirtEngineFactory implements FactoryBean, 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 ;
}
}
public class BirtConfiguration {
@Value("${birt.log.location}")
String logLocation;
//产生FactoryBean
//在使用的依赖IReportEngine注入时候会调用到
@Bean
protected BirtEngineFactory engine(){
BirtEngineFactory factory = new BirtEngineFactory() ;
//Enable BIRT Engine Logging
factory.setLogLevel( Level.INFO);
factory.setLogDirectory( new FileSystemResource(logLocation));
return factory ;
}
}
通过http//127.0.0.1/report/car/{searchBy}/{seachValue} 来生成car report,url中的占位符代表查询的条件和值
@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());
}
}
}
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 setParameters(IReportRunnable report, Map m) throws Exception {
HashMap parms = new HashMap();
IGetParameterDefinitionTask task = birtEngine.createGetParameterDefinitionTask(report);
//拿到birt里所有的parameter定义
Collection params = task.getParameterDefns(true);
Iterator 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工程里的代码
spring=reportContext.getAppContext().get("spring");
var carService=spring.getBean("carService");
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;
@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/
最后再放上github代码