这里我们就不介绍JasperReport怎么使用了,大家可以自己去查。当我们需要一次打印多张的时候我们该怎么处理,这里的解决方法主要是代码。报表我们就画一个,和普通的打印一张的是一样的。
用户随意选择打印报表:
ApplicationContext ctx = SpringContextUtils.getApplicationContext();
Resource resource = ctx.getResource("classpath:/reports/rptIncumbency.jrxml");
InputStream inputStream = resource.getInputStream();
上面所有的操作都是为了获取JasperReport对象,我们是通过ApplicationContext获取的。大家根据自己的需要去解决。
JasperReport jasperReport = JasperCompileManager.compileReport(inputStream);
打印PDF
JRAbstractExporter exporter = new JRPdfExporter();
实例需要打印多张的对象,我们需要一张就add一个。大家处理的时候可以对数据进行循环处理,每条数据我就add一次。
List<JasperPrint> list = new ArrayList<>();
fillReport操作大家根据自己的需要,主要放置数据源和对应的报表。
JasperPrint jasperprint = JasperFillManager.fillReport(jasperReport, null,ReportPrintFactory.setIncumbency(reportPrintService.getIncumbency(companyId)));
将jasperprint对象放入list中,每一个就是一张。
list.add(jasperprint);
list.add(jasperprint);
下面就是固定的输出数据源
ServletOutputStream output = response.getOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, list);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, output);
exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
exporter.exportReport();
上面所述的是一次批量打印多张,下面我们说下怎么自动赋值。如果对报表不是很熟悉就用Map一个一个的放置吧。不需要看下么的内容,主要是给大家提供一个思路。
在做报表操作的时候,我们需要一个一个的put值然后返回一个Map对象。
解决思路:
1.拿到报表JasperReport对象,获取JRField和JRParameter。第一个就是我们常说的循环的那种操作(一行记录),第二个就是普通的参数。
2.通过反射获取dto的所有属性和报表去比对(我们使用Set集合唯一性),如果存在就把值放入。
要求:dto所有属性名称必须和报表一致。以报表为准。否则值不能放入。
使用:可以直接注入,也可以根据自己的需求扩展。
/**
* <pre>
* 报表打印帮助接口
* <T, V>
* 其中T 对应的是parameter
* V 对应的是field
* </pre>
*
*
* @author gao.mq
*
*/
public interface ReportHelper {
/**
* @param reportName
* @param requestFullUri
* @param t
* @param value
* @return
* @throws Exception
*/
public <T, V> Map<String, Object> fillDataSource(String reportName, String requestFullUri, T t, List<V> value)
throws Exception;
}
/**
* <pre>
* 报表打印默认实现
* </pre>
*
* @author gao.mq
*
*/
public abstract class AbstractReportHelper implements ReportHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractReportHelper.class);
// parameter
private static HashSet<String> jrRarameterHashSet = new HashSet<>();
// field
private static HashSet<String> jrFieldHashSet = new HashSet<>();
// return map
private static Map<String, Object> map = new HashMap<String, Object>();
// basic data type
private static final HashSet<String> typesSet = new HashSet<>();
// jasperReport
private JasperReport jasperReport;
// default parameter or field type
static {
typesSet.add("class java.lang.Integer");
typesSet.add("class java.lang.Double");
typesSet.add("class java.lang.Long");
typesSet.add("class java.lang.String");
typesSet.add("class int");
typesSet.add("class java.math.BigDecimal");
}
@Override
public <T, V> Map<String, Object> fillDataSource(String reportName, String requestFullUri, T t, List<V> value)
throws Exception {
jasperReport = getJasperReport(reportName);
// get all field from jasperReport
JRField[] jrFields = jasperReport.getFields();
// get all parameter from jasperReport
JRParameter[] jRParameters = jasperReport.getParameters();
if (jRParameters != null) {
for (JRParameter jRParameter : jRParameters) {
String jRParameterName = jRParameter.getName();
LOGGER.info("parametersName=" + jRParameter.getName());
jrRarameterHashSet.add(jRParameterName);
}
}
if (jrFields != null) {
for (JRField field : jrFields) {
LOGGER.info("fieldName=" + field.getName());
String fieldName = field.getName();
jrFieldHashSet.add(fieldName);
}
}
map.put(JasperReportsMultiFormatView.DEFAULT_FORMAT_KEY, "pdf");
map.put("request_full_uri", requestFullUri);
if (null == t) {
LOGGER.info("dto不可用,为null");
throw new ResourceNotFoundException("dto不可用,为null");
}
Class classType = t.getClass();
Field[] fields = classType.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String parameterName = field.getName();
if (judgeType(field)) {
if (!jrRarameterHashSet.add(parameterName))
map.put(parameterName, field.get(t).toString());
}
}
if (value != null) {
map.put("dataSource", fillCollectionDataSource(value));
}
return map;
}
private static <T> JRMapCollectionDataSource fillCollectionDataSource(List<T> dtoList) throws Exception {
Collection<Map<String, ?>> list = new ArrayList<Map<String, ?>>();
for (T t : dtoList) {
Map<String, Object> datamap = new HashMap<String, Object>();
Class classType = t.getClass();
Field[] fields = classType.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String parameterName = field.getName();
if (!jrFieldHashSet.add(parameterName))
datamap.put(parameterName, field.get(t).toString());
}
list.add(datamap);
}
return new JRMapCollectionDataSource(list);
}
// judge for type
private static boolean judgeType(Field field) {
String fieldType = field.getType().toString();
if (typesSet.contains(fieldType))
return true;
return false;
}
// get JasperReport
private JasperReport getJasperReport(String reportName) throws Exception {
StringBuffer sb = new StringBuffer("classpath:/reports/");
sb.append(reportName);
sb.append(".jrxml");
ApplicationContext ctx = SpringContextUtils.getApplicationContext();
org.springframework.core.io.Resource resource = ctx.getResource(sb.toString());
InputStream inputStream = resource.getInputStream();
jasperReport = JasperCompileManager.compileReport(inputStream);
return jasperReport;
}
}
/**
* 默认实现
* @author gao.mq
*
*/
@Service
public class DefaultReportHelperImpl extends AbstractReportHelper {
@Override
public <T, V> Map<String, Object> fillDataSource(String reportName, String requestFullUri, T t, List<V> value)
throws Exception {
Map<String, Object> map = super.fillDataSource(reportName, requestFullUri, t, value);
return map;
}
}
大家在使用的时候直接注入ReportHelper即可,我们把默认的实现注入为Service了。
例如:
@Autowired
private ReportHelper reportHelper;
Map<String, Object> map = reportHelper.fillDataSource(报表名称, requestFullUri,dataSource);
这里提供了一种思路,欢迎和大家探讨能不能有更好的解决方法。