问题
I am trying to configure birt report in a spring boot applications, the client is an angular 2 application, here is where I run the report:
@PostConstruct
public void startUp() {
if(inputDir == null)
throw new RuntimeException("Cannot start application since birt report input directory was not specified.");
try {
EngineConfig engineConfig = new EngineConfig();
engineConfig.getAppContext().put("spring", this.context);
RegistryProviderFactory.releaseDefault();
Platform.startup(engineConfig);
IReportEngineFactory reportEngineFactory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
birtReportEngine = reportEngineFactory.createReportEngine(engineConfig);
} catch (BirtException e) {
}
reportOutputDirectory = env.getProperty("birt_temp_file_output_dir");
}
@Override
public ByteArrayOutputStream runReport(Report birtReport) {
ByteArrayOutputStream byteArrayOutputStream;
File rptDesignFile;
try {
rptDesignFile = getReportFromFilesystem(birtReport.getName());
} catch (Exception e) {
throw new RuntimeException("Could not find report");
}
Map<String, String> parsedParameters = parseParametersAsMap(birtReport.getParameters());
byteArrayOutputStream = new ByteArrayOutputStream();
try {
IReportRunnable reportDesign = birtReportEngine.openReportDesign(rptDesignFile.getPath());
IRunTask runTask = birtReportEngine.createRunTask(reportDesign);
if (parsedParameters.size() > 0) {
for (Map.Entry<String, String> entry : parsedParameters.entrySet()) {
runTask.setParameterValue(entry.getKey(), entry.getValue());
}
}
runTask.validateParameters();
String rptdocument = reportOutputDirectory + File.separator
+ "generated" + File.separator
+ birtReport.getName() + ".rptdocument";
runTask.run(rptdocument);
IReportDocument reportDocument = birtReportEngine.openReportDocument(rptdocument);
IRenderTask renderTask = birtReportEngine.createRenderTask(reportDocument);
PDFRenderOption pdfRenderOption = new PDFRenderOption();
pdfRenderOption.setOption(IPDFRenderOption.REPAGINATE_FOR_PDF, new Boolean(true));
pdfRenderOption.setOption(IPDFRenderOption.PAGE_OVERFLOW, IPDFRenderOption.OUTPUT_TO_MULTIPLE_PAGES );
pdfRenderOption.setOption(IPDFRenderOption.PDF_TEXT_WRAPPING , true);
pdfRenderOption.setOption(IPDFRenderOption.PDF_HYPHENATION , true);
pdfRenderOption.setOutputFormat("pdf");
pdfRenderOption.setOutputStream(byteArrayOutputStream);
renderTask.setRenderOption(pdfRenderOption);
renderTask.render();
renderTask.close();
} catch (EngineException e) {
throw new RuntimeException();
}
return byteArrayOutputStream;
}
and this is the api service that returns the byte array:
@RequestMapping(value = "/birt", method = RequestMethod.POST)
public ResponseEntity<byte[]> getBIRTReport(@RequestBody ReportRequest reportRequest) {
byte[] reportBytes;
ResponseEntity<byte[]> responseEntity;
try {
reportBytes =
new BIRTReport(
reportRequest.getReportName(),
reportRequest.getReportParameters(),
reportRunner)
.runReport().getReportContent().toByteArray();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaType("application/pdf"));
String fileName = reportRequest.getReportName() + ".pdf";
httpHeaders.setContentDispositionFormData(fileName, fileName);
httpHeaders.setCacheControl("must-revalidate, post-check=0, pre-check=0");
responseEntity = new ResponseEntity<byte[]>(reportBytes, httpHeaders, HttpStatus.OK);
} catch (Exception e) {
responseEntity = new ResponseEntity<byte[]>(HttpStatus.NOT_IMPLEMENTED);
return responseEntity;
}
return responseEntity;
}
and that is the angular 2 code:
public getReport():Observable<any>{
let params = {
"reportName":"my report name",
"reportParameters":"my params"
};
let headers = new Headers();
headers.append('Content-Type','application/json');
let options = new RequestOptions({headers: headers});
return this.http.post("http://localhost:8080/reports/birt",JSON.stringify(params), options);
}
call the service:
getReport(){
this.reportService.getReport().subscribe(
data => {
var blob = new Blob([data._body], { type: 'application/pdf'})
saveAs(blob, "myPdf.pdf");
var fileUrl = URL.createObjectURL(blob);
window.open(fileUrl);
}
)
}
This method returns a corrupt file, can anyone figure out the problem?
回答1:
The problem is that you are missing responseType in options
let options = new RequestOptions({headers: headers, **responseType: ResponseContentType.Blob**});
After that you can just do
window['saveAs'](response.blob(), 'filename.zip');
来源:https://stackoverflow.com/questions/40024461/spring-boot-birt-report-with-angular-2-client-generates-corrupt-pdf-file