关于编写viewer,关键在于使用ReportEngine API,这里将几个主要环节总结一下:
- 启动ReportEngine 这里需要注意启动ReportEngine的开销问题和图片链的协议的问题。使用 IReportEngineFactory比每次new一个出来性能方面要好很多。使用HTMLEmitterConfig可以使得生成的HTML报表中的图片的src指向一个web资源而非file资源。
public IReportEngine getEngine() ... { try ... { if (platformContext == null ) ... { platformContext = new PlatformServletContext(servletContext); } engineConfig = new EngineConfig(); engineConfig.setEngineHome( servletContext.getRealPath( " /WEB-INF/platform/ " )); // 要求ENGINE HOME 位于WEB-INF/Platform engineConfig.setPlatformContext(platformContext); // This call sets the Log directory name and level engineConfig.setLogConfig(getLogDir(), Level.FINE); // 设置Emitter,渲染HTML的时候,image的地址是HTTP协议而不是File协议 HTMLEmitterConfig emitterConfig = new HTMLEmitterConfig( ); emitterConfig.setActionHandler( new HTMLActionHandler()); HTMLServerImageHandler imageHandler = new HTMLServerImageHandler(); emitterConfig.setImageHandler(imageHandler); engineConfig.getEmitterConfigs().put( " html " , emitterConfig); // 设置日志level engineConfig.setLogConfig(getLogDir(), Level.WARNING); // 启动Platform,创建ReportEngine Platform.startup(engineConfig); IReportEngineFactory factory = (IReportEngineFactory) Platform .createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY); engine = factory.createReportEngine(engineConfig); engine.changeLogLevel(Level.WARNING); log.debug( " A new engine startup. " ); } catch (BirtException e) ... { e.printStackTrace(); } return engine; } - 运行报表 我理解为编译报表文件。BIRT在渲染报表之前,要将报表编译为.rptdocument,再根据这个文件将报表渲染为HTML格式或PDF格式。编译报表使用IRunTask:
protected void run(String rptDesign) ... { assert (context != null ); IReportEngine engine = context.getEngine(); // Open a report design IReportRunnable design = null ; try ... { design = engine.openReportDesign(context .getFullRptDesignFilename(rptDesign)); // Create task to run the report - use the task to // execute the report and save to disk. IRunTask task = engine.createRunTask(design); String doc = context.getFullRptDocumentFilename(rptDesign); // run the report and destroy the engine task.run(doc); log.debug( " save rpt design to " + doc); task.close(); } catch (EngineException e) ... { e.printStackTrace(); } } - 渲染报表 BIRT支持HTML格式和PDF格式,这两种报表生成的过程相同,只是设置不同的RenderContext和RenderOptions。我们把相同的部分提取为父类的公共方法,不同的部分留给子类实现:
IReportDocument iReportDocument = engine.openReportDocument(docFilename); // Create Render Task IRenderTask task = engine.createRenderTask(iReportDocument); task.addScriptableJavaObject( " jsBirtObject " , getScriptableObject(scriptObj)); if (params != null && ! params.isEmpty()) ... { task.setParameterValues(params); } setRenderContext(task); // 设置Render Context,具体由子类实现 setRenderOptions(task, out); // 设置Render Options,具体由子类实现 task.render(); task.close(); } catch (EngineException e) ... { e.printStackTrace(); } finally ... { engine.shutdown(); } - 渲染PDF和HTML报表
- PDF
/** */ /** * @see AbstractBirtReportParser#setRenderContext(IRenderTask) */ @Override protected void setRenderContext(IRenderTask task) ... { PDFRenderContext renderContext = new PDFRenderContext(); renderContext.setEmbededFont( true ); HashMap contextMap = new HashMap(); contextMap.put( EngineConstants.APPCONTEXT_PDF_RENDER_CONTEXT, renderContext); task.setAppContext( contextMap ); } /** */ /** * @see AbstractBirtReportParser#setRenderOptions(IRenderTask, OutputStream) */ @Override protected void setRenderOptions(IRenderTask task, OutputStream out) ... { RenderOptionBase options = new RenderOptionBase(); options.setOutputStream(out); options.setOutputFormat(RenderOptionBase.OUTPUT_FORMAT_PDF); task.setRenderOption(options); } - HTML 我们要生成一个HTML的一部分,而非包含<html/>标记的完整的HTML文档
/** */ /** * @see AbstractBirtReportParser#setRenderContext(IRenderTask) */ @Override protected void setRenderContext(IRenderTask task) ... { HTMLRenderContext renderContext = new HTMLRenderContext(); renderContext.setBaseURL(context.getBaseURL()); // You must define HTMLServerImageHandler to use a URL renderContext.setBaseImageURL(context.getBaseImageURL()); // renderContext.setImageDirectory("myimages"); renderContext.setImageDirectory(context.getImageDirectory()); renderContext.setSupportedImageFormats( " JPG;PNG " ); HashMap contextMap = new HashMap(); contextMap.put( EngineConstants.APPCONTEXT_HTML_RENDER_CONTEXT, renderContext); task.setAppContext( contextMap ); } /** */ /** * @see AbstractBirtReportParser#setRenderOptions(oIRenderTask, OutputStream) */ @Override protected void setRenderOptions(IRenderTask task, OutputStream out) ... { HTMLRenderOption options = new HTMLRenderOption(); options.setOutputStream(out); options.setEmbeddable( true ); task.setRenderOption(options); }