我的目标是在Web应用程序中生成报告。我使用Web服务使用Birt运行报告。该构建可以在我的本地计算机上正常工作,但是一旦部署了应用程序,该文档的生成将停止工作。
我将Tempaltes(rptdesign)作为字节[]存储在数据库中,我的Web服务执行以下操作: ->获取:*报告Templte的标识符(所选报告) *格式(pdf,html ...) *参数(在我的情况下,所有报告中只有一个参数)
->配置和引擎(Birt Enfine) ->返回结果
应用程序是使用Jhipster(Angular,Spring)创建的。
“我的班级”的结构:
ReportTemplate |
-- -- -- -- -- -- > dto |
| -- -- -- > AppException.java |
| -- -- -- > Report.java |
|
-- -- -- -- -- -- > services |
| -- -- -- > ReportService.java |
|
|
-- -- -- > impl |
| |-- -- -- > ReportServiceImpl.java
-- -- -- - > ReportService.java |
|
|-- -- -- -- -- -- > ReportTemplateWebService.java
对ReportTemplateWebService进行分类,生成报告的Web服务为“ generateTemplate”:
package com.wlp.uowfrg.reportTemplate;
imports....
import java.util.Optional;
/**
* REST controller for managing ReportTemplate.
*/
@RestController
@RequestMapping("/api")
public class ReportTemplateWebServices {
private final Logger log = LoggerFactory.getLogger(ReportTemplateWebServices.class);
private static final String ENTITY_NAME = "reportTemplate";
private final ReportTemplateService reportTemplateService;
private final ReportTemplateQueryService reportTemplateQueryService;
private final ReportHistoryService reportHistoryService;
private final TaskFileService taskFileService;
@Autowired
private ReportService reportService;
public ReportTemplateWebServices(ApplicationContext applicationContext, ReportTemplateService reportTemplateService, ReportTemplateQueryService reportTemplateQueryService, ReportHistoryService reportHistoryService, TaskFileService taskFileService) {
this.reportTemplateService = reportTemplateService;
this.reportTemplateQueryService = reportTemplateQueryService;
this.reportHistoryService = reportHistoryService;
this.taskFileService = taskFileService;
}
@PostMapping("/SaveTemplate")
@Timed
public ResponseEntity < ReportTemplateDTO > saveTemplate(@RequestParam("file") MultipartFile multipart) throws URISyntaxException {
byte[] bytes = new byte[0];
try {
bytes = toByteArray(multipart.getInputStream());
} catch (IOException ioe) {}
// Create
ReportTemplateDTO newReportTemplate = new ReportTemplateDTO();
newReportTemplate.setName(multipart.getOriginalFilename());
newReportTemplate.setCreatedDate(Instant.now());
newReportTemplate.setTemplateBody(bytes);
newReportTemplate.setDefaultOutputFormat("PDF");
newReportTemplate.setUsableFormats("HTML,PDF,DOC,XLS");
ReportTemplateDTO res = reportTemplateService.save(newReportTemplate);
return ResponseEntity.created(new URI("/api/ReportTemplates/" + res.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, res.getId().toString()))
.body(res);
}
@GetMapping("/GenerateTemplate/{format}/{id}/{idTask}")
@Timed
public ResponseEntity generateTemplate(@PathVariable String format, @PathVariable Long id, @PathVariable String idTask)
throws EngineException, IOException {
byte[] output = reportService.generateMainReport(format, id, idTask);
RegistryProviderFactory.releaseDefault();
HttpHeaders header = new HttpHeaders();
header.set("charset", "utf-8");
header.setContentType(MediaType.APPLICATION_XML);
header.setContentLength(output.length);
header.set("Content-disposition", "attachment; filename=report." + format);
return new ResponseEntity < byte[] > (output, header, HttpStatus.OK);
}
public static byte[] toByteArray(InputStream in ) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
// read bytes from the input stream and store them in buffer
while ((len = in .read(buffer)) != -1) {
// write bytes from the buffer into output stream
os.write(buffer, 0, len);
}
return os.toByteArray();
}
}
Classe AppException.java
package com.wlp.uowfrg.reportTemplate.dto;
/**
* Main application exception
*
* @author shamskool
*
*/
public class AppException extends RuntimeException {
private static final long serialVersionUID = 1 L;
public AppException(String message) {
super(message);
}
public AppException(String message, Throwable t) {
super(message, t);
}
public static class AppExceptionDto {
String error;
Integer code;
public AppExceptionDto(String error, Integer code) {
super();
this.error = error;
this.code = code;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
}
Classe Report.java
包com.wlp.uowfrg.reportTemplate.dto;
import java.util.ArrayList;
import java.util.List;
public class Report {
private String title;
private String name;
private List < Parameter > parameters;
public String getTitle() {
return title;
}
public Report() {
super();
parameters = new ArrayList < > ();
}
public Report(String title, String name) {
this();
this.title = title;
this.name = name;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List < Parameter > getParameters() {
return parameters;
}
public void setParameters(List < Parameter > parameters) {
this.parameters = parameters;
}
public static class Parameter {
private String title;
private String name;
private ParameterType type;
public Parameter() {
super();
}
public Parameter(String title, String name, ParameterType type) {
this();
this.title = title;
this.name = name;
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParameterType getType() {
return type;
}
public void setType(ParameterType type) {
this.type = type;
}
}
public enum ParameterType {
INT,
STRING;
}
}
ReportServiceImpl.java类:
package com.wlp.uowfrg.reportTemplate.services.impl;
import java.io.File;
imports
import com.wlp.uowfrg.service.ReportTemplateService;
import com.wlp.uowfrg.service.dto.ReportTemplateDTO;
@Service
public class ReportServiceImpl implements ReportService, ApplicationContextAware {
public ReportServiceImpl(ReportTemplateService reportTemplateService) {
this.reportTemplateService = reportTemplateService;
}
@Autowired
private ServletContext servletContext;
private IReportEngine birtEngine;
private ApplicationContext context;
private Map < Long, IReportRunnable > reports = new HashMap < > ();
private static final String IMAGE_FOLDER = "/images";
private final ReportTemplateService reportTemplateService;
@SuppressWarnings("unchecked")
@PostConstruct
protected void initialize() throws BirtException {
EngineConfig config = new EngineConfig();
config.getAppContext().put("spring", this.context);
Platform.startup(config);
IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
birtEngine = factory.createReportEngine(config);
loadReports();
}
public void loadReports() throws EngineException {
for (ReportTemplateDTO template: reportTemplateService.findAll()) {
try {
reports.put(template.getId(),
birtEngine.openReportDesign(new ByteArrayInputStream(template.getTemplateBody()))
);
} catch (EngineException e) {
e.printStackTrace();
}
}
}
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
@Override
public List < Report > getReports() {
List < Report > response = new ArrayList < > ();
return response;
}
private ParameterType getParameterType(IParameterDefn param) {
if (IParameterDefn.TYPE_INTEGER == param.getDataType()) {
return ParameterType.INT;
}
return ParameterType.STRING;
}
@Override
public byte[] generateMainReport(String format, Long TemplateId, String idTaskFile) {
return generateReport(TemplateId, format, idTaskFile);
}
@SuppressWarnings("unchecked")
public byte[] generateReport(Long TemplateId, String format, String idTaskFile) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream stream = null;
IReportRunnable report = reports.get(TemplateId);
IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(report);
runAndRenderTask.setParameterValue("TaskBuilder_Id", idTaskFile);
IRenderOption options = new RenderOption();
HTMLRenderOption htmlOptions = new HTMLRenderOption(options);
htmlOptions.setOutputFormat(format);
htmlOptions.setImageHandler(new HTMLServerImageHandler());
htmlOptions.setImageDirectory(servletContext.getRealPath(IMAGE_FOLDER));
runAndRenderTask.setRenderOption(htmlOptions);
IGetParameterDefinitionTask task = birtEngine.createGetParameterDefinitionTask(report);
try {
htmlOptions.setOutputStream(out);
runAndRenderTask.run();
return out.toByteArray();
} catch (Exception e) {
throw new AppException(e.getMessage(), e);
} finally {
runAndRenderTask.close();
}
}
}
pom.xml中的Birt依赖项
<!-- https://mvnrepository.com/artifact/org.eclipse.birt.runtime.3_7_1/org.eclipse.birt.runtime -->
<dependency >
<groupId > org.eclipse.birt.runtime .3 _7_1 < /groupId>
<artifactId > org.eclipse.birt.runtime < /artifactId>
<version > 3.7 .1 < /version> <
/dependency>
错误如下
C: \Utilisateurs\ a699116\ Desktop\ Project example\ forge - portal - gitlab - 0e55 ce04cea52f3dec7df4820b8a11eedc3c9ddf\ target > java - jar configurator - 0.3 .1 - SNAPSHOT.war
██╗██╗██╗████████╗███████╗██████╗████████╗████████╗███████╗██║██║██║╚══██╔══╝██╔═══██╗██╔════╝╚══██╔══╝██╔═════╝██╔═══██╗██║████████║██║███████╔╝╚█████╗██║██████╗███████╔╝██╗██║██╔═══██║██║██╔════╝╚═══██╗██║██╔═══╝██╔══██║╚██████╔╝██║██║████████╗██║██████╔╝██║████████╗██║╚██╗╚═════╝╚═╝╚═╝╚═══════╝╚═╝╚═════╝╚═╝╚═══════╝╚═╝╚═╝
::JHipster ? ::Running Spring Boot 1.5 .10.RELEASE::::http : //www.jhipster.tech ::
2018 - 12 - 27 18: 04: 36.969 INFO 9108-- - [main] com.wlp.uowfrg.ConfiguratorApp: Starting ConfiguratorApp on EFR04475 with PID 9108(C: \Utilisateurs\ a699116\ Desktop\ Project example\ forge - portal - gitlab - 0e55 ce04cea52f3dec7df4820b8a11eedc3c9ddf\ target\ configurator - 0.3 .1 - SNAPSHOT.war started by a699116 in C: \Utilisateurs\ a699116\ Desktop\ Project example\ forge - portal - gitlab - 0e55 ce04cea52f3dec7df4820b8a11eedc3c9ddf\ target)
2018 - 12 - 27 18: 04: 36.982 INFO 9108-- - [main] com.wlp.uowfrg.ConfiguratorApp: The following profiles are active: prod, swagger, no - liquibase
2018 - 12 - 27 18: 05: 10.067 INFO 9108-- - [main] com.wlp.uowfrg.config.WebConfigurer: Web application configuration, using profiles: prod
2018 - 12 - 27 18: 05: 10.139 INFO 9108-- - [main] com.wlp.uowfrg.config.WebConfigurer: Web application fully configured
2018 - 12 - 27 18: 05: 59.034 WARN 9108-- - [main] ationConfigEmbeddedWebApplicationContext: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reportTemplateWebServices': Unsatisfied dependency expressed through field 'reportService';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportServiceImpl': Invocation of init method failed;
nested exception is java.lang.ExceptionInInitializerError
2018 - 12 - 27 18: 05: 59.239 ERROR 9108-- - [main] o.s.boot.SpringApplication: Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reportTemplateWebServices': Unsatisfied dependency expressed through field 'reportService';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportServiceImpl': Invocation of init method failed;
nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java: 588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java: 88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java: 366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java: 1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java: 553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java: 483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java: 306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java: 230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java: 302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java: 197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java: 761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java: 867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java: 543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java: 122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java: 693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java: 360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java: 303)
at com.wlp.uowfrg.ConfiguratorApp.main(ConfiguratorApp.java: 66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java: 48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java: 87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java: 50)
at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java: 59)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportServiceImpl': Invocation of init method failed;
nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java: 137)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java: 409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java: 1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java: 555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java: 483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java: 306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java: 230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java: 302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java: 202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java: 208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java: 1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java: 1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java: 585)
...25 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
at org.eclipse.birt.report.model.metadata.MetaDataDictionary. < init > (MetaDataDictionary.java: 252)
at org.eclipse.birt.report.model.metadata.MetaDataDictionary. < clinit > (MetaDataDictionary.java: 112)
at org.eclipse.birt.report.model.api.impl.DesignEngineImpl.newSessionHandle(DesignEngineImpl.java: 143)
at org.eclipse.birt.report.model.api.DesignEngine.newSessionHandle(DesignEngine.java: 120)
at org.eclipse.birt.report.engine.parser.ReportParser.getDesignHandle(ReportParser.java: 143)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.getReportDesignHandle(ReportEngineHelper.java: 255)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.openReportDesign(ReportEngineHelper.java: 274)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.openReportDesign(ReportEngineHelper.java: 184)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.openReportDesign(ReportEngineHelper.java: 161)
at org.eclipse.birt.report.engine.api.impl.ReportEngine.openReportDesign(ReportEngine.java: 349)
at com.wlp.uowfrg.reportTemplate.services.impl.ReportServiceImpl.loadReports(ReportServiceImpl.java: 98)
at com.wlp.uowfrg.reportTemplate.services.impl.ReportServiceImpl.initialize(ReportServiceImpl.java: 80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java: 366)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java: 311)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java: 134)
...37 common frames omitted
Caused by: java.util.MissingResourceException: Unable to construct Calendar
at com.ibm.icu.util.CalendarServiceShim.createInstance(CalendarServiceShim.java: 69)
at com.ibm.icu.util.Calendar.getInstanceInternal(Calendar.java: 1626)
at com.ibm.icu.util.Calendar.getInstance(Calendar.java: 1588)
at com.ibm.icu.text.SimpleDateFormat.initialize(SimpleDateFormat.java: 504)
at com.ibm.icu.text.SimpleDateFormat. < init > (SimpleDateFormat.java: 469)
at com.ibm.icu.text.SimpleDateFormat. < init > (SimpleDateFormat.java: 394)
at org.eclipse.birt.report.model.metadata.DateTimePropertyType. < clinit > (DateTimePropertyType.java: 63)
...56 common frames omitted