如何将内存中的 JasperReport Design 传递给 Spring 视图

How to pass in-memory JasperReport Design to Spring View

我已经为此工作了很长一段时间,但我找不到适合我正在搜索的内容的确切解决方案。
简而言之:我有一个集成了 JasperReports 的 Spring Boot MVC 应用程序。这些报告应该可以调整大小。 因此,我想通过 jasper 本身提供的 XML-loader 读取 .jrxml,操作 jasperDesign 并将其传递给相应的 Spring/Jasper-view 而不保存。

spring 中的 jasper-config:

@Configuration
public class JasperReportsConfig {

@Bean
public JasperReportsViewResolver getJasperReportsViewResolver() {
    JasperReportsViewResolver resolver = new JasperReportsViewResolver();

    resolver.setViewClass(JasperReportsMultiFormatView.class);
    resolver.setPrefix("classpath:/jrxml/");
    resolver.setSuffix(".jrxml");
    resolver.setReportDataKey("datasource");
    resolver.setViewNames("rpt_*");
    resolver.setOrder(0);

    return resolver;
}
}

spring 中的 jasper-controller:

@Controller
public class JasperReportsController {

//...

@RequestMapping(value = "/reportPreview", method=RequestMethod.GET, produces = "application/pdf")
public ModelAndView setupReport(ModelMap modelMap, ModelAndView modelAndView) throws IOException {
    modelMap.put("datasource", new JREmptyDataSource());
    modelMap.put("background", getbackground());
    modelMap.put("format", "pdf");

    /*modify report here*/

    //currently I pass a String ("rpt_myReport") to the viewResolver, but I need to
    //pass a JasperReportDesign, so that Spring can proceed with compiling
    modelAndView = new ModelAndView("rpt_myReport", modelMap);
    return modelAndView;
}
}

尽管使用了 DynamicJasper 等,但我希望有人对此有解决方案 ^^

提前致以最诚挚的问候和感谢。

我不太确定这是否是您要找的,但我是这样做的。 (我已经更改了事物的名称以使其通用,希望它仍然 compiles/works)

@RequestMapping(value="/report", params = {"objectid"}, method = { RequestMethod.GET })
public void getReport(HttpServletResponse response, @RequestParam(value = "objectid") long objectid){
    Object object = objectDAOFactory.getObjectDAO().loadById(objectid);

    ObjectDataSource dataSource = new ObjectDataSource(object);

    JasperPrint jasperPrint = getObjectPdf("pdf/ObjectReport.jrxml", new HashMap<String, Object>(), dataSource);

    sendPdfResponse(response, jasperPrint, "Object-" + object.getId());
}

public JasperPrint getObjectPdf(String path, Map<String, Object> parameters, JRDataSource dataSource) {
    JasperPrint jasperPrint = null;

    InputStream inStream = null;
    try {
        inStream = getClass().getClassLoader().getResourceAsStream(path);
        JasperDesign jasperDesign = JRXmlLoader.load(inStream);
        JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
        jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
        jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
    } catch (JRException jre) {
        logger.error("Error creating Pdf", jre);
    } finally {
        if (inStream != null) {
            try {
                inStream.close();
            } catch (IOException e) {
                logger.error("Error closing stream", e);
            }
        }
    }

    return jasperPrint;
}

public static void sendPdfResponse(HttpServletResponse response, JasperPrint jasperPrint, String fileName){

    //Remove all whitespace from file name
    fileName.replaceAll("\s","");

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try {
        JasperExportManager.exportReportToPdfStream(jasperPrint, out);
    } catch (JRException e1) {
        e1.printStackTrace();
    }

    byte[] data = out.toByteArray();

    response.setContentType("application/pdf");
    //To make it a download change "inline" to "attachment"
    response.setHeader("Content-disposition", "inline; filename=" + fileName + ".pdf");
    response.setContentLength(data.length);

    try {
        response.getOutputStream().write(data);
        response.getOutputStream().flush();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}