使用Angular 2客户端的Spring启动Birt报告生成损坏的PDF文件

我试图在spring启动应用程序中配置birt报告,客户端是一个角度2应用程序,这是我运行报告的地方:

@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 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 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; } 

这是返回字节数组的api服务:

 @RequestMapping(value = "/birt", method = RequestMethod.POST) public ResponseEntity getBIRTReport(@RequestBody ReportRequest reportRequest) { byte[] reportBytes; ResponseEntity 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(reportBytes, httpHeaders, HttpStatus.OK); } catch (Exception e) { responseEntity = new ResponseEntity(HttpStatus.NOT_IMPLEMENTED); return responseEntity; } return responseEntity; } 

这就是角度2代码:

  public getReport():Observable{ 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); } 

致电服务:

 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); } ) 

}

这个方法返回一个损坏的文件,任何人都可以找出问题吗?

问题是您在选项中缺少responseType

 let options = new RequestOptions({headers: headers, **responseType: ResponseContentType.Blob**}); 

之后你就可以做到

  window['saveAs'](response.blob(), 'filename.zip');