Community
Participate
Working Groups
Build Identifier: 2.5.2 We use BIRT report engine API to generate pdf file from report library, but now it can't generate bookmarks in pdf under BIRT2.5.2, it works fine with BIRT2.2.2 in Eclipse3.3.2. I want to know is there any changes in BIRT2.5.2 to generate pdf bookmarks? need I set any options? Thanks, --Alex Our code like below: public void doPresentation(IProgressMonitor monitor){ if(status == IStatus.ERROR) return; IReportDocument doc = null; try { // doc = engine.openReportDocument(docFile); doc = ReportDocument.getInstance(engine, docFile, toc); } catch (EngineException e1) { PublishDocPlugin.getDefault().getLogger().logError(e1); } renderTask = engine.createRenderTask(doc); RenderOption option = new RenderOption(); // option.setOption(PDFRenderOption.FIT_TO_PAGE, true); // option.setOption(PDFRenderOption.PAGEBREAK_PAGINATION_ONLY, false); // option.setOption(PDFRenderOption.HTML_PAGINATION, false); output = options.getOutputFilename(); option.setOutputFileName(output); if(options.getOutputFormat()==PublishDocOptions.OUTPUT_FORMAT_PDF) option.setOutputFormat(IRenderOption.OUTPUT_FORMAT_PDF); else if(options.getOutputFormat()==PublishDocOptions.OUTPUT_FORMAT_MSWORD) option.setOutputFormat("doc"); //$NON-NLS-1$ option.setSupportedImageFormats("JPG;PNG;BMP;SVG"); //$NON-NLS-1$ // option.setOption("htmlPagination", Boolean.TRUE); //$NON-NLS-1$ renderTask.setRenderOption(option); monitor.subTask(PublishingDocResource.renderingReport); renderTask.setAppContext(new HashMap()); Runnable runnable = new Runnable(){ public void run() { try { // Context.enter(); renderTask.render(); // Context.exit(); } catch (EngineException e) { PublishDocPlugin.getDefault().getLogger().logError(e); } } }; Thread th = new Thread(runnable); th.start(); while(renderTask.getStatus()==IEngineTask.STATUS_NOT_STARTED || renderTask.getStatus()==IEngineTask.STATUS_RUNNING){ if(monitor.isCanceled()){ renderTask.cancel(); } try { Thread.sleep(100); } catch (InterruptedException e) { PublishDocPlugin.getDefault().getLogger().logError(e); } } // renderTask.close(); doc.close(); if(renderTask.getStatus()==IEngineTask.STATUS_SUCCEEDED) status = IStatus.OK; renderTask = null; } Reproducible: Always
Could you please attach a sample document which can reproduce this problem?
(In reply to comment #1) > Could you please attach a sample document which can reproduce this problem? 1. This issue may relate to this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=299737 So I want to know is it OK for below replacement? ///////////////////////////////// We use below classes before in our code: 1. org.eclipse.birt.report.engine.toc.TOCTree 2. org.eclipse.birt.report.engine.toc.TOCTreeNode But from we upgrading our product to Eclipse 3.5.1, we found the two above classes are no longer available, after some investigations, we use below classes instead: 1. org.eclipse.birt.report.engine.toc.TOCTree -> org.eclipse.birt.report.engine.toc.TOCView 2. org.eclipse.birt.report.engine.toc.TOCTreeNode -> org.eclipse.birt.report.engine.toc.document.MemTreeNode but org.eclipse.birt.report.engine.toc.document.MemTreeNode isn't be exported, that's why I created this bug. Or maybe you have some other good suggestions? ////////////////////////////////////// 2. We build TOC on the fly, so I can't upload the document to reproduce this issue, you can get the detail from our code: doc = ReportDocument.getInstance(engine, docFile, toc); ////////////////////////////////// public class ReportDocument extends ReportDocumentReader { private TOCView toc; public ReportDocument(IReportEngine engine, IDocArchiveReader archive) throws EngineException { super((ReportEngine) engine, archive); } public static IReportDocument getInstance(IReportEngine engine, String docFile, TOCView toc) throws EngineException{ try { IDocArchiveReader reader = new FileArchiveReader(docFile); ReportDocument reportDoc = new ReportDocument(engine, reader); reportDoc.setToc(toc); return reportDoc; } catch (IOException e) { PublishDocPlugin.getDefault().getLogger().logError(e); return null; } } @Override public ITOCTree getTOCTree(String format, ULocale locale) { if(toc==null) return super.getTOCTree(format, locale); if ( !isComplete( ) ) { return null; } TOCView result = new TOCView((ITreeNode) toc.getRoot( ), ( (ReportRunnable) getReportRunnable( ) ).getReport( ) , locale, null, format); return result; } public void setToc(TOCView toc) { this.toc = toc; } } //////////////////////////////////
If you could, please point me to the BIRT code location where generate the bookmarks, then I can debug it? Thanks much, --Alex
Any updates on this issue? Thanks, --Alex
Alex, Please try to use ITreeNode instead of TOCTreeNode/MemTreeNode to avoid compatibility issue. What do you mean by "build TOC on the fly"? Is there some sample program(runnable for us) to reproduce your problem?
(In reply to comment #5) > Please try to use ITreeNode instead of TOCTreeNode/MemTreeNode to avoid > compatibility issue. ITreeNode is an interface, to build TOC by ourselves, we need a concrete class which implements ITreeNode, right? Previously, we use 1. org.eclipse.birt.report.engine.toc.TOCTree 2. org.eclipse.birt.report.engine.toc.TOCTreeNode But in BIRT 2.5.2, they are gone, so could you please tell me which classes replaced them? > > What do you mean by "build TOC on the fly"? Is there some sample > program(runnable for us) to reproduce your problem? I mean we build TOC by ourselves, instead of let BIRT build it as default. public class ReportTOCBuilder { TreeNode root = null; TOCView tree = null; public ReportTOCBuilder(ReportDesignHandle design){ this.root = new MemTreeNode(); this.tree = new TOCView(root, design, ULocale.getDefault(), null, "" ); //$NON-NLS-1$ // public TOCView( ITreeNode tree, ReportDesignHandle handle, ULocale locale, // TimeZone timeZone, String format ) } public TOCView getTOCTree(){ return this.tree; } public MemTreeNode getRoot(){ return (MemTreeNode)this.root; } public MemTreeNode createNode(MemTreeNode parentNode, String bookmark, Object tocValue){ String id = parentNode.getNodeId( ); if ( id == null ) { id = "__TOC"; //$NON-NLS-1$ } id = id + "_" + parentNode.getChildren( ).size( ); //$NON-NLS-1$ MemTreeNode node = new MemTreeNode(); node.setNodeId( id ); node.setBookmark( bookmark == null ? id : bookmark ); node.setParent( parentNode ); node.setTOCValue(tocValue); parentNode.getChildren( ).add( node ); return node; } } Again, could you point me the location in BIRT engine to generate the pdf bookmarks? Thanks, --Alex
In pdf output, the TOC is generated in org.eclipse.birt.report.engine.emitter.pdf.PDFPageDevice.createTOC(...). It need not any extra options.
1. The TOC tree is generated by TOCBuilder. 2. In PDF, the TOCs are output by PDFPageDevice.createTOC(), bookmarks are output by PDFPage.createBookmark(), both classes are in plugin org.eclipse.birt.report.engine.emitter.pdf. Please notice TOC and bookmark are different. 3. According to my understanding, you create your own TOCBuilder or TOC writer, is that correct? If so, you can just copy the code MemTreeNode and use it as your own class. So that it's not necessary to depends on the class of BIRT and can avoid compatibility issue.
Hi BIRT guys, Seems BIRT changed its API in org.eclipse.birt.report.engine.api.impl.ReportDocumentReader, right now I use org.eclipse.birt.report.engine.api.impl.ReportDocumentReader.getTOCTree() instead of org.eclipse.birt.report.engine.api.impl.ReportDocumentReader.getTOCTree(String, ULocale), then I get right result. synchronized public ITreeNode getTOCTree( ) throws EngineException { if ( !isComplete( ) ) { return null; } return this.treeRoot; } So please resolve this issue, and thanks very much for your kindly help! --Alex
Resolved as "worksforme".