Hi there,
I'm using apache.camel as an event listener, when an XML file is dropped into a directoy camel will call a Java processor method that pulls out an ID from the XML and passes it on to my DocGenerator that uses Birt. I need the DocGenerator to return a File to the processor so that camel can send it to another process.
Is there a way for Birt to not create a physical file in the file system? It would be convenient if I could keep it in memory the whole time.
I know that a File is a physical representation of the file system so I need to think of something else.
Thanks so much for your help and please let me know if I left out any info you need.
Camel code:
<route>
<description>Generate Report</description>
<from uri="file:C:\dir\to\watch\"/>
<setHeader headerName="reportPath">
<constant>C:\path\to\report\report.rptdesign</constant>
</setHeader>
<bean ref="processor" method="generateDocument"/>
</route>
Processor code:
public void generateDocument(Exchange exchange)
{
processorLogger.debug("-------------------- Generating PDF Document from Report --------------------");
Element root = exchangeToElement(exchange);
String reportPath = exchange.getIn().getHeaders().get("reportPath").toString();
String id = null;
List<Element> updatedItems = root.getChildren();
for (Element item : updatedItems) {
if (item.getAttribute("name").equals("id")) {
id = item.getChild("new").getValue();
break;
}
}
// call birt report with id, return PDF doc generated by birt
DocGenerator generator = new DocGenerator();
File pdfDoc = generator.createDoc(id, reportPath);
// update exchage with pdfDoc
}
DocGenerator code:
public class DocGenerator {
private IReportEngine engine;
public DocGenerator() {
try {
EngineConfig config = new EngineConfig();
Platform.startup(config);
IReportEngineFactory factory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
engine = factory.createReportEngine(config);
System.out.println("Birt report engine is up and running.");
} catch (Exception ex) {
System.out.println("Error instantiating the DocGenerator class");
ex.printStackTrace();
}
}
public void close() {
// destroy the engine.
try {
engine.destroy();
Platform.shutdown();
RegistryProviderFactory.releaseDefault();
} catch (Exception e) {
// Ignore
}
}
public File createDoc(String id, String reportPath) {
String output = null;
try {
IReportRunnable report = engine.openReportDesign(reportPath);
IRunAndRenderTask task = engine.createRunAndRenderTask(report);
ByteArrayOutputStream oStream = new ByteArrayOutputStream();
HashMap parameters = new HashMap();
parameters.put("id", id);
// this method is not included, but it assigns the id to the birt report parameter, this works fine.
setTaskParameters(report, task, parameters);
PDFRenderOption pdfOptions = new PDFRenderOption();
pdfOptions.setOutputStream(oStream);
// pdfOptions.setOutputFileName(fullDesiredFilePath);
pdfOptions.setEmbededFont(false);
pdfOptions.setOutputFormat("pdf");
task.setRenderOption(pdfOptions);
// save doc in memory, don't write it to file system
task.run();
task.close();
output = oStream.toString();
// this is what I have so far but I'm obviously working in the wrong direction since this still creates a file in the file system.
// I was thinking of creating a temporary File using the OutputStream because I still have the oStream in memory at this point
File temp = File.createTempFile("birt-pdf", ".pdf");
temp.deleteOnExit();
BufferedWriter out = new BufferedWriter(new FileWriter(temp));
out.write(output);
out.close();
return temp;
} catch (EngineException | IOException ex) {
ex.printStackTrace();
}
}
}
Eclipse: Kepler (build: 20130614-0229)
JDK: jdk1.7.0_80
Birt: 4.5.0
camel-core: 2.15.2