早上好! 我有一个方法" gerarJasper"使用JasperReports打印报告。此方法将列表作为参数,因此我可以在整个应用程序中使用此方法。但是,当此列表不包含任何数据时,JasperReports将打印一个空白PDF。我想做什么:当data参数为空时,我想在此列表中添加一个对象。我有如何在运行时找到List的Object类型
下面的代码public void imprimir(List<TrUltimaLocalizacaoGps> l){
try {
super.gerarJasper("RelLstTrUltimaLocalizacaoGps", "PDF", l, new HashMap());
} catch (Exception e) {
e.printStackTrace();
}
}
public void gerarJasper(String jasperName, String type, List data, Map params) throws IllegalArgumentException, RuntimeException, Exception {
boolean found = false;
for (int i = 0; i < VALID_TYPES.length; i++) {
if (VALID_TYPES[i].equals(type)) {
found = true;
break;
}
}
if (!found) {
throw new IllegalArgumentException("Tipo solicitado '" + type + "' inválido");
}
ExternalContext econtext = FacesContext.getCurrentInstance().getExternalContext();
InputStream stream = econtext.getResourceAsStream(PREFIX + name + SUFFIX);
if (stream == null) {
throw new IllegalArgumentException("O relatório '" + name + "' não existe");
}
FacesContext fc = FacesContext.getCurrentInstance();
ServletContext context = (ServletContext)fc.getExternalContext().getContext();
String path = context.getRealPath(File.separator) + "resources/jasper" + File.separator;
params.put("SUBREPORT_DIR", path);
// here I would like to know what the Object Type of the data parameter
JRDataSource ds = new JRBeanArrayDataSource(data.toArray());
JasperPrint jasperPrint = null;
try {
jasperPrint = JasperFillManager.fillReport(stream, params, ds);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new FacesException(e);
} finally {
try {
stream.close();
} catch (IOException e) {
}
}
JRExporter exporter = null;
HttpServletResponse response = (HttpServletResponse) econtext.getResponse();
FacesContext fcontext = FacesContext.getCurrentInstance();
try {
response.setContentType(type);
if ("application/pdf".equals(type)) {
exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
} else if ("text/html".equals(type)) {
exporter = new JRHtmlExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();
request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, new HashMap());
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new FacesException(e);
}
try {
exporter.exportReport();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new FacesException(e);
}
fcontext.responseComplete();
}
答案 0 :(得分:0)
正如已经评论的那样,java的类型擦除使得无法找出什么类型的列表&#34;数据&#34;是。因此,您必须考虑替代问题。
一个选项是,,因为列表为空,它的类型真的很重要吗?如果没有,您可以在输入为空时创建一个包含一个项目的新列表:
JRDataSource ds = new JRBeanArrayDataSource(data.isEmpty() ? Arrays.asList(new SomeObject()), data.toArray());
另一个选项是,如果列表类型有所不同,您可以将其类作为参数传递:
public void gerarJasper(String jasperName, String type, List data, Map params, Class<?> listClass) throws IllegalArgumentException, RuntimeException, Exception {
然后在&#34;数据&#34;时创建一个新对象。是空的:
JRDataSource ds;
if (data.isEmpty()) {
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance();
ds = new JRBeanArrayDataSource(object);
} else {
ds = new JRBeanArrayDataSource(data.toArray());
}
最后,而不是在生成报告时向列表中添加内容,为什么不在创建时确保列表中始终存在某些内容。您可能知道创建它时的列表类型。根据应用程序的设置方式,这可能有意义。