parent
355c6f0715
commit
7dda9fbd8c
17
build.gradle
17
build.gradle
|
@ -51,7 +51,6 @@ configure(allprojects) { project ->
|
|||
ext.httpasyncVersion = "4.1.2"
|
||||
ext.httpclientVersion = "4.5.2"
|
||||
ext.jackson2Version = "2.8.0"
|
||||
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
|
||||
ext.javamailVersion = "1.5.5"
|
||||
ext.jcaVersion = "1.7"
|
||||
ext.jettyVersion = "9.3.10.v20160621"
|
||||
|
@ -622,14 +621,6 @@ project("spring-context-support") {
|
|||
optional("org.codehaus.fabric3.api:commonj:1.1.0")
|
||||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
optional("com.lowagie:itext:2.1.7")
|
||||
optional("net.sf.jasperreports:jasperreports:$jasperreportsVersion") {
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-annotations"
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-core"
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-databind"
|
||||
exclude group: "org.olap4j", module: "olap4j"
|
||||
exclude group: "xml-apis", module: "xml-apis"
|
||||
exclude group: "org.springframework", module: "spring-context"
|
||||
}
|
||||
testCompile(project(":spring-context"))
|
||||
testCompile("org.apache.poi:poi:${poiVersion}")
|
||||
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
|
@ -748,14 +739,6 @@ project("spring-webmvc") {
|
|||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("com.lowagie:itext:2.1.7")
|
||||
optional("net.sf.jasperreports:jasperreports:$jasperreportsVersion") {
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-annotations"
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-core"
|
||||
exclude group: "com.fasterxml.jackson.core", module: "jackson-databind"
|
||||
exclude group: "org.olap4j", module: "olap4j"
|
||||
exclude group: "xml-apis", module: "xml-apis"
|
||||
exclude group: "org.springframework", module: "spring-context"
|
||||
}
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
|
||||
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
|
||||
optional("com.rometools:rome:${romeVersion}")
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.jasperreports.engine.JRDataSource;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JasperFillManager;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;
|
||||
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
|
||||
import net.sf.jasperreports.engine.export.JRCsvExporter;
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporter;
|
||||
import net.sf.jasperreports.engine.export.JRXlsExporter;
|
||||
|
||||
/**
|
||||
* Utility methods for working with JasperReports. Provides a set of convenience
|
||||
* methods for generating reports in a CSV, HTML, PDF and XLS formats.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which has been deprecated in early 2014.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public abstract class JasperReportsUtils {
|
||||
|
||||
/**
|
||||
* Convert the given report data value to a {@code JRDataSource}.
|
||||
* <p>In the default implementation, a {@code JRDataSource},
|
||||
* {@code java.util.Collection} or object array is detected.
|
||||
* The latter are converted to {@code JRBeanCollectionDataSource}
|
||||
* or {@code JRBeanArrayDataSource}, respectively.
|
||||
* @param value the report data value to convert
|
||||
* @return the JRDataSource (never {@code null})
|
||||
* @throws IllegalArgumentException if the value could not be converted
|
||||
* @see net.sf.jasperreports.engine.JRDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
|
||||
*/
|
||||
public static JRDataSource convertReportData(Object value) throws IllegalArgumentException {
|
||||
if (value instanceof JRDataSource) {
|
||||
return (JRDataSource) value;
|
||||
}
|
||||
else if (value instanceof Collection) {
|
||||
return new JRBeanCollectionDataSource((Collection<?>) value);
|
||||
}
|
||||
else if (value instanceof Object[]) {
|
||||
return new JRBeanArrayDataSource((Object[]) value);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Value [" + value + "] cannot be converted to a JRDataSource");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the supplied {@code JasperPrint} instance using the
|
||||
* supplied {@code JRAbstractExporter} instance and write the results
|
||||
* to the supplied {@code Writer}.
|
||||
* <p>Make sure that the {@code JRAbstractExporter} implementation
|
||||
* you supply is capable of writing to a {@code Writer}.
|
||||
* @param exporter the {@code JRAbstractExporter} to use to render the report
|
||||
* @param print the {@code JasperPrint} instance to render
|
||||
* @param writer the {@code Writer} to write the result to
|
||||
* @throws JRException if rendering failed
|
||||
*/
|
||||
public static void render(net.sf.jasperreports.engine.JRExporter exporter, JasperPrint print, Writer writer)
|
||||
throws JRException {
|
||||
|
||||
exporter.setParameter(net.sf.jasperreports.engine.JRExporterParameter.JASPER_PRINT, print);
|
||||
exporter.setParameter(net.sf.jasperreports.engine.JRExporterParameter.OUTPUT_WRITER, writer);
|
||||
exporter.exportReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the supplied {@code JasperPrint} instance using the
|
||||
* supplied {@code JRAbstractExporter} instance and write the results
|
||||
* to the supplied {@code OutputStream}.
|
||||
* <p>Make sure that the {@code JRAbstractExporter} implementation you
|
||||
* supply is capable of writing to a {@code OutputStream}.
|
||||
* @param exporter the {@code JRAbstractExporter} to use to render the report
|
||||
* @param print the {@code JasperPrint} instance to render
|
||||
* @param outputStream the {@code OutputStream} to write the result to
|
||||
* @throws JRException if rendering failed
|
||||
*/
|
||||
public static void render(net.sf.jasperreports.engine.JRExporter exporter, JasperPrint print,
|
||||
OutputStream outputStream) throws JRException {
|
||||
|
||||
exporter.setParameter(net.sf.jasperreports.engine.JRExporterParameter.JASPER_PRINT, print);
|
||||
exporter.setParameter(net.sf.jasperreports.engine.JRExporterParameter.OUTPUT_STREAM, outputStream);
|
||||
exporter.exportReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in CSV format using the supplied report data.
|
||||
* Writes the results to the supplied {@code Writer}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param writer the {@code Writer} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsCsv(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
Writer writer) throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
render(new JRCsvExporter(), print, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in CSV format using the supplied report data.
|
||||
* Writes the results to the supplied {@code Writer}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param writer the {@code Writer} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @param exporterParameters a {@link Map} of {@code JRExporterParameter exporter parameters}
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsCsv(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
Writer writer, Map<net.sf.jasperreports.engine.JRExporterParameter, Object> exporterParameters)
|
||||
throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
JRCsvExporter exporter = new JRCsvExporter();
|
||||
exporter.setParameters(exporterParameters);
|
||||
render(exporter, print, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in HTML format using the supplied report data.
|
||||
* Writes the results to the supplied {@code Writer}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param writer the {@code Writer} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsHtml(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
Writer writer) throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
render(new net.sf.jasperreports.engine.export.JRHtmlExporter(), print, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in HTML format using the supplied report data.
|
||||
* Writes the results to the supplied {@code Writer}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param writer the {@code Writer} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @param exporterParameters a {@link Map} of {@code JRExporterParameter exporter parameters}
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsHtml(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
Writer writer, Map<net.sf.jasperreports.engine.JRExporterParameter, Object> exporterParameters)
|
||||
throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
net.sf.jasperreports.engine.export.JRHtmlExporter exporter = new net.sf.jasperreports.engine.export.JRHtmlExporter();
|
||||
exporter.setParameters(exporterParameters);
|
||||
render(exporter, print, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in PDF format using the supplied report data.
|
||||
* Writes the results to the supplied {@code OutputStream}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param stream the {@code OutputStream} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsPdf(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
OutputStream stream) throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
render(new JRPdfExporter(), print, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in PDF format using the supplied report data.
|
||||
* Writes the results to the supplied {@code OutputStream}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param stream the {@code OutputStream} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @param exporterParameters a {@link Map} of {@code JRExporterParameter exporter parameters}
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsPdf(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
OutputStream stream, Map<net.sf.jasperreports.engine.JRExporterParameter, Object> exporterParameters)
|
||||
throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
JRPdfExporter exporter = new JRPdfExporter();
|
||||
exporter.setParameters(exporterParameters);
|
||||
render(exporter, print, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in XLS format using the supplied report data.
|
||||
* Writes the results to the supplied {@code OutputStream}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param stream the {@code OutputStream} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsXls(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
OutputStream stream) throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
render(new JRXlsExporter(), print, stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a report in XLS format using the supplied report data.
|
||||
* Writes the results to the supplied {@code OutputStream}.
|
||||
* @param report the {@code JasperReport} instance to render
|
||||
* @param parameters the parameters to use for rendering
|
||||
* @param stream the {@code OutputStream} to write the rendered report to
|
||||
* @param reportData a {@code JRDataSource}, {@code java.util.Collection} or object array
|
||||
* (converted accordingly), representing the report data to read fields from
|
||||
* @param exporterParameters a {@link Map} of {@code JRExporterParameter exporter parameters}
|
||||
* @throws JRException if rendering failed
|
||||
* @see #convertReportData
|
||||
*/
|
||||
public static void renderAsXls(JasperReport report, Map<String, Object> parameters, Object reportData,
|
||||
OutputStream stream, Map<net.sf.jasperreports.engine.JRExporterParameter, Object> exporterParameters)
|
||||
throws JRException {
|
||||
|
||||
JasperPrint print = JasperFillManager.fillReport(report, parameters, convertReportData(reportData));
|
||||
JRXlsExporter exporter = new JRXlsExporter();
|
||||
exporter.setParameters(exporterParameters);
|
||||
render(exporter, print, stream);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/**
|
||||
* Support classes for
|
||||
* <a href="http://jasperreports.sourceforge.net">JasperReports</a>.
|
||||
*/
|
||||
package org.springframework.ui.jasperreports;
|
|
@ -1,274 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import net.sf.jasperreports.engine.JRDataSource;
|
||||
import net.sf.jasperreports.engine.JRExporterParameter;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.JasperFillManager;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
|
||||
import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
|
||||
import net.sf.jasperreports.engine.export.JRHtmlExporter;
|
||||
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporter;
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
|
||||
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
|
||||
import net.sf.jasperreports.engine.util.JRLoader;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.tests.Assume;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 18.11.2004
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class JasperReportsUtilsTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void assumptions() {
|
||||
Assume.canLoadNativeDirFonts();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsCsvWithDataSource() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getDataSource(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsCsvWithCollection() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsCsvWithExporterParameters() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<>();
|
||||
exporterParameters.put(JRCsvExporterParameter.FIELD_DELIMITER, "~");
|
||||
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer, exporterParameters);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertCsvOutputCorrect(output);
|
||||
assertTrue("Delimiter is incorrect", output.contains("~"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsHtmlWithDataSource() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getDataSource(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsHtmlWithCollection() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsHtmlWithExporterParameters() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<>();
|
||||
String uri = "/my/uri";
|
||||
exporterParameters.put(JRHtmlExporterParameter.IMAGES_URI, uri);
|
||||
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer, exporterParameters);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
assertTrue("URI not included", output.contains(uri));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsPdfWithDataSource() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getDataSource(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsPdfWithCollection() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsPdfWithExporterParameters() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<>();
|
||||
exporterParameters.put(JRPdfExporterParameter.PDF_VERSION, JRPdfExporterParameter.PDF_VERSION_1_6.toString());
|
||||
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os, exporterParameters);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
assertTrue(new String(output).contains("PDF-1.6"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsXlsWithDataSource() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getDataSource(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsXlsWithCollection() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderAsXlsWithExporterParameters() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
Map<JRExporterParameter, Object> exporterParameters = new HashMap<>();
|
||||
|
||||
SimpleProgressMonitor monitor = new SimpleProgressMonitor();
|
||||
exporterParameters.put(JRXlsExporterParameter.PROGRESS_MONITOR, monitor);
|
||||
|
||||
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os, exporterParameters);
|
||||
byte[] output = os.toByteArray();
|
||||
assertXlsOutputCorrect(output);
|
||||
assertTrue(monitor.isInvoked());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderWithWriter() throws Exception {
|
||||
StringWriter writer = new StringWriter();
|
||||
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
|
||||
JasperReportsUtils.render(new JRHtmlExporter(), print, writer);
|
||||
String output = writer.getBuffer().toString();
|
||||
assertHtmlOutputCorrect(output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderWithOutputStream() throws Exception {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
|
||||
JasperReportsUtils.render(new JRPdfExporter(), print, os);
|
||||
byte[] output = os.toByteArray();
|
||||
assertPdfOutputCorrect(output);
|
||||
}
|
||||
|
||||
private void assertCsvOutputCorrect(String output) {
|
||||
assertTrue("Output length should be greater than 0", (output.length() > 0));
|
||||
assertTrue("Output should start with Dear Lord!", output.startsWith("Dear Lord!"));
|
||||
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
|
||||
}
|
||||
|
||||
private void assertHtmlOutputCorrect(String output) {
|
||||
assertTrue("Output length should be greater than 0", (output.length() > 0));
|
||||
assertTrue("Output should contain <html>", output.contains("<html>"));
|
||||
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
|
||||
}
|
||||
|
||||
private void assertPdfOutputCorrect(byte[] output) throws Exception {
|
||||
assertTrue("Output length should be greater than 0", (output.length > 0));
|
||||
|
||||
String translated = new String(output, "US-ASCII");
|
||||
assertTrue("Output should start with %PDF", translated.startsWith("%PDF"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
private void assertXlsOutputCorrect(byte[] output) throws Exception {
|
||||
HSSFWorkbook workbook = new HSSFWorkbook(new ByteArrayInputStream(output));
|
||||
HSSFSheet sheet = workbook.getSheetAt(0);
|
||||
assertNotNull("Sheet should not be null", sheet);
|
||||
HSSFRow row = sheet.getRow(3);
|
||||
HSSFCell cell = row.getCell((short) 1);
|
||||
assertNotNull("Cell should not be null", cell);
|
||||
assertEquals("Cell content should be Dear Lord!", "Dear Lord!", cell.getRichStringCellValue().getString());
|
||||
}
|
||||
|
||||
private JasperReport getReport() throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource("DataSourceReport.jasper", getClass());
|
||||
return (JasperReport) JRLoader.loadObject(resource.getInputStream());
|
||||
}
|
||||
|
||||
private Map<String, Object> getParameters() {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put("ReportTitle", "Dear Lord!");
|
||||
model.put(JRParameter.REPORT_LOCALE, Locale.GERMAN);
|
||||
model.put(JRParameter.REPORT_RESOURCE_BUNDLE,
|
||||
ResourceBundle.getBundle("org/springframework/ui/jasperreports/messages", Locale.GERMAN));
|
||||
return model;
|
||||
}
|
||||
|
||||
private JRDataSource getDataSource() {
|
||||
return new JRBeanCollectionDataSource(getData());
|
||||
}
|
||||
|
||||
private List<PersonBean> getData() {
|
||||
List<PersonBean> list = new ArrayList<>();
|
||||
for (int x = 0; x < 10; x++) {
|
||||
PersonBean bean = new PersonBean();
|
||||
bean.setId(x);
|
||||
bean.setName("Rob Harrop");
|
||||
bean.setStreet("foo");
|
||||
list.add(bean);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleProgressMonitor implements JRExportProgressMonitor {
|
||||
|
||||
private boolean invoked = false;
|
||||
|
||||
@Override
|
||||
public void afterPageExport() {
|
||||
this.invoked = true;
|
||||
}
|
||||
|
||||
public boolean isInvoked() {
|
||||
return invoked;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class PersonBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String street;
|
||||
|
||||
private String city;
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ui.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ProductBean {
|
||||
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private float quantity;
|
||||
|
||||
private float price;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public float getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(float quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public float getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(float price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -1,185 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="DataSourceReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ReportTitle" class="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="DataFile" class="java.lang.String">
|
||||
</parameter>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="street" class="java.lang.String">
|
||||
</field>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<variable name="CityNumber" class="java.lang.Integer" resetType="Group" resetGroup="CityGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{CityNumber} != null)?(new Integer($V{CityNumber}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="CityGroup" minHeightToStartNewPage="60">
|
||||
<groupExpression><![CDATA[$F{city}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="4" width="515" height="15" forecolor="#c0c0c0" backcolor="#c0c0c0"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<textField>
|
||||
<reportElement mode="Opaque" x="0" y="4" width="515" height="15" backcolor="#c0c0c0"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{CityNumber}) + ". " + String.valueOf($F{city})]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="19" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band height="20">
|
||||
<line>
|
||||
<reportElement x="0" y="-1" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="400" y="1" width="60" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="460" y="1" width="30" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{CityGroup_COUNT}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="70">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportTitle}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="40" width="515" height="20"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="14"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{DataFile}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" forecolor="#333333" backcolor="#333333"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="55" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="55" y="5" width="205" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="260" y="5" width="255" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Street]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="20">
|
||||
<textField>
|
||||
<reportElement x="0" y="4" width="50" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="55" y="4" width="200" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="260" y="4" width="255" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{street}]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement positionType="Float" x="0" y="19" width="515" height="1" forecolor="#808080"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<lastPageFooter>
|
||||
<band height="60">
|
||||
<textField>
|
||||
<reportElement x="0" y="10" width="515" height="15"/>
|
||||
<textElement textAlignment="Center"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["There were " +
|
||||
String.valueOf($V{REPORT_COUNT}) +
|
||||
" address records on this report."]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="30" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="40" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="40" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</lastPageFooter>
|
||||
</jasperReport>
|
|
@ -1 +0,0 @@
|
|||
page=MeineSeite
|
Binary file not shown.
|
@ -1,227 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="ProductReport" columnCount="2" pageWidth="325" pageHeight="842" columnWidth="160" columnSpacing="5" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="8" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="8" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="8" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="City" class="java.lang.String"/>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="quantity" class="java.lang.Float">
|
||||
</field>
|
||||
<field name="price" class="java.lang.Float">
|
||||
</field>
|
||||
<variable name="QuantityProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="QuantitySum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceSum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="ProductCount" class="java.lang.Integer" resetType="Group" resetGroup="ProductGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{ProductCount} != null)?(new Integer($V{ProductCount}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="ProductGroup">
|
||||
<groupExpression><![CDATA[$F{id}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="14">
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="15" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="20" y="2" width="80" height="10"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0">
|
||||
<reportElement positionType="Float" x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantityProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0.00">
|
||||
<reportElement positionType="Float" x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="14">
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Title]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="325" height="10"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Products ordered by people in " + $P{City}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Header]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<columnHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="160" height="10" forecolor="#ffff99" backcolor="#ffff99"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="20" y="2" width="85" height="10" backcolor="#ffff99"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="105" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Qty]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="125" y="2" width="35" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Price]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</columnHeader>
|
||||
<columnFooter>
|
||||
<band height="14">
|
||||
<line>
|
||||
<reportElement x="0" y="1" width="160" height="1"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Column Footer]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement x="70" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Total :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantitySum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField pattern="#0.00">
|
||||
<reportElement x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</columnFooter>
|
||||
<pageFooter>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Footer]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="150" y="2" width="100" height="10" forecolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of "]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="250" y="2" width="50" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<summary>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="325" height="10" forecolor="#808000" backcolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="230" height="10" backcolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Summary]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="230" y="2" width="55" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement mode="Opaque" x="285" y="2" width="40" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{ProductCount}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</summary>
|
||||
</jasperReport>
|
Binary file not shown.
|
@ -1,103 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="MasterReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ProductsSubReport" class="net.sf.jasperreports.engine.JasperReport"/>
|
||||
<parameter name="SubReportData" class="net.sf.jasperreports.engine.JRDataSource"/>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<title>
|
||||
<band height="50">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Master Report]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="21">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" backcolor="#333333"/>
|
||||
<graphicElement pen="None"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="515" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[City List]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="50">
|
||||
<textField>
|
||||
<reportElement x="5" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{city}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement isPrintRepeatedValues="false" x="110" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[(continued)]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1" isPrintWhenDetailOverflows="true"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<subreport>
|
||||
<reportElement isPrintRepeatedValues="false" x="5" y="25" width="325" height="20" isRemoveLineWhenBlank="true" backcolor="#ffcc99"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{city}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<dataSourceExpression><![CDATA[$P{SubReportData}]]></dataSourceExpression>
|
||||
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{ProductsSubReport}]]></subreportExpression>
|
||||
</subreport>
|
||||
<!--<subreport>
|
||||
<reportElement positionType="Float" x="335" y="25" width="175" height="20" isRemoveLineWhenBlank="true" backcolor="#99ccff"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{City}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
|
||||
<subreportExpression class="java.lang.String"><![CDATA["AddressReport.jasper"]]></subreportExpression>
|
||||
</subreport> -->
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
</jasperReport>
|
|
@ -16,15 +16,11 @@
|
|||
|
||||
package org.springframework.tests;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.AssumptionViolatedException;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
/**
|
||||
|
@ -89,26 +85,6 @@ public abstract class Assume {
|
|||
assumeFalse(log.isDebugEnabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assume that we can load fonts.
|
||||
* <p>See <a href="https://java.net/jira/browse/MACOSX_PORT-355">MACOSX_PORT-355</a>
|
||||
* issue.
|
||||
* @throws AssumptionViolatedException if the assumption fails
|
||||
*/
|
||||
public static void canLoadNativeDirFonts() {
|
||||
try {
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
|
||||
Class<?> parserClass = ClassUtils.forName(
|
||||
"net.sf.jasperreports.engine.util.JRStyledTextParser", Assume.class.getClassLoader());
|
||||
Method method = parserClass.getMethod("getInstance");
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new AssumptionViolatedException("Requires GraphicsEnvironment that can load fonts", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.2
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
|
||||
import org.springframework.ui.jasperreports.JasperReportsUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Extends {@code AbstractJasperReportsView} to provide basic rendering logic
|
||||
* for views that use a fixed format, e.g. always PDF or always HTML.
|
||||
*
|
||||
* <p>Subclasses need to implement two template methods: {@code createExporter}
|
||||
* to create a JasperReports exporter for a specific output format, and
|
||||
* {@code useWriter} to determine whether to write text or binary content.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.5
|
||||
* @see #createExporter()
|
||||
* @see #useWriter()
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public abstract class AbstractJasperReportsSingleFormatView extends AbstractJasperReportsView {
|
||||
|
||||
@Override
|
||||
protected boolean generatesDownloadContent() {
|
||||
return !useWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform rendering for a single Jasper Reports exporter, that is,
|
||||
* for a pre-defined output format.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void renderReport(JasperPrint populatedReport, Map<String, Object> model, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
net.sf.jasperreports.engine.JRExporter exporter = createExporter();
|
||||
|
||||
Map<net.sf.jasperreports.engine.JRExporterParameter, Object> mergedExporterParameters = getConvertedExporterParameters();
|
||||
if (!CollectionUtils.isEmpty(mergedExporterParameters)) {
|
||||
exporter.setParameters(mergedExporterParameters);
|
||||
}
|
||||
|
||||
if (useWriter()) {
|
||||
renderReportUsingWriter(exporter, populatedReport, response);
|
||||
}
|
||||
else {
|
||||
renderReportUsingOutputStream(exporter, populatedReport, response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to write text to the response Writer.
|
||||
* @param exporter the JasperReports exporter to use
|
||||
* @param populatedReport the populated {@code JasperPrint} to render
|
||||
* @param response the HTTP response the report should be rendered to
|
||||
* @throws Exception if rendering failed
|
||||
*/
|
||||
protected void renderReportUsingWriter(net.sf.jasperreports.engine.JRExporter exporter,
|
||||
JasperPrint populatedReport, HttpServletResponse response) throws Exception {
|
||||
|
||||
// Copy the encoding configured for the report into the response.
|
||||
String contentType = getContentType();
|
||||
String encoding = (String) exporter.getParameter(net.sf.jasperreports.engine.JRExporterParameter.CHARACTER_ENCODING);
|
||||
if (encoding != null) {
|
||||
// Only apply encoding if content type is specified but does not contain charset clause already.
|
||||
if (contentType != null && !contentType.toLowerCase().contains(WebUtils.CONTENT_TYPE_CHARSET_PREFIX)) {
|
||||
contentType = contentType + WebUtils.CONTENT_TYPE_CHARSET_PREFIX + encoding;
|
||||
}
|
||||
}
|
||||
response.setContentType(contentType);
|
||||
|
||||
// Render report into HttpServletResponse's Writer.
|
||||
JasperReportsUtils.render(exporter, populatedReport, response.getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to write binary output to the response OutputStream.
|
||||
* @param exporter the JasperReports exporter to use
|
||||
* @param populatedReport the populated {@code JasperPrint} to render
|
||||
* @param response the HTTP response the report should be rendered to
|
||||
* @throws Exception if rendering failed
|
||||
*/
|
||||
protected void renderReportUsingOutputStream(net.sf.jasperreports.engine.JRExporter exporter,
|
||||
JasperPrint populatedReport, HttpServletResponse response) throws Exception {
|
||||
|
||||
// IE workaround: write into byte array first.
|
||||
ByteArrayOutputStream baos = createTemporaryOutputStream();
|
||||
JasperReportsUtils.render(exporter, populatedReport, baos);
|
||||
writeToResponse(response, baos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a JasperReports exporter for a specific output format,
|
||||
* which will be used to render the report to the HTTP response.
|
||||
* <p>The {@code useWriter} method determines whether the
|
||||
* output will be written as text or as binary content.
|
||||
* @see #useWriter()
|
||||
*/
|
||||
protected abstract net.sf.jasperreports.engine.JRExporter createExporter();
|
||||
|
||||
/**
|
||||
* Return whether to use a {@code java.io.Writer} to write text content
|
||||
* to the HTTP response. Else, a {@code java.io.OutputStream} will be used,
|
||||
* to write binary content to the response.
|
||||
* @see javax.servlet.ServletResponse#getWriter()
|
||||
* @see javax.servlet.ServletResponse#getOutputStream()
|
||||
*/
|
||||
protected abstract boolean useWriter();
|
||||
|
||||
}
|
|
@ -1,848 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import net.sf.jasperreports.engine.JRDataSource;
|
||||
import net.sf.jasperreports.engine.JRDataSourceProvider;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.JasperCompileManager;
|
||||
import net.sf.jasperreports.engine.JasperFillManager;
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.design.JasperDesign;
|
||||
import net.sf.jasperreports.engine.util.JRLoader;
|
||||
import net.sf.jasperreports.engine.xml.JRXmlLoader;
|
||||
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.support.MessageSourceResourceBundle;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.ui.jasperreports.JasperReportsUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.servlet.support.RequestContext;
|
||||
import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
||||
|
||||
/**
|
||||
* Base class for all JasperReports views. Applies on-the-fly compilation
|
||||
* of report designs as required and coordinates the rendering process.
|
||||
* The resource path of the main report needs to be specified as {@code url}.
|
||||
*
|
||||
* <p>This class is responsible for getting report data from the model that has
|
||||
* been provided to the view. The default implementation checks for a model object
|
||||
* under the specified {@code reportDataKey} first, then falls back to looking
|
||||
* for a value of type {@code JRDataSource}, {@code java.util.Collection},
|
||||
* object array (in that order).
|
||||
*
|
||||
* <p>If no {@code JRDataSource} can be found in the model, then reports will
|
||||
* be filled using the configured {@code javax.sql.DataSource} if any. If neither
|
||||
* a {@code JRDataSource} or {@code javax.sql.DataSource} is available then
|
||||
* an {@code IllegalArgumentException} is raised.
|
||||
*
|
||||
* <p>Provides support for sub-reports through the {@code subReportUrls} and
|
||||
* {@code subReportDataKeys} properties.
|
||||
*
|
||||
* <p>When using sub-reports, the master report should be configured using the
|
||||
* {@code url} property and the sub-reports files should be configured using
|
||||
* the {@code subReportUrls} property. Each entry in the {@code subReportUrls}
|
||||
* Map corresponds to an individual sub-report. The key of an entry must match up
|
||||
* to a sub-report parameter in your report file of type
|
||||
* {@code net.sf.jasperreports.engine.JasperReport},
|
||||
* and the value of an entry must be the URL for the sub-report file.
|
||||
*
|
||||
* <p>For sub-reports that require an instance of {@code JRDataSource}, that is,
|
||||
* they don't have a hard-coded query for data retrieval, you can include the
|
||||
* appropriate data in your model as would with the data source for the parent report.
|
||||
* However, you must provide a List of parameter names that need to be converted to
|
||||
* {@code JRDataSource} instances for the sub-report via the
|
||||
* {@code subReportDataKeys} property. When using {@code JRDataSource}
|
||||
* instances for sub-reports, you <i>must</i> specify a value for the
|
||||
* {@code reportDataKey} property, indicating the data to use for the main report.
|
||||
*
|
||||
* <p>Allows for exporter parameters to be configured declatively using the
|
||||
* {@code exporterParameters} property. This is a {@code Map} typed
|
||||
* property where the key of an entry corresponds to the fully-qualified name
|
||||
* of the static field for the {@code JRExporterParameter} and the value
|
||||
* of an entry is the value you want to assign to the exporter parameter.
|
||||
*
|
||||
* <p>Response headers can be controlled via the {@code headers} property. Spring
|
||||
* will attempt to set the correct value for the {@code Content-Diposition} header
|
||||
* so that reports render correctly in Internet Explorer. However, you can override this
|
||||
* setting through the {@code headers} property.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
* @see #setUrl
|
||||
* @see #setReportDataKey
|
||||
* @see #setSubReportUrls
|
||||
* @see #setSubReportDataKeys
|
||||
* @see #setHeaders
|
||||
* @see #setExporterParameters
|
||||
* @see #setJdbcDataSource
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public abstract class AbstractJasperReportsView extends AbstractUrlBasedView {
|
||||
|
||||
/**
|
||||
* Constant that defines "Content-Disposition" header.
|
||||
*/
|
||||
protected static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||
|
||||
/**
|
||||
* The default Content-Disposition header. Used to make IE play nice.
|
||||
*/
|
||||
protected static final String CONTENT_DISPOSITION_INLINE = "inline";
|
||||
|
||||
|
||||
/**
|
||||
* A String key used to lookup the {@code JRDataSource} in the model.
|
||||
*/
|
||||
private String reportDataKey;
|
||||
|
||||
/**
|
||||
* Stores the paths to any sub-report files used by this top-level report,
|
||||
* along with the keys they are mapped to in the top-level report file.
|
||||
*/
|
||||
private Properties subReportUrls;
|
||||
|
||||
/**
|
||||
* Stores the names of any data source objects that need to be converted to
|
||||
* {@code JRDataSource} instances and included in the report parameters
|
||||
* to be passed on to a sub-report.
|
||||
*/
|
||||
private String[] subReportDataKeys;
|
||||
|
||||
/**
|
||||
* Stores the headers to written with each response
|
||||
*/
|
||||
private Properties headers;
|
||||
|
||||
/**
|
||||
* Stores the exporter parameters passed in by the user as passed in by the user. May be keyed as
|
||||
* {@code String}s with the fully qualified name of the exporter parameter field.
|
||||
*/
|
||||
private Map<?, ?> exporterParameters = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Stores the converted exporter parameters - keyed by {@code JRExporterParameter}.
|
||||
*/
|
||||
private Map<net.sf.jasperreports.engine.JRExporterParameter, Object> convertedExporterParameters;
|
||||
|
||||
/**
|
||||
* Stores the {@code DataSource}, if any, used as the report data source.
|
||||
*/
|
||||
private DataSource jdbcDataSource;
|
||||
|
||||
/**
|
||||
* The {@code JasperReport} that is used to render the view.
|
||||
*/
|
||||
private JasperReport report;
|
||||
|
||||
/**
|
||||
* Holds mappings between sub-report keys and {@code JasperReport} objects.
|
||||
*/
|
||||
private Map<String, JasperReport> subReports;
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the model attribute that represents the report data.
|
||||
* If not specified, the model map will be searched for a matching value type.
|
||||
* <p>A {@code JRDataSource} will be taken as-is. For other types, conversion
|
||||
* will apply: By default, a {@code java.util.Collection} will be converted
|
||||
* to {@code JRBeanCollectionDataSource}, and an object array to
|
||||
* {@code JRBeanArrayDataSource}.
|
||||
* <p><b>Note:</b> If you pass in a Collection or object array in the model map
|
||||
* for use as plain report parameter, rather than as report data to extract fields
|
||||
* from, you need to specify the key for the actual report data to use, to avoid
|
||||
* mis-detection of report data by type.
|
||||
* @see #convertReportData
|
||||
* @see net.sf.jasperreports.engine.JRDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
|
||||
*/
|
||||
public void setReportDataKey(String reportDataKey) {
|
||||
this.reportDataKey = reportDataKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify resource paths which must be loaded as instances of
|
||||
* {@code JasperReport} and passed to the JasperReports engine for
|
||||
* rendering as sub-reports, under the same keys as in this mapping.
|
||||
* @param subReports mapping between model keys and resource paths
|
||||
* (Spring resource locations)
|
||||
* @see #setUrl
|
||||
* @see org.springframework.context.ApplicationContext#getResource
|
||||
*/
|
||||
public void setSubReportUrls(Properties subReports) {
|
||||
this.subReportUrls = subReports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of names corresponding to the model parameters that will contain
|
||||
* data source objects for use in sub-reports. Spring will convert these objects
|
||||
* to instances of {@code JRDataSource} where applicable and will then
|
||||
* include the resulting {@code JRDataSource} in the parameters passed into
|
||||
* the JasperReports engine.
|
||||
* <p>The name specified in the list should correspond to an attribute in the
|
||||
* model Map, and to a sub-report data source parameter in your report file.
|
||||
* If you pass in {@code JRDataSource} objects as model attributes,
|
||||
* specifying this list of keys is not required.
|
||||
* <p>If you specify a list of sub-report data keys, it is required to also
|
||||
* specify a {@code reportDataKey} for the main report, to avoid confusion
|
||||
* between the data source objects for the various reports involved.
|
||||
* @param subReportDataKeys list of names for sub-report data source objects
|
||||
* @see #setReportDataKey
|
||||
* @see #convertReportData
|
||||
* @see net.sf.jasperreports.engine.JRDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
|
||||
*/
|
||||
public void setSubReportDataKeys(String... subReportDataKeys) {
|
||||
this.subReportDataKeys = subReportDataKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the set of headers that are included in each of response.
|
||||
* @param headers the headers to write to each response.
|
||||
*/
|
||||
public void setHeaders(Properties headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exporter parameters that should be used when rendering a view.
|
||||
* @param parameters {@code Map} with the fully qualified field name
|
||||
* of the {@code JRExporterParameter} instance as key
|
||||
* (e.g. "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI")
|
||||
* and the value you wish to assign to the parameter as value
|
||||
*/
|
||||
public void setExporterParameters(Map<?, ?> parameters) {
|
||||
this.exporterParameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exporter parameters that this view uses, if any.
|
||||
*/
|
||||
public Map<?, ?> getExporterParameters() {
|
||||
return this.exporterParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to populate the converted exporter parameters.
|
||||
*/
|
||||
protected void setConvertedExporterParameters(Map<net.sf.jasperreports.engine.JRExporterParameter, Object> parameters) {
|
||||
this.convertedExporterParameters = parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to retrieve the converted exporter parameters.
|
||||
*/
|
||||
protected Map<net.sf.jasperreports.engine.JRExporterParameter, Object> getConvertedExporterParameters() {
|
||||
return this.convertedExporterParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the {@code javax.sql.DataSource} to use for reports with
|
||||
* embedded SQL statements.
|
||||
*/
|
||||
public void setJdbcDataSource(DataSource jdbcDataSource) {
|
||||
this.jdbcDataSource = jdbcDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@code javax.sql.DataSource} that this view uses, if any.
|
||||
*/
|
||||
protected DataSource getJdbcDataSource() {
|
||||
return this.jdbcDataSource;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* JasperReports views do not strictly required a 'url' value.
|
||||
* Alternatively, the {@link #getReport()} template method may be overridden.
|
||||
*/
|
||||
@Override
|
||||
protected boolean isUrlRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see that a valid report file URL is supplied in the
|
||||
* configuration. Compiles the report file is necessary.
|
||||
* <p>Subclasses can add custom initialization logic by overriding
|
||||
* the {@link #onInit} method.
|
||||
*/
|
||||
@Override
|
||||
protected final void initApplicationContext() throws ApplicationContextException {
|
||||
this.report = loadReport();
|
||||
|
||||
// Load sub reports if required, and check data source parameters.
|
||||
if (this.subReportUrls != null) {
|
||||
if (this.subReportDataKeys != null && this.subReportDataKeys.length > 0 && this.reportDataKey == null) {
|
||||
throw new ApplicationContextException(
|
||||
"'reportDataKey' for main report is required when specifying a value for 'subReportDataKeys'");
|
||||
}
|
||||
this.subReports = new HashMap<>(this.subReportUrls.size());
|
||||
for (Enumeration<?> urls = this.subReportUrls.propertyNames(); urls.hasMoreElements();) {
|
||||
String key = (String) urls.nextElement();
|
||||
String path = this.subReportUrls.getProperty(key);
|
||||
Resource resource = getApplicationContext().getResource(path);
|
||||
this.subReports.put(key, loadReport(resource));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert user-supplied exporterParameters.
|
||||
convertExporterParameters();
|
||||
|
||||
if (this.headers == null) {
|
||||
this.headers = new Properties();
|
||||
}
|
||||
if (!this.headers.containsKey(HEADER_CONTENT_DISPOSITION)) {
|
||||
this.headers.setProperty(HEADER_CONTENT_DISPOSITION, CONTENT_DISPOSITION_INLINE);
|
||||
}
|
||||
|
||||
onInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to add some custom initialization logic. Called
|
||||
* by {@link #initApplicationContext()} as soon as all standard initialization logic
|
||||
* has finished executing.
|
||||
* @see #initApplicationContext()
|
||||
*/
|
||||
protected void onInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the exporter parameters passed in by the user which may be keyed
|
||||
* by {@code String}s corresponding to the fully qualified name of the
|
||||
* {@code JRExporterParameter} into parameters which are keyed by
|
||||
* {@code JRExporterParameter}.
|
||||
* @see #getExporterParameter(Object)
|
||||
*/
|
||||
protected final void convertExporterParameters() {
|
||||
if (!CollectionUtils.isEmpty(this.exporterParameters)) {
|
||||
this.convertedExporterParameters =
|
||||
new HashMap<>(this.exporterParameters.size());
|
||||
for (Map.Entry<?, ?> entry : this.exporterParameters.entrySet()) {
|
||||
net.sf.jasperreports.engine.JRExporterParameter exporterParameter = getExporterParameter(entry.getKey());
|
||||
this.convertedExporterParameters.put(
|
||||
exporterParameter, convertParameterValue(exporterParameter, entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the supplied parameter value into the actual type required by the
|
||||
* corresponding {@code JRExporterParameter}.
|
||||
* <p>The default implementation simply converts the String values "true" and
|
||||
* "false" into corresponding {@code Boolean} objects, and tries to convert
|
||||
* String values that start with a digit into {@code Integer} objects
|
||||
* (simply keeping them as String if number conversion fails).
|
||||
* @param parameter the parameter key
|
||||
* @param value the parameter value
|
||||
* @return the converted parameter value
|
||||
*/
|
||||
protected Object convertParameterValue(net.sf.jasperreports.engine.JRExporterParameter parameter, Object value) {
|
||||
if (value instanceof String) {
|
||||
String str = (String) value;
|
||||
if ("true".equals(str)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
else if ("false".equals(str)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
else if (str.length() > 0 && Character.isDigit(str.charAt(0))) {
|
||||
// Looks like a number... let's try.
|
||||
try {
|
||||
return new Integer(str);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
// OK, then let's keep it as a String value.
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code JRExporterParameter} for the given parameter object,
|
||||
* converting it from a String if necessary.
|
||||
* @param parameter the parameter object, either a String or a JRExporterParameter
|
||||
* @return a JRExporterParameter for the given parameter object
|
||||
* @see #convertToExporterParameter(String)
|
||||
*/
|
||||
protected net.sf.jasperreports.engine.JRExporterParameter getExporterParameter(Object parameter) {
|
||||
if (parameter instanceof net.sf.jasperreports.engine.JRExporterParameter) {
|
||||
return (net.sf.jasperreports.engine.JRExporterParameter) parameter;
|
||||
}
|
||||
if (parameter instanceof String) {
|
||||
return convertToExporterParameter((String) parameter);
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter [" + parameter + "] is invalid type. Should be either String or JRExporterParameter.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given fully qualified field name to a corresponding
|
||||
* JRExporterParameter instance.
|
||||
* @param fqFieldName the fully qualified field name, consisting
|
||||
* of the class name followed by a dot followed by the field name
|
||||
* (e.g. "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI")
|
||||
* @return the corresponding JRExporterParameter instance
|
||||
*/
|
||||
protected net.sf.jasperreports.engine.JRExporterParameter convertToExporterParameter(String fqFieldName) {
|
||||
int index = fqFieldName.lastIndexOf('.');
|
||||
if (index == -1 || index == fqFieldName.length()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter name [" + fqFieldName + "] is not a valid static field. " +
|
||||
"The parameter name must map to a static field such as " +
|
||||
"[net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI]");
|
||||
}
|
||||
String className = fqFieldName.substring(0, index);
|
||||
String fieldName = fqFieldName.substring(index + 1);
|
||||
|
||||
try {
|
||||
Class<?> cls = ClassUtils.forName(className, getApplicationContext().getClassLoader());
|
||||
Field field = cls.getField(fieldName);
|
||||
|
||||
if (net.sf.jasperreports.engine.JRExporterParameter.class.isAssignableFrom(field.getType())) {
|
||||
try {
|
||||
return (net.sf.jasperreports.engine.JRExporterParameter) field.get(null);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to access field [" + fieldName + "] of class [" + className + "]. " +
|
||||
"Check that it is static and accessible.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Field [" + fieldName + "] on class [" + className +
|
||||
"] is not assignable from JRExporterParameter - check the type of this field.");
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
"Class [" + className + "] in key [" + fqFieldName + "] could not be found.");
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
throw new IllegalArgumentException("Field [" + fieldName + "] in key [" + fqFieldName +
|
||||
"] could not be found on class [" + className + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the main {@code JasperReport} from the specified {@code Resource}.
|
||||
* If the {@code Resource} points to an uncompiled report design file then the
|
||||
* report file is compiled dynamically and loaded into memory.
|
||||
* @return a {@code JasperReport} instance, or {@code null} if no main
|
||||
* report has been statically defined
|
||||
*/
|
||||
protected JasperReport loadReport() {
|
||||
String url = getUrl();
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
Resource mainReport = getApplicationContext().getResource(url);
|
||||
return loadReport(mainReport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a {@code JasperReport} from the specified {@code Resource}.
|
||||
* If the {@code Resource} points to an uncompiled report design file then
|
||||
* the report file is compiled dynamically and loaded into memory.
|
||||
* @param resource the {@code Resource} containing the report definition or design
|
||||
* @return a {@code JasperReport} instance
|
||||
*/
|
||||
protected final JasperReport loadReport(Resource resource) {
|
||||
try {
|
||||
String filename = resource.getFilename();
|
||||
if (filename != null) {
|
||||
if (filename.endsWith(".jasper")) {
|
||||
// Load pre-compiled report.
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Loading pre-compiled Jasper Report from " + resource);
|
||||
}
|
||||
InputStream is = resource.getInputStream();
|
||||
try {
|
||||
return (JasperReport) JRLoader.loadObject(is);
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
else if (filename.endsWith(".jrxml")) {
|
||||
// Compile report on-the-fly.
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Compiling Jasper Report loaded from " + resource);
|
||||
}
|
||||
InputStream is = resource.getInputStream();
|
||||
try {
|
||||
JasperDesign design = JRXmlLoader.load(is);
|
||||
return JasperCompileManager.compileReport(design);
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Report filename [" + filename + "] must end in either .jasper or .jrxml");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new ApplicationContextException(
|
||||
"Could not load JasperReports report from " + resource, ex);
|
||||
}
|
||||
catch (JRException ex) {
|
||||
throw new ApplicationContextException(
|
||||
"Could not parse JasperReports report from " + resource, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds the report data to use for rendering the report and then invokes the
|
||||
* {@link #renderReport} method that should be implemented by the subclass.
|
||||
* @param model the model map, as passed in for view rendering. Must contain
|
||||
* a report data value that can be converted to a {@code JRDataSource},
|
||||
* according to the rules of the {@link #fillReport} method.
|
||||
*/
|
||||
@Override
|
||||
protected void renderMergedOutputModel(
|
||||
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
if (this.subReports != null) {
|
||||
// Expose sub-reports as model attributes.
|
||||
model.putAll(this.subReports);
|
||||
|
||||
// Transform any collections etc into JRDataSources for sub reports.
|
||||
if (this.subReportDataKeys != null) {
|
||||
for (String key : this.subReportDataKeys) {
|
||||
model.put(key, convertReportData(model.get(key)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expose Spring-managed Locale and MessageSource.
|
||||
exposeLocalizationContext(model, request);
|
||||
|
||||
// Fill the report.
|
||||
JasperPrint filledReport = fillReport(model);
|
||||
postProcessReport(filledReport, model);
|
||||
|
||||
// Prepare response and render report.
|
||||
populateHeaders(response);
|
||||
renderReport(filledReport, model, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose current Spring-managed Locale and MessageSource to JasperReports i18n
|
||||
* ($R expressions etc). The MessageSource should only be exposed as JasperReports
|
||||
* resource bundle if no such bundle is defined in the report itself.
|
||||
* <p>The default implementation exposes the Spring RequestContext Locale and a
|
||||
* MessageSourceResourceBundle adapter for the Spring ApplicationContext,
|
||||
* analogous to the {@code JstlUtils.exposeLocalizationContext} method.
|
||||
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
|
||||
* @see org.springframework.context.support.MessageSourceResourceBundle
|
||||
* @see #getApplicationContext()
|
||||
* @see net.sf.jasperreports.engine.JRParameter#REPORT_LOCALE
|
||||
* @see net.sf.jasperreports.engine.JRParameter#REPORT_RESOURCE_BUNDLE
|
||||
* @see org.springframework.web.servlet.support.JstlUtils#exposeLocalizationContext
|
||||
*/
|
||||
protected void exposeLocalizationContext(Map<String, Object> model, HttpServletRequest request) {
|
||||
RequestContext rc = new RequestContext(request, getServletContext());
|
||||
Locale locale = rc.getLocale();
|
||||
if (!model.containsKey(JRParameter.REPORT_LOCALE)) {
|
||||
model.put(JRParameter.REPORT_LOCALE, locale);
|
||||
}
|
||||
TimeZone timeZone = rc.getTimeZone();
|
||||
if (timeZone != null && !model.containsKey(JRParameter.REPORT_TIME_ZONE)) {
|
||||
model.put(JRParameter.REPORT_TIME_ZONE, timeZone);
|
||||
}
|
||||
JasperReport report = getReport();
|
||||
if ((report == null || report.getResourceBundle() == null) &&
|
||||
!model.containsKey(JRParameter.REPORT_RESOURCE_BUNDLE)) {
|
||||
model.put(JRParameter.REPORT_RESOURCE_BUNDLE,
|
||||
new MessageSourceResourceBundle(rc.getMessageSource(), locale));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a populated {@code JasperPrint} instance from the configured
|
||||
* {@code JasperReport} instance.
|
||||
* <p>By default, this method will use any {@code JRDataSource} instance
|
||||
* (or wrappable {@code Object}) that can be located using {@link #setReportDataKey},
|
||||
* a lookup for type {@code JRDataSource} in the model Map, or a special value
|
||||
* retrieved via {@link #getReportData}.
|
||||
* <p>If no {@code JRDataSource} can be found, this method will use a JDBC
|
||||
* {@code Connection} obtained from the configured {@code javax.sql.DataSource}
|
||||
* (or a DataSource attribute in the model). If no JDBC DataSource can be found
|
||||
* either, the JasperReports engine will be invoked with plain model Map,
|
||||
* assuming that the model contains parameters that identify the source
|
||||
* for report data (e.g. Hibernate or JPA queries).
|
||||
* @param model the model for this request
|
||||
* @throws IllegalArgumentException if no {@code JRDataSource} can be found
|
||||
* and no {@code javax.sql.DataSource} is supplied
|
||||
* @throws SQLException if there is an error when populating the report using
|
||||
* the {@code javax.sql.DataSource}
|
||||
* @throws JRException if there is an error when populating the report using
|
||||
* a {@code JRDataSource}
|
||||
* @return the populated {@code JasperPrint} instance
|
||||
* @see #getReportData
|
||||
* @see #setJdbcDataSource
|
||||
*/
|
||||
protected JasperPrint fillReport(Map<String, Object> model) throws Exception {
|
||||
// Determine main report.
|
||||
JasperReport report = getReport();
|
||||
if (report == null) {
|
||||
throw new IllegalStateException("No main report defined for 'fillReport' - " +
|
||||
"specify a 'url' on this view or override 'getReport()' or 'fillReport(Map)'");
|
||||
}
|
||||
|
||||
JRDataSource jrDataSource = null;
|
||||
DataSource jdbcDataSourceToUse = null;
|
||||
|
||||
// Try model attribute with specified name.
|
||||
if (this.reportDataKey != null) {
|
||||
Object reportDataValue = model.get(this.reportDataKey);
|
||||
if (reportDataValue instanceof DataSource) {
|
||||
jdbcDataSourceToUse = (DataSource) reportDataValue;
|
||||
}
|
||||
else {
|
||||
jrDataSource = convertReportData(reportDataValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Collection<?> values = model.values();
|
||||
jrDataSource = CollectionUtils.findValueOfType(values, JRDataSource.class);
|
||||
if (jrDataSource == null) {
|
||||
JRDataSourceProvider provider = CollectionUtils.findValueOfType(values, JRDataSourceProvider.class);
|
||||
if (provider != null) {
|
||||
jrDataSource = createReport(provider);
|
||||
}
|
||||
else {
|
||||
jdbcDataSourceToUse = CollectionUtils.findValueOfType(values, DataSource.class);
|
||||
if (jdbcDataSourceToUse == null) {
|
||||
jdbcDataSourceToUse = this.jdbcDataSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jdbcDataSourceToUse != null) {
|
||||
return doFillReport(report, model, jdbcDataSourceToUse);
|
||||
}
|
||||
else {
|
||||
// Determine JRDataSource for main report.
|
||||
if (jrDataSource == null) {
|
||||
jrDataSource = getReportData(model);
|
||||
}
|
||||
if (jrDataSource != null) {
|
||||
// Use the JasperReports JRDataSource.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Filling report with JRDataSource [" + jrDataSource + "]");
|
||||
}
|
||||
return JasperFillManager.fillReport(report, model, jrDataSource);
|
||||
}
|
||||
else {
|
||||
// Assume that the model contains parameters that identify
|
||||
// the source for report data (e.g. Hibernate or JPA queries).
|
||||
logger.debug("Filling report with plain model");
|
||||
return JasperFillManager.fillReport(report, model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the given report using the given JDBC DataSource and model.
|
||||
*/
|
||||
private JasperPrint doFillReport(JasperReport report, Map<String, Object> model, DataSource ds) throws Exception {
|
||||
// Use the JDBC DataSource.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Filling report using JDBC DataSource [" + ds + "]");
|
||||
}
|
||||
Connection con = ds.getConnection();
|
||||
try {
|
||||
return JasperFillManager.fillReport(report, model, con);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
con.close();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.debug("Could not close JDBC Connection", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the headers in the {@code HttpServletResponse} with the
|
||||
* headers supplied by the user.
|
||||
*/
|
||||
private void populateHeaders(HttpServletResponse response) {
|
||||
// Apply the headers to the response.
|
||||
for (Enumeration<?> en = this.headers.propertyNames(); en.hasMoreElements();) {
|
||||
String key = (String) en.nextElement();
|
||||
response.addHeader(key, this.headers.getProperty(key));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the {@code JasperReport} to fill.
|
||||
* Called by {@link #fillReport}.
|
||||
* <p>The default implementation returns the report as statically configured
|
||||
* through the 'url' property (and loaded by {@link #loadReport()}).
|
||||
* Can be overridden in subclasses in order to dynamically obtain a
|
||||
* {@code JasperReport} instance. As an alternative, consider
|
||||
* overriding the {@link #fillReport} template method itself.
|
||||
* @return an instance of {@code JasperReport}
|
||||
*/
|
||||
protected JasperReport getReport() {
|
||||
return this.report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an appropriate {@code JRDataSource} for passed-in report data.
|
||||
* Called by {@link #fillReport} when its own lookup steps were not successful.
|
||||
* <p>The default implementation looks for a value of type {@code java.util.Collection}
|
||||
* or object array (in that order). Can be overridden in subclasses.
|
||||
* @param model the model map, as passed in for view rendering
|
||||
* @return the {@code JRDataSource} or {@code null} if the data source is not found
|
||||
* @see #getReportDataTypes
|
||||
* @see #convertReportData
|
||||
*/
|
||||
protected JRDataSource getReportData(Map<String, Object> model) {
|
||||
// Try to find matching attribute, of given prioritized types.
|
||||
Object value = CollectionUtils.findValueOfType(model.values(), getReportDataTypes());
|
||||
return (value != null ? convertReportData(value) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given report data value to a {@code JRDataSource}.
|
||||
* <p>The default implementation delegates to {@code JasperReportUtils} unless
|
||||
* the report data value is an instance of {@code JRDataSourceProvider}.
|
||||
* A {@code JRDataSource}, {@code JRDataSourceProvider},
|
||||
* {@code java.util.Collection} or object array is detected.
|
||||
* {@code JRDataSource}s are returned as is, whilst {@code JRDataSourceProvider}s
|
||||
* are used to create an instance of {@code JRDataSource} which is then returned.
|
||||
* The latter two are converted to {@code JRBeanCollectionDataSource} or
|
||||
* {@code JRBeanArrayDataSource}, respectively.
|
||||
* @param value the report data value to convert
|
||||
* @return the JRDataSource
|
||||
* @throws IllegalArgumentException if the value could not be converted
|
||||
* @see org.springframework.ui.jasperreports.JasperReportsUtils#convertReportData
|
||||
* @see net.sf.jasperreports.engine.JRDataSource
|
||||
* @see net.sf.jasperreports.engine.JRDataSourceProvider
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
|
||||
* @see net.sf.jasperreports.engine.data.JRBeanArrayDataSource
|
||||
*/
|
||||
protected JRDataSource convertReportData(Object value) throws IllegalArgumentException {
|
||||
if (value instanceof JRDataSourceProvider) {
|
||||
return createReport((JRDataSourceProvider) value);
|
||||
}
|
||||
else {
|
||||
return JasperReportsUtils.convertReportData(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a report using the given provider.
|
||||
* @param provider the JRDataSourceProvider to use
|
||||
* @return the created report
|
||||
*/
|
||||
protected JRDataSource createReport(JRDataSourceProvider provider) {
|
||||
try {
|
||||
JasperReport report = getReport();
|
||||
if (report == null) {
|
||||
throw new IllegalStateException("No main report defined for JRDataSourceProvider - " +
|
||||
"specify a 'url' on this view or override 'getReport()'");
|
||||
}
|
||||
return provider.create(report);
|
||||
}
|
||||
catch (JRException ex) {
|
||||
throw new IllegalArgumentException("Supplied JRDataSourceProvider is invalid", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value types that can be converted to a {@code JRDataSource},
|
||||
* in prioritized order. Should only return types that the
|
||||
* {@link #convertReportData} method is actually able to convert.
|
||||
* <p>Default value types are: {@code java.util.Collection} and {@code Object} array.
|
||||
* @return the value types in prioritized order
|
||||
*/
|
||||
protected Class<?>[] getReportDataTypes() {
|
||||
return new Class<?>[] {Collection.class, Object[].class};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template method to be overridden for custom post-processing of the
|
||||
* populated report. Invoked after filling but before rendering.
|
||||
* <p>The default implementation is empty.
|
||||
* @param populatedReport the populated {@code JasperPrint}
|
||||
* @param model the map containing report parameters
|
||||
* @throws Exception if post-processing failed
|
||||
*/
|
||||
protected void postProcessReport(JasperPrint populatedReport, Map<String, Object> model) throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method to perform the actual rendering process.
|
||||
* <p>Note that the content type has not been set yet: Implementers should build
|
||||
* a content type String and set it via {@code response.setContentType}.
|
||||
* If necessary, this can include a charset clause for a specific encoding.
|
||||
* The latter will only be necessary for textual output onto a Writer, and only
|
||||
* in case of the encoding being specified in the JasperReports exporter parameters.
|
||||
* <p><b>WARNING:</b> Implementers should not use {@code response.setCharacterEncoding}
|
||||
* unless they are willing to depend on Servlet API 2.4 or higher. Prefer a
|
||||
* concatenated content type String with a charset clause instead.
|
||||
* @param populatedReport the populated {@code JasperPrint} to render
|
||||
* @param model the map containing report parameters
|
||||
* @param response the HTTP response the report should be rendered to
|
||||
* @throws Exception if rendering failed
|
||||
* @see #getContentType()
|
||||
* @see javax.servlet.ServletResponse#setContentType
|
||||
* @see javax.servlet.ServletResponse#setCharacterEncoding
|
||||
*/
|
||||
protected abstract void renderReport(
|
||||
JasperPrint populatedReport, Map<String, Object> model, HttpServletResponse response)
|
||||
throws Exception;
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Configurable JasperReports View, allowing to specify the JasperReports exporter
|
||||
* to be specified through bean properties rather than through the view class name.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
* @see JasperReportsCsvView
|
||||
* @see JasperReportsHtmlView
|
||||
* @see JasperReportsPdfView
|
||||
* @see JasperReportsXlsView
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class ConfigurableJasperReportsView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
private Class<? extends net.sf.jasperreports.engine.JRExporter> exporterClass;
|
||||
|
||||
private boolean useWriter = true;
|
||||
|
||||
|
||||
/**
|
||||
* Set the {@code JRExporter} implementation {@code Class} to use. Throws
|
||||
* {@link IllegalArgumentException} if the {@code Class} doesn't implement
|
||||
* {@code JRExporter}. Required setting, as it does not have a default.
|
||||
*/
|
||||
public void setExporterClass(Class<? extends net.sf.jasperreports.engine.JRExporter> exporterClass) {
|
||||
Assert.isAssignable(net.sf.jasperreports.engine.JRExporter.class, exporterClass);
|
||||
this.exporterClass = exporterClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether or not the {@code JRExporter} writes to the {@link java.io.PrintWriter}
|
||||
* of the associated with the request ({@code true}) or whether it writes directly to the
|
||||
* {@link java.io.InputStream} of the request ({@code false}). Default is {@code true}.
|
||||
*/
|
||||
public void setUseWriter(boolean useWriter) {
|
||||
this.useWriter = useWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the {@link #setExporterClass(Class) exporterClass} property is specified.
|
||||
*/
|
||||
@Override
|
||||
protected void onInit() {
|
||||
if (this.exporterClass == null) {
|
||||
throw new IllegalArgumentException("exporterClass is required");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new instance of the specified {@link net.sf.jasperreports.engine.JRExporter} class.
|
||||
* @see #setExporterClass(Class)
|
||||
* @see BeanUtils#instantiateClass(Class)
|
||||
*/
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return BeanUtils.instantiateClass(this.exporterClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates how the {@code JRExporter} should render its data.
|
||||
* @see #setUseWriter(boolean)
|
||||
*/
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return this.useWriter;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import net.sf.jasperreports.engine.export.JRCsvExporter;
|
||||
|
||||
/**
|
||||
* Implementation of {@code AbstractJasperReportsSingleFormatView}
|
||||
* that renders report results in CSV format.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class JasperReportsCsvView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
public JasperReportsCsvView() {
|
||||
setContentType("text/csv");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return new JRCsvExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* Implementation of {@code AbstractJasperReportsSingleFormatView}
|
||||
* that renders report results in HTML format.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class JasperReportsHtmlView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
public JasperReportsHtmlView() {
|
||||
setContentType("text/html");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return new net.sf.jasperreports.engine.export.JRHtmlExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,219 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* JasperReports view class that allows for the actual rendering format
|
||||
* to be specified at runtime using a parameter contained in the model.
|
||||
*
|
||||
* <p>This view works on the concept of a format key and a mapping key.
|
||||
* The format key is used to pass the mapping key from your {@code Controller}
|
||||
* to Spring through as part of the model and the mapping key is used to map
|
||||
* a logical format to an actual JasperReports view class.
|
||||
*
|
||||
* <p>For example, you might add the following code to your {@code Controller}:
|
||||
*
|
||||
* <pre class="code">
|
||||
* Map<String, Object> model = new HashMap<String, Object>();
|
||||
* model.put("format", "pdf");</pre>
|
||||
*
|
||||
* Here {@code format} is the format key and {@code pdf} is the mapping key.
|
||||
* When rendering a report, this class looks for a model parameter under the
|
||||
* format key, which by default is {@code format}. It then uses the value of
|
||||
* this parameter to lookup the actual {@code View} class to use.
|
||||
*
|
||||
* <p>The default mappings for the format lookup are:
|
||||
*
|
||||
* <p><ul>
|
||||
* <li>{@code csv} - {@code JasperReportsCsvView}</li>
|
||||
* <li>{@code html} - {@code JasperReportsHtmlView}</li>
|
||||
* <li>{@code pdf} - {@code JasperReportsPdfView}</li>
|
||||
* <li>{@code xls} - {@code JasperReportsXlsView}</li>
|
||||
* <li>{@code xlsx} - {@code JasperReportsXlsxView}</li> (as of Spring 4.2)
|
||||
* </ul>
|
||||
*
|
||||
* <p>The format key can be changed using the {@code formatKey} property.
|
||||
* The applicable key-to-view-class mappings can be configured using the
|
||||
* {@code formatMappings} property.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.5
|
||||
* @see #setFormatKey
|
||||
* @see #setFormatMappings
|
||||
*/
|
||||
public class JasperReportsMultiFormatView extends AbstractJasperReportsView {
|
||||
|
||||
/**
|
||||
* Default value used for format key: "format"
|
||||
*/
|
||||
public static final String DEFAULT_FORMAT_KEY = "format";
|
||||
|
||||
|
||||
/**
|
||||
* The key of the model parameter that holds the format key.
|
||||
*/
|
||||
private String formatKey = DEFAULT_FORMAT_KEY;
|
||||
|
||||
/**
|
||||
* Stores the format mappings, with the format discriminator
|
||||
* as key and the corresponding view class as value.
|
||||
*/
|
||||
private Map<String, Class<? extends AbstractJasperReportsView>> formatMappings;
|
||||
|
||||
/**
|
||||
* Stores the mappings of mapping keys to Content-Disposition header values.
|
||||
*/
|
||||
private Properties contentDispositionMappings;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@code JasperReportsMultiFormatView} instance
|
||||
* with a default set of mappings.
|
||||
*/
|
||||
public JasperReportsMultiFormatView() {
|
||||
this.formatMappings = new HashMap<>(4);
|
||||
this.formatMappings.put("csv", JasperReportsCsvView.class);
|
||||
this.formatMappings.put("html", JasperReportsHtmlView.class);
|
||||
this.formatMappings.put("pdf", JasperReportsPdfView.class);
|
||||
this.formatMappings.put("xls", JasperReportsXlsView.class);
|
||||
this.formatMappings.put("xlsx", JasperReportsXlsxView.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the key of the model parameter that holds the format discriminator.
|
||||
* Default is "format".
|
||||
*/
|
||||
public void setFormatKey(String formatKey) {
|
||||
this.formatKey = formatKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mappings of format discriminators to view class names.
|
||||
* The default mappings are:
|
||||
* <p><ul>
|
||||
* <li>{@code csv} - {@code JasperReportsCsvView}</li>
|
||||
* <li>{@code html} - {@code JasperReportsHtmlView}</li>
|
||||
* <li>{@code pdf} - {@code JasperReportsPdfView}</li>
|
||||
* <li>{@code xls} - {@code JasperReportsXlsView}</li>
|
||||
* <li>{@code xlsx} - {@code JasperReportsXlsxView}</li> (as of Spring 4.2)
|
||||
* </ul>
|
||||
*/
|
||||
public void setFormatMappings(Map<String, Class<? extends AbstractJasperReportsView>> formatMappings) {
|
||||
if (CollectionUtils.isEmpty(formatMappings)) {
|
||||
throw new IllegalArgumentException("'formatMappings' must not be empty");
|
||||
}
|
||||
this.formatMappings = formatMappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mappings of {@code Content-Disposition} header values to
|
||||
* mapping keys. If specified, Spring will look at these mappings to determine
|
||||
* the value of the {@code Content-Disposition} header for a given
|
||||
* format mapping.
|
||||
*/
|
||||
public void setContentDispositionMappings(Properties mappings) {
|
||||
this.contentDispositionMappings = mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mappings of {@code Content-Disposition} header values to
|
||||
* mapping keys. Mainly available for configuration through property paths
|
||||
* that specify individual keys.
|
||||
*/
|
||||
public Properties getContentDispositionMappings() {
|
||||
if (this.contentDispositionMappings == null) {
|
||||
this.contentDispositionMappings = new Properties();
|
||||
}
|
||||
return this.contentDispositionMappings;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean generatesDownloadContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the format key in the model using the configured discriminator key and uses this
|
||||
* key to lookup the appropriate view class from the mappings. The rendering of the
|
||||
* report is then delegated to an instance of that view class.
|
||||
*/
|
||||
@Override
|
||||
protected void renderReport(JasperPrint populatedReport, Map<String, Object> model, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
String format = (String) model.get(this.formatKey);
|
||||
if (format == null) {
|
||||
throw new IllegalArgumentException("No format found in model");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Rendering report using format mapping key [" + format + "]");
|
||||
}
|
||||
|
||||
Class<? extends AbstractJasperReportsView> viewClass = this.formatMappings.get(format);
|
||||
if (viewClass == null) {
|
||||
throw new IllegalArgumentException("Format discriminator [" + format + "] is not a configured mapping");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Rendering report using view class [" + viewClass.getName() + "]");
|
||||
}
|
||||
|
||||
AbstractJasperReportsView view = BeanUtils.instantiateClass(viewClass);
|
||||
// Can skip most initialization since all relevant URL processing
|
||||
// has been done - just need to convert parameters on the sub view.
|
||||
view.setExporterParameters(getExporterParameters());
|
||||
view.setConvertedExporterParameters(getConvertedExporterParameters());
|
||||
|
||||
// Prepare response and render report.
|
||||
populateContentDispositionIfNecessary(response, format);
|
||||
view.renderReport(populatedReport, model, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds/overwrites the {@code Content-Disposition} header value with the format-specific
|
||||
* value if the mappings have been specified and a valid one exists for the given format.
|
||||
* @param response the {@code HttpServletResponse} to set the header in
|
||||
* @param format the format key of the mapping
|
||||
* @see #setContentDispositionMappings
|
||||
*/
|
||||
private void populateContentDispositionIfNecessary(HttpServletResponse response, String format) {
|
||||
if (this.contentDispositionMappings != null) {
|
||||
String header = this.contentDispositionMappings.getProperty(format);
|
||||
if (header != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Setting Content-Disposition header to: [" + header + "]");
|
||||
}
|
||||
response.setHeader(HEADER_CONTENT_DISPOSITION, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporter;
|
||||
|
||||
/**
|
||||
* Implementation of {@code AbstractJasperReportsSingleFormatView}
|
||||
* that renders report results in PDF format.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class JasperReportsPdfView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
public JasperReportsPdfView() {
|
||||
setContentType("application/pdf");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return new JRPdfExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.web.servlet.ViewResolver} implementation that
|
||||
* resolves instances of {@link AbstractJasperReportsView} by translating
|
||||
* the supplied view name into the URL of the report file.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 1.2.6
|
||||
*/
|
||||
public class JasperReportsViewResolver extends UrlBasedViewResolver {
|
||||
|
||||
private String reportDataKey;
|
||||
|
||||
private Properties subReportUrls;
|
||||
|
||||
private String[] subReportDataKeys;
|
||||
|
||||
private Properties headers;
|
||||
|
||||
private Map<String, Object> exporterParameters = new HashMap<>();
|
||||
|
||||
private DataSource jdbcDataSource;
|
||||
|
||||
|
||||
/**
|
||||
* Requires the view class to be a subclass of {@link AbstractJasperReportsView}.
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> requiredViewClass() {
|
||||
return AbstractJasperReportsView.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code reportDataKey} the view class should use.
|
||||
* @see AbstractJasperReportsView#setReportDataKey
|
||||
*/
|
||||
public void setReportDataKey(String reportDataKey) {
|
||||
this.reportDataKey = reportDataKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code subReportUrls} the view class should use.
|
||||
* @see AbstractJasperReportsView#setSubReportUrls
|
||||
*/
|
||||
public void setSubReportUrls(Properties subReportUrls) {
|
||||
this.subReportUrls = subReportUrls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code subReportDataKeys} the view class should use.
|
||||
* @see AbstractJasperReportsView#setSubReportDataKeys
|
||||
*/
|
||||
public void setSubReportDataKeys(String... subReportDataKeys) {
|
||||
this.subReportDataKeys = subReportDataKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code headers} the view class should use.
|
||||
* @see AbstractJasperReportsView#setHeaders
|
||||
*/
|
||||
public void setHeaders(Properties headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code exporterParameters} the view class should use.
|
||||
* @see AbstractJasperReportsView#setExporterParameters
|
||||
*/
|
||||
public void setExporterParameters(Map<String, Object> exporterParameters) {
|
||||
this.exporterParameters = exporterParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link DataSource} the view class should use.
|
||||
* @see AbstractJasperReportsView#setJdbcDataSource
|
||||
*/
|
||||
public void setJdbcDataSource(DataSource jdbcDataSource) {
|
||||
this.jdbcDataSource = jdbcDataSource;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
|
||||
AbstractJasperReportsView view = (AbstractJasperReportsView) super.buildView(viewName);
|
||||
view.setReportDataKey(this.reportDataKey);
|
||||
view.setSubReportUrls(this.subReportUrls);
|
||||
view.setSubReportDataKeys(this.subReportDataKeys);
|
||||
view.setHeaders(this.headers);
|
||||
view.setExporterParameters(this.exporterParameters);
|
||||
view.setJdbcDataSource(this.jdbcDataSource);
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import net.sf.jasperreports.engine.export.JRXlsExporter;
|
||||
|
||||
/**
|
||||
* Implementation of {@code AbstractJasperReportsSingleFormatView}
|
||||
* that renders report results in XLS format.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class JasperReportsXlsView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
public JasperReportsXlsView() {
|
||||
setContentType("application/vnd.ms-excel");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return new JRXlsExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
|
||||
|
||||
/**
|
||||
* Implementation of {@code AbstractJasperReportsSingleFormatView}
|
||||
* that renders report results in XLSX format.
|
||||
*
|
||||
* <p><b>This class is compatible with classic JasperReports releases back until 2.x.</b>
|
||||
* As a consequence, it keeps using the {@link net.sf.jasperreports.engine.JRExporter}
|
||||
* API which got deprecated as of JasperReports 5.5.2 (early 2014).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.2
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "rawtypes"})
|
||||
public class JasperReportsXlsxView extends AbstractJasperReportsSingleFormatView {
|
||||
|
||||
public JasperReportsXlsxView() {
|
||||
setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected net.sf.jasperreports.engine.JRExporter createExporter() {
|
||||
return new JRXlsxExporter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean useWriter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/**
|
||||
* Support classes for the integration of
|
||||
* <a href="http://jasperreports.sourceforge.net">JasperReports</a>
|
||||
* as Spring web view technology.
|
||||
* Contains various View implementations for JasperReports.
|
||||
*/
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public abstract class AbstractConfigurableJasperReportsViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void noConfiguredExporter() throws Exception {
|
||||
ConfigurableJasperReportsView view = new ConfigurableJasperReportsView();
|
||||
view.setUrl(COMPILED_REPORT);
|
||||
// Should not be able to set up view class without an exporter class.
|
||||
view.setApplicationContext(new StaticApplicationContext());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.tests.Assume;
|
||||
import org.springframework.ui.jasperreports.PersonBean;
|
||||
import org.springframework.ui.jasperreports.ProductBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public abstract class AbstractJasperReportsTests {
|
||||
|
||||
protected static final String COMPILED_REPORT = "/org/springframework/ui/jasperreports/DataSourceReport.jasper";
|
||||
|
||||
protected static final String UNCOMPILED_REPORT = "/org/springframework/ui/jasperreports/DataSourceReport.jrxml";
|
||||
|
||||
protected static final String SUB_REPORT_PARENT = "/org/springframework/ui/jasperreports/subReportParent.jrxml";
|
||||
|
||||
protected static final boolean canCompileReport = ClassUtils.isPresent(
|
||||
"org.eclipse.jdt.internal.compiler.Compiler", AbstractJasperReportsTests.class.getClassLoader());
|
||||
|
||||
|
||||
protected final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
protected final MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
{
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver());
|
||||
request.addPreferredLocale(Locale.GERMAN);
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void assumptions() {
|
||||
Assume.canLoadNativeDirFonts();
|
||||
}
|
||||
|
||||
|
||||
protected Map<String, Object> getModel() {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put("ReportTitle", "Dear Lord!");
|
||||
model.put("dataSource", new JRBeanCollectionDataSource(getData()));
|
||||
extendModel(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can extend the model if they need to.
|
||||
*/
|
||||
protected void extendModel(Map<String, Object> model) {
|
||||
}
|
||||
|
||||
protected List<Object> getData() {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (int x = 0; x < 10; x++) {
|
||||
PersonBean bean = new PersonBean();
|
||||
bean.setId(x);
|
||||
bean.setName("Rob Harrop");
|
||||
bean.setStreet("foo");
|
||||
list.add(bean);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected List<Object> getProductData() {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (int x = 0; x < 10; x++) {
|
||||
ProductBean bean = new ProductBean();
|
||||
bean.setId(x);
|
||||
bean.setName("Foo Bar");
|
||||
bean.setPrice(1.9f);
|
||||
bean.setQuantity(1.0f);
|
||||
list.add(bean);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,414 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import net.sf.jasperreports.engine.JRDataSource;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JasperReport;
|
||||
import net.sf.jasperreports.engine.data.JRAbstractBeanDataSourceProvider;
|
||||
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.ui.jasperreports.PersonBean;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractJasperReportsViewTests extends AbstractJasperReportsTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException exception = ExpectedException.none();
|
||||
|
||||
|
||||
/**
|
||||
* Simple test to see if compiled report succeeds.
|
||||
*/
|
||||
@Test
|
||||
public void compiledReport() throws Exception {
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(getModel(), request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
|
||||
assumeTrue(view instanceof AbstractJasperReportsSingleFormatView
|
||||
&& ((AbstractJasperReportsSingleFormatView) view).useWriter());
|
||||
|
||||
String output = response.getContentAsString();
|
||||
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uncompiledReport() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
view.render(getModel(), request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withInvalidPath() throws Exception {
|
||||
exception.expect(ApplicationContextException.class);
|
||||
getView("foo.jasper");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidExtension() throws Exception {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
getView("foo.bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentType() throws Exception {
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(getModel(), request, response);
|
||||
assertEquals("Response content type is incorrect", getDesiredContentType(), response.getContentType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutDatasource() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getStatus() == HttpServletResponse.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withCollection() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData());
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void withMultipleCollections() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData());
|
||||
model.put("otherData", new LinkedList());
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
// no clear data source found
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withJRDataSourceProvider() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("dataSource", new MockDataSourceProvider(PersonBean.class));
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void withSpecificCollection() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData());
|
||||
model.put("otherData", new LinkedList());
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.setReportDataKey("reportData");
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withArray() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData().toArray());
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withMultipleArrays() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData().toArray());
|
||||
model.put("otherData", new String[0]);
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(model, request, response);
|
||||
// no clear data source found
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSpecificArray() throws Exception {
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("reportData", getData().toArray());
|
||||
model.put("otherData", new String[0]);
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.setReportDataKey("reportData");
|
||||
view.render(model, request, response);
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSubReport() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.put("SubReportData", getProductData());
|
||||
|
||||
Properties subReports = new Properties();
|
||||
subReports.put("ProductsSubReport", "/org/springframework/ui/jasperreports/subReportChild.jrxml");
|
||||
|
||||
AbstractJasperReportsView view = getView(SUB_REPORT_PARENT);
|
||||
view.setReportDataKey("dataSource");
|
||||
view.setSubReportUrls(subReports);
|
||||
view.setSubReportDataKeys(new String[]{"SubReportData"});
|
||||
view.initApplicationContext();
|
||||
view.render(model, request, response);
|
||||
|
||||
assertTrue(response.getContentAsByteArray().length > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withNonExistentSubReport() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.put("SubReportData", getProductData());
|
||||
|
||||
Properties subReports = new Properties();
|
||||
subReports.put("ProductsSubReport", "org/springframework/ui/jasperreports/subReportChildFalse.jrxml");
|
||||
|
||||
AbstractJasperReportsView view = getView(SUB_REPORT_PARENT);
|
||||
view.setReportDataKey("dataSource");
|
||||
view.setSubReportUrls(subReports);
|
||||
view.setSubReportDataKeys(new String[]{"SubReportData"});
|
||||
|
||||
// Invalid report URL should throw ApplicationContextException
|
||||
exception.expect(ApplicationContextException.class);
|
||||
view.initApplicationContext();
|
||||
}
|
||||
|
||||
// TODO Determine why encoding does not get overridden.
|
||||
@Ignore("Disabled since encoding does not get overridden")
|
||||
@Test
|
||||
public void overrideExporterParameters() throws Exception {
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
|
||||
assumeTrue(view instanceof AbstractJasperReportsSingleFormatView
|
||||
&& ((AbstractJasperReportsSingleFormatView) view).useWriter());
|
||||
|
||||
String characterEncoding = "UTF-8";
|
||||
String overiddenCharacterEncoding = "ASCII";
|
||||
|
||||
Map<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put(net.sf.jasperreports.engine.JRExporterParameter.CHARACTER_ENCODING, characterEncoding);
|
||||
|
||||
view.setExporterParameters(parameters);
|
||||
view.convertExporterParameters();
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.put(net.sf.jasperreports.engine.JRExporterParameter.CHARACTER_ENCODING.toString(),
|
||||
overiddenCharacterEncoding);
|
||||
|
||||
view.render(model, this.request, this.response);
|
||||
|
||||
assertEquals(overiddenCharacterEncoding, this.response.getCharacterEncoding());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subReportWithUnspecifiedParentDataSource() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.put("SubReportData", getProductData());
|
||||
|
||||
Properties subReports = new Properties();
|
||||
subReports.put("ProductsSubReport", "org/springframework/ui/jasperreports/subReportChildFalse.jrxml");
|
||||
|
||||
AbstractJasperReportsView view = getView(SUB_REPORT_PARENT);
|
||||
view.setSubReportUrls(subReports);
|
||||
view.setSubReportDataKeys(new String[]{"SubReportData"});
|
||||
|
||||
// Unspecified reportDataKey should throw exception when subReportDataSources is specified
|
||||
exception.expect(ApplicationContextException.class);
|
||||
view.initApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentDisposition() throws Exception {
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.render(getModel(), request, response);
|
||||
assertEquals("Invalid content type", "inline", response.getHeader("Content-Disposition"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overrideContentDisposition() throws Exception {
|
||||
Properties headers = new Properties();
|
||||
String cd = "attachment";
|
||||
headers.setProperty("Content-Disposition", cd);
|
||||
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.setHeaders(headers);
|
||||
view.render(getModel(), request, response);
|
||||
assertEquals("Invalid content type", cd, response.getHeader("Content-Disposition"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCustomHeaders() throws Exception {
|
||||
Properties headers = new Properties();
|
||||
|
||||
String key = "foo";
|
||||
String value = "bar";
|
||||
|
||||
headers.setProperty(key, value);
|
||||
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
view.setHeaders(headers);
|
||||
view.render(getModel(), request, response);
|
||||
|
||||
assertNotNull("Header not present", response.getHeader(key));
|
||||
assertEquals("Invalid header value", value, response.getHeader(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withJdbcDataSource() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
view.setJdbcDataSource(getMockJdbcDataSource());
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
|
||||
// DataSource was not used as report DataSource
|
||||
exception.expect(SQLException.class);
|
||||
view.render(model, request, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withJdbcDataSourceInModel() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
|
||||
Map<String, Object> model = getModel();
|
||||
model.remove("dataSource");
|
||||
model.put("someKey", getMockJdbcDataSource());
|
||||
|
||||
// DataSource was not used as report DataSource
|
||||
exception.expect(SQLException.class);
|
||||
view.render(model, request, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jrDataSourceOverridesJdbcDataSource() throws Exception {
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
view.setJdbcDataSource(getMockJdbcDataSource());
|
||||
|
||||
view.render(getModel(), request, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withCharacterEncoding() throws Exception {
|
||||
AbstractJasperReportsView view = getView(COMPILED_REPORT);
|
||||
|
||||
assumeTrue(view instanceof AbstractJasperReportsSingleFormatView
|
||||
&& ((AbstractJasperReportsSingleFormatView) view).useWriter());
|
||||
|
||||
String characterEncoding = "UTF-8";
|
||||
|
||||
Map<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put(net.sf.jasperreports.engine.JRExporterParameter.CHARACTER_ENCODING, characterEncoding);
|
||||
|
||||
view.setExporterParameters(parameters);
|
||||
view.convertExporterParameters();
|
||||
|
||||
view.render(getModel(), this.request, this.response);
|
||||
assertEquals(characterEncoding, this.response.getCharacterEncoding());
|
||||
}
|
||||
|
||||
protected AbstractJasperReportsView getView(String url) throws Exception {
|
||||
AbstractJasperReportsView view = getViewImplementation();
|
||||
view.setUrl(url);
|
||||
StaticWebApplicationContext ac = new StaticWebApplicationContext();
|
||||
ac.setServletContext(new MockServletContext());
|
||||
ac.addMessage("page", Locale.GERMAN, "MeineSeite");
|
||||
ac.refresh();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, ac);
|
||||
view.setApplicationContext(ac);
|
||||
return view;
|
||||
}
|
||||
|
||||
protected abstract AbstractJasperReportsView getViewImplementation();
|
||||
|
||||
protected abstract String getDesiredContentType();
|
||||
|
||||
private DataSource getMockJdbcDataSource() throws SQLException {
|
||||
DataSource ds = mock(DataSource.class);
|
||||
given(ds.getConnection()).willThrow(new SQLException());
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
private class MockDataSourceProvider extends JRAbstractBeanDataSourceProvider {
|
||||
|
||||
public MockDataSourceProvider(Class<?> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JRDataSource create(JasperReport jasperReport) throws JRException {
|
||||
return new JRBeanCollectionDataSource(getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(JRDataSource jrDataSource) throws JRException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ConfigurableJasperReportsViewWithStreamTests extends AbstractConfigurableJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
ConfigurableJasperReportsView view = new ConfigurableJasperReportsView();
|
||||
view.setExporterClass(net.sf.jasperreports.engine.export.JRHtmlExporter.class);
|
||||
view.setUseWriter(true);
|
||||
view.setContentType("application/pdf");
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "application/pdf";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import net.sf.jasperreports.engine.export.JRPdfExporter;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ConfigurableJasperReportsViewWithWriterTests extends AbstractConfigurableJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
ConfigurableJasperReportsView view = new ConfigurableJasperReportsView();
|
||||
view.setExporterClass(JRPdfExporter.class);
|
||||
view.setUseWriter(false);
|
||||
view.setContentType("text/html");
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "text/html";
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ExporterParameterTests extends AbstractJasperReportsTests {
|
||||
|
||||
@Test
|
||||
public void parameterParsing() throws Exception {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI", "/foo/bar");
|
||||
|
||||
AbstractJasperReportsView view = new AbstractJasperReportsView() {
|
||||
|
||||
@Override
|
||||
protected void renderReport(JasperPrint filledReport, Map<String, Object> model, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
assertEquals("Invalid number of exporter parameters", 1, getConvertedExporterParameters().size());
|
||||
|
||||
net.sf.jasperreports.engine.JRExporterParameter key = net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI;
|
||||
Object value = getConvertedExporterParameters().get(key);
|
||||
|
||||
assertNotNull("Value not mapped to correct key", value);
|
||||
assertEquals("Incorrect value for parameter", "/foo/bar", value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
view.setExporterParameters(params);
|
||||
setViewProperties(view);
|
||||
view.render(getModel(), request, response);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invalidClass() throws Exception {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("foo.net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI", "/foo");
|
||||
|
||||
AbstractJasperReportsView view = new JasperReportsHtmlView();
|
||||
setViewProperties(view);
|
||||
|
||||
view.setExporterParameters(params);
|
||||
view.convertExporterParameters();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invalidField() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI_FOO", "/foo");
|
||||
|
||||
AbstractJasperReportsView view = new JasperReportsHtmlView();
|
||||
setViewProperties(view);
|
||||
|
||||
view.setExporterParameters(params);
|
||||
view.convertExporterParameters();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void invalidType() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("java.lang.Boolean.TRUE", "/foo");
|
||||
|
||||
AbstractJasperReportsView view = new JasperReportsHtmlView();
|
||||
setViewProperties(view);
|
||||
|
||||
view.setExporterParameters(params);
|
||||
view.convertExporterParameters();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeConversion() {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN", "true");
|
||||
|
||||
AbstractJasperReportsView view = new JasperReportsHtmlView();
|
||||
setViewProperties(view);
|
||||
|
||||
view.setExporterParameters(params);
|
||||
view.convertExporterParameters();
|
||||
Object value = view.getConvertedExporterParameters().get(
|
||||
net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN);
|
||||
assertEquals(Boolean.TRUE, value);
|
||||
}
|
||||
|
||||
private void setViewProperties(AbstractJasperReportsView view) {
|
||||
view.setUrl("/org/springframework/ui/jasperreports/DataSourceReport.jasper");
|
||||
StaticWebApplicationContext ac = new StaticWebApplicationContext();
|
||||
ac.setServletContext(new MockServletContext());
|
||||
ac.addMessage("page", Locale.GERMAN, "MeineSeite");
|
||||
ac.refresh();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, ac);
|
||||
view.setApplicationContext(ac);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class JasperReportViewResolverTests {
|
||||
|
||||
@Test
|
||||
public void resolveView() throws Exception {
|
||||
StaticApplicationContext ctx = new StaticApplicationContext();
|
||||
|
||||
String prefix = "org/springframework/ui/jasperreports/";
|
||||
String suffix = ".jasper";
|
||||
String viewName = "DataSourceReport";
|
||||
|
||||
JasperReportsViewResolver viewResolver = new JasperReportsViewResolver();
|
||||
viewResolver.setViewClass(JasperReportsHtmlView.class);
|
||||
viewResolver.setPrefix(prefix);
|
||||
viewResolver.setSuffix(suffix);
|
||||
viewResolver.setApplicationContext(ctx);
|
||||
|
||||
AbstractJasperReportsView view = (AbstractJasperReportsView) viewResolver.resolveViewName(viewName,
|
||||
Locale.ENGLISH);
|
||||
assertNotNull("View should not be null", view);
|
||||
assertEquals("Incorrect URL", prefix + viewName + suffix, view.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withViewNamesAndEndsWithPattern() throws Exception {
|
||||
doViewNamesTest("DataSource*");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withViewNamesAndStartsWithPattern() throws Exception {
|
||||
doViewNamesTest("*Report");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withViewNamesAndStatic() throws Exception {
|
||||
doViewNamesTest("DataSourceReport");
|
||||
}
|
||||
|
||||
private void doViewNamesTest(String... viewNames) throws Exception {
|
||||
StaticApplicationContext ctx = new StaticApplicationContext();
|
||||
|
||||
String prefix = "org/springframework/ui/jasperreports/";
|
||||
String suffix = ".jasper";
|
||||
String viewName = "DataSourceReport";
|
||||
|
||||
JasperReportsViewResolver viewResolver = new JasperReportsViewResolver();
|
||||
viewResolver.setViewClass(JasperReportsHtmlView.class);
|
||||
viewResolver.setPrefix(prefix);
|
||||
viewResolver.setSuffix(suffix);
|
||||
viewResolver.setViewNames(viewNames);
|
||||
viewResolver.setApplicationContext(ctx);
|
||||
|
||||
AbstractJasperReportsView view = (AbstractJasperReportsView) viewResolver.resolveViewName(viewName,
|
||||
Locale.ENGLISH);
|
||||
assertNotNull("View should not be null", view);
|
||||
assertEquals("Incorrect URL", prefix + viewName + suffix, view.getUrl());
|
||||
assertNull(viewResolver.resolveViewName("foo", Locale.ENGLISH));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class JasperReportsCsvViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsCsvView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "text/csv";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class JasperReportsHtmlViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsHtmlView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void configureExporterParametersWithEncodingFromPropertiesFile() throws Exception {
|
||||
GenericWebApplicationContext ac = new GenericWebApplicationContext();
|
||||
ac.setServletContext(new MockServletContext());
|
||||
BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(ac);
|
||||
reader.loadBeanDefinitions(new ClassPathResource("view.properties", getClass()));
|
||||
ac.refresh();
|
||||
|
||||
AbstractJasperReportsView view = (AbstractJasperReportsView) ac.getBean("report");
|
||||
String encoding = (String) view.getConvertedExporterParameters().get(
|
||||
net.sf.jasperreports.engine.export.JRHtmlExporterParameter.CHARACTER_ENCODING);
|
||||
assertEquals("UTF-8", encoding);
|
||||
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, ac);
|
||||
view.render(getModel(), request, response);
|
||||
assertEquals("Response content type is incorrect", "text/html;charset=UTF-8", response.getContentType());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.sf.jasperreports.engine.JasperPrint;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.tests.Assume;
|
||||
import org.springframework.tests.TestGroup;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
public class JasperReportsMultiFormatViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected void extendModel(Map<String, Object> model) {
|
||||
model.put(getDiscriminatorKey(), "csv");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleHtmlRender() throws Exception {
|
||||
Assume.group(TestGroup.CUSTOM_COMPILATION);
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
|
||||
Map<String, Object> model = getBaseModel();
|
||||
model.put(getDiscriminatorKey(), "html");
|
||||
|
||||
view.render(model, request, response);
|
||||
|
||||
assertEquals("Invalid content type", "text/html", response.getContentType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void overrideContentDisposition() throws Exception {
|
||||
Assume.group(TestGroup.CUSTOM_COMPILATION);
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
AbstractJasperReportsView view = getView(UNCOMPILED_REPORT);
|
||||
|
||||
Map<String, Object> model = getBaseModel();
|
||||
model.put(getDiscriminatorKey(), "csv");
|
||||
|
||||
String headerValue = "inline; filename=foo.txt";
|
||||
|
||||
Properties mappings = new Properties();
|
||||
mappings.put("csv", headerValue);
|
||||
|
||||
((JasperReportsMultiFormatView) view).setContentDispositionMappings(mappings);
|
||||
|
||||
view.render(model, request, response);
|
||||
|
||||
assertEquals("Invalid Content-Disposition header value", headerValue,
|
||||
response.getHeader("Content-Disposition"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exporterParametersAreCarriedAcross() throws Exception {
|
||||
Assume.group(TestGroup.CUSTOM_COMPILATION);
|
||||
assumeTrue(canCompileReport);
|
||||
|
||||
JasperReportsMultiFormatView view = (JasperReportsMultiFormatView) getView(UNCOMPILED_REPORT);
|
||||
|
||||
Map<String, Class<? extends AbstractJasperReportsView>> mappings =
|
||||
new HashMap<>();
|
||||
mappings.put("test", ExporterParameterTestView.class);
|
||||
|
||||
Map<String, String> exporterParameters = new HashMap<>();
|
||||
|
||||
// test view class performs the assertions - robh
|
||||
exporterParameters.put(ExporterParameterTestView.TEST_PARAM, "foo");
|
||||
|
||||
view.setExporterParameters(exporterParameters);
|
||||
view.setFormatMappings(mappings);
|
||||
view.initApplicationContext();
|
||||
|
||||
Map<String, Object> model = getBaseModel();
|
||||
model.put(getDiscriminatorKey(), "test");
|
||||
|
||||
view.render(model, request, response);
|
||||
}
|
||||
|
||||
protected String getDiscriminatorKey() {
|
||||
return "format";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsMultiFormatView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "text/csv";
|
||||
}
|
||||
|
||||
private Map<String, Object> getBaseModel() {
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
model.put("ReportTitle", "Foo");
|
||||
model.put("dataSource", getData());
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
public static class ExporterParameterTestView extends AbstractJasperReportsView {
|
||||
|
||||
public static final String TEST_PARAM = "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI";
|
||||
|
||||
@Override
|
||||
protected void renderReport(JasperPrint filledReport, Map<String, Object> parameters, HttpServletResponse response) {
|
||||
assertNotNull("Exporter parameters are null", getExporterParameters());
|
||||
assertEquals("Incorrect number of exporter parameters", 1, getExporterParameters().size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class JasperReportsMultiFormatViewWithCustomMappingsTests extends JasperReportsMultiFormatViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
JasperReportsMultiFormatView view = new JasperReportsMultiFormatView();
|
||||
view.setFormatKey("fmt");
|
||||
Map<String, Class<? extends AbstractJasperReportsView>> mappings =
|
||||
new HashMap<>();
|
||||
mappings.put("csv", JasperReportsCsvView.class);
|
||||
mappings.put("comma-separated", JasperReportsCsvView.class);
|
||||
mappings.put("html", JasperReportsHtmlView.class);
|
||||
view.setFormatMappings(mappings);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDiscriminatorKey() {
|
||||
return "fmt";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendModel(Map<String, Object> model) {
|
||||
model.put(getDiscriminatorKey(), "comma-separated");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class JasperReportsPdfViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsPdfView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "application/pdf";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class JasperReportsXlsViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsXlsView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "application/vnd.ms-excel";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.view.jasperreports;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.2
|
||||
*/
|
||||
public class JasperReportsXlsxViewTests extends AbstractJasperReportsViewTests {
|
||||
|
||||
@Override
|
||||
protected AbstractJasperReportsView getViewImplementation() {
|
||||
return new JasperReportsXlsxView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDesiredContentType() {
|
||||
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
net.sf.jasperreports.awt.ignore.missing.font=true
|
Binary file not shown.
|
@ -1,185 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="DataSourceReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ReportTitle" class="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="DataFile" class="java.lang.String">
|
||||
</parameter>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="street" class="java.lang.String">
|
||||
</field>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<variable name="CityNumber" class="java.lang.Integer" resetType="Group" resetGroup="CityGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{CityNumber} != null)?(new Integer($V{CityNumber}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="CityGroup" minHeightToStartNewPage="60">
|
||||
<groupExpression><![CDATA[$F{city}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="4" width="515" height="15" forecolor="#c0c0c0" backcolor="#c0c0c0"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<textField>
|
||||
<reportElement mode="Opaque" x="0" y="4" width="515" height="15" backcolor="#c0c0c0"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{CityNumber}) + ". " + String.valueOf($F{city})]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="19" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band height="20">
|
||||
<line>
|
||||
<reportElement x="0" y="-1" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="400" y="1" width="60" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="460" y="1" width="30" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{CityGroup_COUNT}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="70">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportTitle}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="40" width="515" height="20"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="14"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{DataFile}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" forecolor="#333333" backcolor="#333333"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="55" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="55" y="5" width="205" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="260" y="5" width="255" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Street]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="20">
|
||||
<textField>
|
||||
<reportElement x="0" y="4" width="50" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="55" y="4" width="200" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="260" y="4" width="255" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{street}]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement positionType="Float" x="0" y="19" width="515" height="1" forecolor="#808080"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<lastPageFooter>
|
||||
<band height="60">
|
||||
<textField>
|
||||
<reportElement x="0" y="10" width="515" height="15"/>
|
||||
<textElement textAlignment="Center"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["There were " +
|
||||
String.valueOf($V{REPORT_COUNT}) +
|
||||
" address records on this report."]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="30" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="40" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="40" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</lastPageFooter>
|
||||
</jasperReport>
|
|
@ -1 +0,0 @@
|
|||
page=MeineSeite
|
Binary file not shown.
|
@ -1,227 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="ProductReport" columnCount="2" pageWidth="325" pageHeight="842" columnWidth="160" columnSpacing="5" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="8" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="8" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="8" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="City" class="java.lang.String"/>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="quantity" class="java.lang.Float">
|
||||
</field>
|
||||
<field name="price" class="java.lang.Float">
|
||||
</field>
|
||||
<variable name="QuantityProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="QuantitySum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceSum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="ProductCount" class="java.lang.Integer" resetType="Group" resetGroup="ProductGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{ProductCount} != null)?(new Integer($V{ProductCount}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="ProductGroup">
|
||||
<groupExpression><![CDATA[$F{id}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="14">
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="15" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="20" y="2" width="80" height="10"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0">
|
||||
<reportElement positionType="Float" x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantityProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0.00">
|
||||
<reportElement positionType="Float" x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="14">
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Title]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="325" height="10"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Products ordered by people in " + $P{City}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Header]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<columnHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="160" height="10" forecolor="#ffff99" backcolor="#ffff99"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="20" y="2" width="85" height="10" backcolor="#ffff99"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="105" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Qty]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="125" y="2" width="35" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Price]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</columnHeader>
|
||||
<columnFooter>
|
||||
<band height="14">
|
||||
<line>
|
||||
<reportElement x="0" y="1" width="160" height="1"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Column Footer]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement x="70" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Total :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantitySum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField pattern="#0.00">
|
||||
<reportElement x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</columnFooter>
|
||||
<pageFooter>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Footer]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="150" y="2" width="100" height="10" forecolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of "]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="250" y="2" width="50" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<summary>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="325" height="10" forecolor="#808000" backcolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="230" height="10" backcolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Summary]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="230" y="2" width="55" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement mode="Opaque" x="285" y="2" width="40" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{ProductCount}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</summary>
|
||||
</jasperReport>
|
Binary file not shown.
|
@ -1,103 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="MasterReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ProductsSubReport" class="net.sf.jasperreports.engine.JasperReport"/>
|
||||
<parameter name="SubReportData" class="net.sf.jasperreports.engine.JRDataSource"/>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<title>
|
||||
<band height="50">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Master Report]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="21">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" backcolor="#333333"/>
|
||||
<graphicElement pen="None"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="515" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[City List]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="50">
|
||||
<textField>
|
||||
<reportElement x="5" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{city}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement isPrintRepeatedValues="false" x="110" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[(continued)]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1" isPrintWhenDetailOverflows="true"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<subreport>
|
||||
<reportElement isPrintRepeatedValues="false" x="5" y="25" width="325" height="20" isRemoveLineWhenBlank="true" backcolor="#ffcc99"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{city}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<dataSourceExpression><![CDATA[$P{SubReportData}]]></dataSourceExpression>
|
||||
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{ProductsSubReport}]]></subreportExpression>
|
||||
</subreport>
|
||||
<!--<subreport>
|
||||
<reportElement positionType="Float" x="335" y="25" width="175" height="20" isRemoveLineWhenBlank="true" backcolor="#99ccff"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{City}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
|
||||
<subreportExpression class="java.lang.String"><![CDATA["AddressReport.jasper"]]></subreportExpression>
|
||||
</subreport> -->
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
</jasperReport>
|
|
@ -1,4 +0,0 @@
|
|||
report.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView
|
||||
report.url=/org/springframework/ui/jasperreports/DataSourceReport.jasper
|
||||
report.exporterParameters[net.sf.jasperreports.engine.export.JRHtmlExporterParameter.CHARACTER_ENCODING]=UTF-8
|
||||
report.exporterParameters[net.sf.jasperreports.engine.JRExporterParameter.PAGE_INDEX]=0
|
|
@ -144,9 +144,8 @@ loading, and the transparent creation of contexts by, for example, a Servlet con
|
|||
The Context module also supports Java EE features such as EJB, JMX, and basic remoting.
|
||||
The `ApplicationContext` interface is the focal point of the Context module.
|
||||
`spring-context-support` provides support for integrating common third-party libraries
|
||||
into a Spring application context for caching (EhCache, Guava, JCache), mailing
|
||||
(JavaMail), scheduling (CommonJ, Quartz) and template engines (FreeMarker, JasperReports).
|
||||
|
||||
into a Spring application context, in particular for caching (EhCache, JCache) and
|
||||
scheduling (CommonJ, Quartz).
|
||||
|
||||
The `spring-expression` module provides a powerful <<expressions,__Expression
|
||||
Language__>> for querying and manipulating an object graph at runtime. It is an extension
|
||||
|
|
|
@ -2037,358 +2037,6 @@ document should appear listing each of the words in the model map.
|
|||
|
||||
|
||||
|
||||
[[view-jasper-reports]]
|
||||
== JasperReports
|
||||
JasperReports ( http://jasperreports.sourceforge.net[]) is a powerful open-source
|
||||
reporting engine that supports the creation of report designs using an easily understood
|
||||
XML file format. JasperReports is capable of rendering reports in four different
|
||||
formats: CSV, Excel, HTML and PDF.
|
||||
|
||||
|
||||
|
||||
[[view-jasper-reports-dependencies]]
|
||||
=== Dependencies
|
||||
Your application will need to include the latest release of JasperReports, which at the
|
||||
time of writing was 0.6.1. JasperReports itself depends on the following projects:
|
||||
|
||||
* BeanShell
|
||||
* Commons BeanUtils
|
||||
* Commons Collections
|
||||
* Commons Digester
|
||||
* Commons Logging
|
||||
* iText
|
||||
* POI
|
||||
|
||||
JasperReports also requires a JAXP compliant XML parser.
|
||||
|
||||
|
||||
|
||||
[[view-jasper-reports-configuration]]
|
||||
=== Configuration
|
||||
To configure JasperReports views in your Spring container configuration you need to
|
||||
define a `ViewResolver` to map view names to the appropriate view class depending on
|
||||
which format you want your report rendered in.
|
||||
|
||||
|
||||
[[view-jasper-reports-configuration-resolver]]
|
||||
==== Configuring the ViewResolver
|
||||
|
||||
Typically, you will use the `ResourceBundleViewResolver` to map view names to view
|
||||
classes and files in a properties file.
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
|
||||
<property name="basename" value="views"/>
|
||||
</bean>
|
||||
----
|
||||
|
||||
Here we've configured an instance of the `ResourceBundleViewResolver` class that will
|
||||
look for view mappings in the resource bundle with base name `views`. (The content of
|
||||
this file is described in the next section.)
|
||||
|
||||
|
||||
[[view-jasper-reports-configuration-views]]
|
||||
==== Configuring the Views
|
||||
|
||||
The Spring Framework contains five different `View` implementations for JasperReports,
|
||||
four of which correspond to one of the four output formats supported by JasperReports,
|
||||
and one that allows for the format to be determined at runtime:
|
||||
|
||||
[[view-jasper-reports-configuration-views-classes]]
|
||||
.JasperReports View classes
|
||||
|===
|
||||
| Class Name| Render Format
|
||||
|
||||
| `JasperReportsCsvView`
|
||||
| CSV
|
||||
|
||||
| `JasperReportsHtmlView`
|
||||
| HTML
|
||||
|
||||
| `JasperReportsPdfView`
|
||||
| PDF
|
||||
|
||||
| `JasperReportsXlsView`
|
||||
| Microsoft Excel
|
||||
|
||||
| `JasperReportsMultiFormatView`
|
||||
| The view is <<view-jasper-reports-configuration-multiformat-view,decided upon at
|
||||
runtime>>
|
||||
|===
|
||||
|
||||
Mapping one of these classes to a view name and a report file is a matter of adding the
|
||||
appropriate entries in the resource bundle configured in the previous section as shown
|
||||
here:
|
||||
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
simpleReport.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
|
||||
simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper
|
||||
----
|
||||
|
||||
Here you can see that the view with name `simpleReport` is mapped to the
|
||||
`JasperReportsPdfView` class, causing the output of this report to be rendered in PDF
|
||||
format. The `url` property of the view is set to the location of the underlying report
|
||||
file.
|
||||
|
||||
|
||||
[[view-jasper-reports-configuration-report-files]]
|
||||
==== About Report Files
|
||||
JasperReports has two distinct types of report file: the design file, which has a
|
||||
`.jrxml` extension, and the compiled report file, which has a `.jasper` extension.
|
||||
Typically, you use the JasperReports Ant task to compile your `.jrxml` design file into
|
||||
a `.jasper` file before deploying it into your application. With the Spring Framework
|
||||
you can map either of these files to your report file and the framework will take care
|
||||
of compiling the `.jrxml` file on the fly for you. You should note that after a `.jrxml`
|
||||
file is compiled by the Spring Framework, the compiled report is cached for the lifetime
|
||||
of the application. Thus, to make changes to the file you will need to restart your
|
||||
application.
|
||||
|
||||
|
||||
[[view-jasper-reports-configuration-multiformat-view]]
|
||||
==== Using JasperReportsMultiFormatView
|
||||
|
||||
The `JasperReportsMultiFormatView` allows for the report format to be specified at
|
||||
runtime. The actual rendering of the report is delegated to one of the other
|
||||
JasperReports view classes - the `JasperReportsMultiFormatView` class simply adds a
|
||||
wrapper layer that allows for the exact implementation to be specified at runtime.
|
||||
|
||||
The `JasperReportsMultiFormatView` class introduces two concepts: the format key and the
|
||||
discriminator key. The `JasperReportsMultiFormatView` class uses the mapping key to look
|
||||
up the actual view implementation class, and it uses the format key to lookup up the
|
||||
mapping key. From a coding perspective you add an entry to your model with the format
|
||||
key as the key and the mapping key as the value, for example:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
public ModelAndView handleSimpleReportMulti(HttpServletRequest request,
|
||||
HttpServletResponse response) throws Exception {
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
String format = uri.substring(uri.lastIndexOf(".") + 1);
|
||||
|
||||
Map model = getModel();
|
||||
model.put("format", format);
|
||||
|
||||
return new ModelAndView("simpleReportMulti", model);
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
In this example, the mapping key is determined from the extension of the request URI and
|
||||
is added to the model under the default format key: `format`. If you wish to use a
|
||||
different format key then you can configure this using the `formatKey` property of the
|
||||
`JasperReportsMultiFormatView` class.
|
||||
|
||||
By default the following mapping key mappings are configured in
|
||||
`JasperReportsMultiFormatView`:
|
||||
|
||||
[[view-jasper-reports-configuration-multiformat-view-mappings]]
|
||||
.JasperReportsMultiFormatView Default Mapping Key Mappings
|
||||
|===
|
||||
| Mapping Key| View Class
|
||||
|
||||
| csv
|
||||
| `JasperReportsCsvView`
|
||||
|
||||
| html
|
||||
| `JasperReportsHtmlView`
|
||||
|
||||
| pdf
|
||||
| `JasperReportsPdfView`
|
||||
|
||||
| xls
|
||||
| `JasperReportsXlsView`
|
||||
|===
|
||||
|
||||
So in the example above a request to URI /foo/myReport.pdf would be mapped to the
|
||||
`JasperReportsPdfView` class. You can override the mapping key to view class mappings
|
||||
using the `formatMappings` property of `JasperReportsMultiFormatView`.
|
||||
|
||||
|
||||
|
||||
[[view-jasper-reports-model]]
|
||||
=== Populating the ModelAndView
|
||||
|
||||
In order to render your report correctly in the format you have chosen, you must supply
|
||||
Spring with all of the data needed to populate your report. For JasperReports this means
|
||||
you must pass in all report parameters along with the report datasource. Report
|
||||
parameters are simple name/value pairs and can be added to the `Map` for your model as
|
||||
you would add any name/value pair.
|
||||
|
||||
When adding the datasource to the model you have two approaches to choose from. The
|
||||
first approach is to add an instance of `JRDataSource` or a `Collection` type to the
|
||||
model `Map` under any arbitrary key. Spring will then locate this object in the model
|
||||
and treat it as the report datasource. For example, you may populate your model like so:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
private Map getModel() {
|
||||
Map model = new HashMap();
|
||||
Collection beanData = getBeanData();
|
||||
model.put("myBeanData", beanData);
|
||||
return model;
|
||||
}
|
||||
----
|
||||
|
||||
The second approach is to add the instance of `JRDataSource` or `Collection` under a
|
||||
specific key and then configure this key using the `reportDataKey` property of the view
|
||||
class. In both cases Spring will wrap instances of `Collection` in a
|
||||
`JRBeanCollectionDataSource` instance. For example:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
private Map getModel() {
|
||||
Map model = new HashMap();
|
||||
Collection beanData = getBeanData();
|
||||
Collection someData = getSomeData();
|
||||
model.put("myBeanData", beanData);
|
||||
model.put("someData", someData);
|
||||
return model;
|
||||
}
|
||||
----
|
||||
|
||||
Here you can see that two `Collection` instances are being added to the model. To ensure
|
||||
that the correct one is used, we simply modify our view configuration as appropriate:
|
||||
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
simpleReport.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
|
||||
simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper
|
||||
simpleReport.reportDataKey=myBeanData
|
||||
----
|
||||
|
||||
Be aware that when using the first approach, Spring will use the first instance of
|
||||
`JRDataSource` or `Collection` that it encounters. If you need to place multiple
|
||||
instances of `JRDataSource` or `Collection` into the model you need to use the second
|
||||
approach.
|
||||
|
||||
|
||||
|
||||
[[view-jasper-reports-subreports]]
|
||||
=== Working with Sub-Reports
|
||||
JasperReports provides support for embedded sub-reports within your master report files.
|
||||
There are a wide variety of mechanisms for including sub-reports in your report files.
|
||||
The easiest way is to hard code the report path and the SQL query for the sub report
|
||||
into your design files. The drawback of this approach is obvious: the values are
|
||||
hard-coded into your report files reducing reusability and making it harder to modify
|
||||
and update report designs. To overcome this you can configure sub-reports declaratively,
|
||||
and you can include additional data for these sub-reports directly from your controllers.
|
||||
|
||||
|
||||
[[view-jasper-reports-subreports-config-reports]]
|
||||
==== Configuring Sub-Report Files
|
||||
To control which sub-report files are included in a master report using Spring, your
|
||||
report file must be configured to accept sub-reports from an external source. To do this
|
||||
you declare a parameter in your report file like so:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<parameter name="ProductsSubReport" class="net.sf.jasperreports.engine.JasperReport"/>
|
||||
----
|
||||
|
||||
Then, you define your sub-report to use this sub-report parameter:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<subreport>
|
||||
<reportElement isPrintRepeatedValues="false" x="5" y="25" width="325"
|
||||
height="20" isRemoveLineWhenBlank="true" backcolor="#ffcc99"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{city}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<dataSourceExpression><![CDATA[$P{SubReportData}]]></dataSourceExpression>
|
||||
<subreportExpression class="net.sf.jasperreports.engine.JasperReport">
|
||||
<![CDATA[$P{ProductsSubReport}]]></subreportExpression>
|
||||
</subreport>
|
||||
----
|
||||
|
||||
This defines a master report file that expects the sub-report to be passed in as an
|
||||
instance of `net.sf.jasperreports.engine.JasperReports` under the parameter
|
||||
`ProductsSubReport`. When configuring your Jasper view class, you can instruct Spring to
|
||||
load a report file and pass it into the JasperReports engine as a sub-report using the
|
||||
`subReportUrls` property:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<property name="subReportUrls">
|
||||
<map>
|
||||
<entry key="ProductsSubReport" value="/WEB-INF/reports/subReportChild.jrxml"/>
|
||||
</map>
|
||||
</property>
|
||||
----
|
||||
|
||||
Here, the key of the `Map` corresponds to the name of the sub-report parameter in the
|
||||
report design file, and the entry is the URL of the report file. Spring will load this
|
||||
report file, compiling it if necessary, and pass it into the JasperReports engine under
|
||||
the given key.
|
||||
|
||||
|
||||
[[view-jasper-reports-subreports-config-datasources]]
|
||||
==== Configuring Sub-Report Data Sources
|
||||
This step is entirely optional when using Spring to configure your sub-reports. If you
|
||||
wish, you can still configure the data source for your sub-reports using static queries.
|
||||
However, if you want Spring to convert data returned in your `ModelAndView` into
|
||||
instances of `JRDataSource` then you need to specify which of the parameters in your
|
||||
`ModelAndView` Spring should convert. To do this, configure the list of parameter names
|
||||
using the `subReportDataKeys` property of your chosen view class:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<property name="subReportDataKeys" value="SubReportData"/>
|
||||
----
|
||||
|
||||
Here, the key you supply __must__ correspond to both the key used in your `ModelAndView`
|
||||
and the key used in your report design file.
|
||||
|
||||
|
||||
|
||||
[[view-jasper-reports-exporter-parameters]]
|
||||
=== Configuring Exporter Parameters
|
||||
If you have special requirements for exporter configuration -- perhaps you want a
|
||||
specific page size for your PDF report -- you can configure these exporter parameters
|
||||
declaratively in your Spring configuration file using the `exporterParameters` property
|
||||
of the view class. The `exporterParameters` property is typed as a `Map`. In your
|
||||
configuration the key of an entry should be the fully-qualified name of a static field
|
||||
that contains the exporter parameter definition, and the value of an entry should be the
|
||||
value you want to assign to the parameter. An example of this is shown below:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<bean id="htmlReport" class="org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView">
|
||||
<property name="url" value="/WEB-INF/reports/simpleReport.jrxml"/>
|
||||
<property name="exporterParameters">
|
||||
<map>
|
||||
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.HTML_FOOTER">
|
||||
<value>Footer by Spring!
|
||||
</td><td width="50%">&nbsp; </td></tr>
|
||||
</table></body></html>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
----
|
||||
|
||||
Here you can see that the `JasperReportsHtmlView` is configured with an exporter
|
||||
parameter for `net.sf.jasperreports.engine.export.JRHtmlExporterParameter.HTML_FOOTER`
|
||||
which will output a footer in the resulting HTML.
|
||||
|
||||
|
||||
|
||||
|
||||
[[view-feeds]]
|
||||
== Feed Views
|
||||
Both `AbstractAtomFeedView` and `AbstractRssFeedView` inherit from the base class
|
||||
|
|
Loading…
Reference in New Issue