comparison artifacts/src/main/java/org/dive4elements/river/exports/sq/SQRelationExporter.java @ 8578:4eb1a3c71579

(issue1753) Implement PDF export of SQ Measurement data. The SQRelationExporter now consists of two reports (to avoid subreport woes). The old SQReleation PDF only takes the Page count of the Measurement attachment as argument to correctly print the page numbers. Otherwise it is unchanged. The new SQMeasurements report lists the measured data points on which the calculation was based.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 16 Mar 2015 11:35:19 +0100
parents c0334399625b
children d9f038b8e2ce
comparison
equal deleted inserted replaced
8577:3fae08a8cb90 8578:4eb1a3c71579
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde 1 /* Copyright (C) 2011, 2012, 2013, 2015 by Bundesanstalt für Gewässerkunde
2 * Software engineering by Intevation GmbH 2 * Software engineering by Intevation GmbH
3 * 3 *
4 * This file is Free Software under the GNU AGPL (>=v3) 4 * This file is Free Software under the GNU AGPL (>=v3)
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the 5 * and comes with ABSOLUTELY NO WARRANTY! Check out the
6 * documentation coming with Dive4Elements River for details. 6 * documentation coming with Dive4Elements River for details.
19 import java.text.NumberFormat; 19 import java.text.NumberFormat;
20 20
21 import net.sf.jasperreports.engine.JasperExportManager; 21 import net.sf.jasperreports.engine.JasperExportManager;
22 import net.sf.jasperreports.engine.JasperFillManager; 22 import net.sf.jasperreports.engine.JasperFillManager;
23 import net.sf.jasperreports.engine.JasperPrint; 23 import net.sf.jasperreports.engine.JasperPrint;
24 import net.sf.jasperreports.engine.JRPrintPage;
24 import net.sf.jasperreports.engine.JRException; 25 import net.sf.jasperreports.engine.JRException;
25 26
26 import au.com.bytecode.opencsv.CSVWriter; 27 import au.com.bytecode.opencsv.CSVWriter;
27 28
28 import org.dive4elements.artifacts.CallMeta; 29 import org.dive4elements.artifacts.CallMeta;
30 import org.dive4elements.river.artifacts.model.CalculationResult; 31 import org.dive4elements.river.artifacts.model.CalculationResult;
31 import org.dive4elements.river.artifacts.model.sq.SQFractionResult; 32 import org.dive4elements.river.artifacts.model.sq.SQFractionResult;
32 import org.dive4elements.river.artifacts.model.sq.SQResult; 33 import org.dive4elements.river.artifacts.model.sq.SQResult;
33 import org.dive4elements.river.artifacts.model.sq.SQ; 34 import org.dive4elements.river.artifacts.model.sq.SQ;
34 import org.dive4elements.river.artifacts.model.sq.SQRelationJRDataSource; 35 import org.dive4elements.river.artifacts.model.sq.SQRelationJRDataSource;
36 import org.dive4elements.river.artifacts.model.sq.SQMeasurementsJRDataSource;
35 import org.dive4elements.river.artifacts.model.Parameters; 37 import org.dive4elements.river.artifacts.model.Parameters;
36 import org.dive4elements.river.artifacts.model.DateRange; 38 import org.dive4elements.river.artifacts.model.DateRange;
37 import org.dive4elements.river.artifacts.access.SQRelationAccess; 39 import org.dive4elements.river.artifacts.access.SQRelationAccess;
38 40
39 import org.dive4elements.river.artifacts.resources.Resources; 41 import org.dive4elements.river.artifacts.resources.Resources;
172 public static final String PDF_HEADER_MODE = 174 public static final String PDF_HEADER_MODE =
173 "export.sqrelation.pdf.mode"; 175 "export.sqrelation.pdf.mode";
174 176
175 public static final String JASPER_FILE = 177 public static final String JASPER_FILE =
176 "export.sqrelation.pdf.file"; 178 "export.sqrelation.pdf.file";
179
180 public static final String JASPER_MEASUREMENTS_FILE =
181 "export.sqrelation.measurements.pdf.file";
177 182
178 protected List<SQResult []> data; 183 protected List<SQResult []> data;
179 184
180 public SQRelationExporter() { 185 public SQRelationExporter() {
181 data = new ArrayList<SQResult []>(); 186 data = new ArrayList<SQResult []>();
237 242
238 writeCSVHeader(writer); 243 writeCSVHeader(writer);
239 244
240 for (SQResult [] results: data) { 245 for (SQResult [] results: data) {
241 for (SQResult result: results) { 246 for (SQResult result: results) {
242 writer.writeAll(data2StringArrays(result)); 247 writer.writeAll(data2StringArrays(result, true));
243 } 248 }
244 } 249 }
245 } 250 }
246 251
247 protected List<String[]> data2StringArrays(SQResult result) { 252 protected List<String[]> data2StringArrays(SQResult result, boolean includeMeasurements) {
248 String km = Formatter.getSQRelationKM(context 253 String km = Formatter.getSQRelationKM(context
249 ).format(result.getKm()); 254 ).format(result.getKm());
250 List<String[]> retval = new ArrayList<String[]>(); 255 List<String[]> retval = new ArrayList<String[]>();
251 256
252 NumberFormat sqAFormatter = Formatter.getSQRelationA(context); 257 NumberFormat sqAFormatter = Formatter.getSQRelationA(context);
281 286
282 287
283 o = String.valueOf(fraction.totalNumOutliers()); 288 o = String.valueOf(fraction.totalNumOutliers());
284 t = String.valueOf(fraction.numMeasurements()); 289 t = String.valueOf(fraction.numMeasurements());
285 290
286 for (SQ sq: fraction.getMeasurements()) { 291 if (includeMeasurements) {
292 for (SQ sq: fraction.getMeasurements()) {
293 retval.add(new String[] {
294 km,
295 name,
296 a,
297 b,
298 sd, // 4
299 max_q, // 5
300 r2, // 6
301 t, // 7
302 o, // 8
303 c_duan, // 9
304 c_ferguson, // 10
305 sqAFormatter.format(sq.getS()),
306 fZeroFormatter.format(sq.getQ()),
307 df.format(sq.getDate())
308 });
309 }
310 } else {
287 retval.add(new String[] { 311 retval.add(new String[] {
288 km, 312 km,
289 name, 313 name,
290 a, 314 a,
291 b, 315 b,
293 max_q, // 5 317 max_q, // 5
294 r2, // 6 318 r2, // 6
295 t, // 7 319 t, // 7
296 o, // 8 320 o, // 8
297 c_duan, // 9 321 c_duan, // 9
298 c_ferguson, // 10 322 c_ferguson // 10
299 sqAFormatter.format(sq.getS()),
300 fZeroFormatter.format(sq.getQ()),
301 df.format(sq.getDate())
302 }); 323 });
303 } 324 }
304 325
305 } 326 }
306 return retval; 327 return retval;
311 SQRelationJRDataSource source = new SQRelationJRDataSource(); 332 SQRelationJRDataSource source = new SQRelationJRDataSource();
312 333
313 addMetaData(source); 334 addMetaData(source);
314 for (SQResult [] results: data) { 335 for (SQResult [] results: data) {
315 for (SQResult result: results) { 336 for (SQResult result: results) {
316 for (String[] res: data2StringArrays(result)) { 337 for (String[] res: data2StringArrays(result, false)) {
317 source.addData(res); 338 source.addData(res);
339 }
340 }
341 }
342 return source;
343 }
344
345 protected SQMeasurementsJRDataSource createMeasurementJRData() {
346 SQMeasurementsJRDataSource source = new SQMeasurementsJRDataSource();
347 NumberFormat fZeroFormatter = Formatter.getFormatter(context, 0, 0);
348 NumberFormat fEightFormatter = Formatter.getFormatter(context, 0, 8);
349 DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT,
350 Resources.getLocale(context.getMeta()));
351
352 for (SQResult [] results: data) {
353 for (SQResult result: results) {
354 for (int i = 0; i < SQResult.NUMBER_FRACTIONS; ++i) {
355 String name = result.getFractionName(i);
356 SQFractionResult fraction = result.getFraction(i);
357 for (SQ sq: fraction.getMeasurements()) {
358 source.addData(new String[] {
359 name,
360 fEightFormatter.format(sq.getS()),
361 fZeroFormatter.format(sq.getQ()),
362 df.format(sq.getDate()),
363 null
364 });
365 }
366 for (int j = 0; j < fraction.numIterations(); j++) {
367 for (SQ sq: fraction.getOutliers(j)) {
368 source.addData(new String[] {
369 name,
370 fEightFormatter.format(sq.getS()),
371 fZeroFormatter.format(sq.getQ()),
372 df.format(sq.getDate()),
373 Integer.toString(j + 1)
374 });
375 }
376 }
318 } 377 }
319 } 378 }
320 } 379 }
321 return source; 380 return source;
322 } 381 }
371 430
372 @Override 431 @Override
373 protected void writePDF(OutputStream out) { 432 protected void writePDF(OutputStream out) {
374 log.debug("write PDF"); 433 log.debug("write PDF");
375 SQRelationJRDataSource source = createJRData(); 434 SQRelationJRDataSource source = createJRData();
435 SQMeasurementsJRDataSource measureSource = createMeasurementJRData();
376 436
377 String jasperFile = Resources.getMsg( 437 String jasperFile = Resources.getMsg(
378 context.getMeta(), 438 context.getMeta(),
379 JASPER_FILE, 439 JASPER_FILE,
380 "/jasper/sqrelation_en.jasper"); 440 "/jasper/sqrelation_en.jasper");
441 String jasperMeasurementsFile = Resources.getMsg(
442 context.getMeta(),
443 JASPER_MEASUREMENTS_FILE,
444 "/jasper/sqmeasurements_en.jasper");
381 String confPath = Config.getConfigDirectory().toString(); 445 String confPath = Config.getConfigDirectory().toString();
382 446
383 447
384 Map parameters = new HashMap(); 448 Map parameters = new HashMap();
385 parameters.put("ReportTitle", Resources.getMsg( 449 parameters.put("ReportTitle", Resources.getMsg(
386 context.getMeta(), PDF_TITLE, "Exported Data")); 450 context.getMeta(), PDF_TITLE, "Exported Data"));
387 try { 451 try {
388 JasperPrint print = JasperFillManager.fillReport( 452 /* Page numbers start have a built in offset of 1 so this
453 * is fine. */
454 JasperPrint p2 = JasperFillManager.fillReport(
455 confPath + jasperMeasurementsFile,
456 parameters,
457 measureSource);
458 parameters.put("MEASUREMENT_PAGE_NUM", p2.getPages().size());
459 JasperPrint p1 = JasperFillManager.fillReport(
389 confPath + jasperFile, 460 confPath + jasperFile,
390 parameters, 461 parameters,
391 source); 462 source);
392 JasperExportManager.exportReportToPdfStream(print, out); 463 for (Object page: p2.getPages()) {
464 JRPrintPage object = (JRPrintPage)page;
465 p1.addPage(object);
466 }
467 JasperExportManager.exportReportToPdfStream(p1, out);
393 } 468 }
394 catch(JRException je) { 469 catch(JRException je) {
395 log.warn("Error generating PDF Report!", je); 470 log.warn("Error generating PDF Report!", je);
396 } 471 }
397 } 472 }

http://dive4elements.wald.intevation.org