/** @see de.willuhn.jameica.hbci.io.print.AbstractPrintSupport#printContent() */
  Print printContent() throws ApplicationException {
    Object data = this.ctx;

    if (data == null) throw new ApplicationException(i18n.tr("Bitte wählen Sie einen Auftrag aus"));

    if (data instanceof TablePart) data = ((TablePart) data).getSelection();

    if (!(data instanceof SammelTransfer))
      throw new ApplicationException(i18n.tr("Bitte wählen Sie einen Auftrag aus"));

    try {
      SammelTransfer a = (SammelTransfer) data;
      Konto k = a.getKonto();

      // Das Haupt-Layout
      GridPrint grid = new GridPrint("l:d:g");

      // Die eigentlich Tabelle mit den Werten
      {
        DefaultGridLook look = new DefaultGridLook(5, 5);
        GridPrint table = new GridPrint("l:p:n, l:d:g", look);

        // Bezeichnung
        table.add(new TextPrint(i18n.tr("Bezeichnung"), fontNormal));
        table.add(new TextPrint(notNull(a.getBezeichnung()), fontBold));

        // Konto
        table.add(new TextPrint(i18n.tr("Konto"), fontNormal));
        table.add(new TextPrint(notNull(k != null ? k.getLongName() : null), fontNormal));

        // Termin
        Date termin = a.getTermin();
        table.add(new TextPrint(i18n.tr("Fällig am"), fontNormal));
        table.add(new TextPrint(termin == null ? "-" : HBCI.DATEFORMAT.format(termin), fontNormal));

        // Summe
        table.add(new TextPrint(i18n.tr("Summe"), fontNormal));
        table.add(
            new TextPrint(
                HBCI.DECIMALFORMAT.format(a.getSumme()) + " " + k.getWaehrung(), fontBold));

        // Ausfuehrungsstatus
        Date ausgefuehrt = a.getAusfuehrungsdatum();
        table.add(new TextPrint(i18n.tr("Ausgeführt"), fontNormal));
        if (ausgefuehrt != null)
          table.add(new TextPrint(HBCI.DATEFORMAT.format(ausgefuehrt), fontBold));
        else table.add(new TextPrint(a.ausgefuehrt() ? "Ja" : "Nein", fontBold));

        grid.add(table); // Zum Haupt-Layout hinzufuegen
      }

      // Leerzeile
      grid.add(new LineBreakPrint(fontNormal));
      grid.add(new LineBreakPrint(fontNormal));

      // Liste der Buchungen
      grid.add(new TextPrint(i18n.tr("Enthaltene Buchungen"), fontBold));

      // Leerzeile
      grid.add(new LineBreakPrint(fontNormal));

      DBIterator buchungen = a.getBuchungen();
      if (buchungen.size() > 0) {
        DefaultGridLook look = new DefaultGridLook();
        look.setHeaderBackground(new RGB(220, 220, 220));

        LineBorder border = new LineBorder(new RGB(100, 100, 100));
        border.setGapSize(3);
        look.setCellBorder(border);

        GridPrint table = new GridPrint("r:d:n, l:d:n, l:p:g, l:p:n, r:p:n", look);
        table.addHeader(new TextPrint(i18n.tr("Nr."), fontTinyBold));
        table.addHeader(new TextPrint(i18n.tr("Gegenkonto"), fontTinyBold));
        table.addHeader(new TextPrint(i18n.tr("Zweck"), fontTinyBold));
        table.addHeader(new TextPrint(i18n.tr("Typ"), fontTinyBold));
        table.addHeader(new TextPrint(i18n.tr("Betrag"), fontTinyBold));

        int count = 0;
        while (buchungen.hasNext()) {
          SammelTransferBuchung b = (SammelTransferBuchung) buchungen.next();
          String usage = VerwendungszweckUtil.toString(b, "\n");

          table.add(new TextPrint(Integer.toString(++count), fontTiny));
          table.add(
              new TextPrint(
                  i18n.tr(
                      "{0}, Kto. {1}, BLZ {2}",
                      b.getGegenkontoName(), b.getGegenkontoNummer(), b.getGegenkontoBLZ()),
                  fontTiny));
          table.add(new TextPrint(usage, fontTiny));
          table.add(new TextPrint(notNull(TextSchluessel.get(b.getTextSchluessel())), fontTiny));
          table.add(
              new TextPrint(
                  HBCI.DECIMALFORMAT.format(b.getBetrag()) + " " + k.getWaehrung(), fontTiny));
        }
        grid.add(table); // Zum Haupt-Layout hinzufuegen
      } else {
        grid.add(new TextPrint("- " + i18n.tr("keine") + " -", fontTiny));
      }

      return grid;
    } catch (RemoteException re) {
      Logger.error("unable to print data", re);
      throw new ApplicationException(i18n.tr("Druck fehlgeschlagen: {0}", re.getMessage()));
    }
  }
  /**
   * @see de.willuhn.jameica.hbci.io.Exporter#doExport(java.lang.Object[],
   *     de.willuhn.jameica.hbci.io.IOFormat, java.io.OutputStream, de.willuhn.util.ProgressMonitor)
   */
  public void doExport(Object[] objects, IOFormat format, OutputStream os, ProgressMonitor monitor)
      throws RemoteException, ApplicationException {
    if (os == null)
      throw new ApplicationException(i18n.tr("Kein Ausgabe-Ziel für die Datei angegeben"));

    if (format == null) throw new ApplicationException(i18n.tr("Kein Ausgabe-Format angegeben"));

    if (objects == null || objects.length == 0)
      throw new ApplicationException(i18n.tr("Keine zu exportierenden Daten angegeben"));

    if (!(objects instanceof SammelTransfer[]))
      throw new ApplicationException(
          i18n.tr("Die zu exportierenden Daten enthalten keine Sammel-Aufträge"));

    DtausDateiWriter writer = null;

    try {
      writer = new DtausDateiWriter(os);
      for (int i = 0; i < objects.length; ++i) {
        SammelTransfer transfer = (SammelTransfer) objects[i];
        Konto konto = transfer.getKonto();
        GenericIterator buchungen = transfer.getBuchungen();

        monitor.setPercentComplete(0);
        monitor.setStatusText(i18n.tr("Exportiere logische Datei Nr. {0}", "" + (i + 1)));

        double factor = 100d / buchungen.size();
        int count = 0;
        int success = 0;

        long kundenNummer = 0;
        String s = konto.getKundennummer();
        try {
          kundenNummer = Long.parseLong(s);
        } catch (Exception e) {
          monitor.log(i18n.tr("Ignoriere Kundennummer {0}: ungültig", s));
        }

        long blz = 0;
        s = konto.getBLZ();
        try {
          blz = Long.parseLong(s);
        } catch (Exception e) {
          monitor.log(i18n.tr("Ignoriere BLZ {0}: ungültig", s));
        }

        writer.open();
        writer.setAAusfuehrungsdatum(transfer.getTermin());
        writer.setABLZBank(blz);

        String type = (transfer instanceof SammelUeberweisung) ? "GK" : "LK";
        writer.setAGutschriftLastschrift(type);

        writer.setAKonto(Long.parseLong(konto.getKontonummer()));
        writer.setAKundenname(konto.getName());
        writer.writeASatz();

        while (buchungen.hasNext()) {
          // Mit diesem Factor sollte sich der Fortschrittsbalken
          // bis zum Ende der DTAUS-Datei genau auf 100% bewegen
          monitor.setPercentComplete((int) ((++count) * factor));

          SammelTransferBuchung buchung = (SammelTransferBuchung) buchungen.next();

          monitor.log(i18n.tr("Exportiere Datensatz {0}", buchung.getGegenkontoName()));

          writer.setCBetragInEuro(buchung.getBetrag());
          writer.setCBLZEndbeguenstigt(Long.parseLong(buchung.getGegenkontoBLZ()));
          writer.setCBLZErstbeteiligtesInstitut(blz);
          writer.setCKonto(Long.parseLong(buchung.getGegenkontoNummer()));
          writer.setCName(buchung.getGegenkontoName());
          writer.setCInterneKundennummer(kundenNummer);
          writer.setCTextschluessel(mapTextschluesselToDtaus(buchung));

          String[] lines = VerwendungszweckUtil.toArray(buchung);
          for (String line : lines) writer.addCVerwendungszweck(line);

          writer.writeCSatz();
          success++;
        }
        monitor.setStatusText(i18n.tr("{0} Aufträge erfolgreich exportiert", "" + success));
      }
      writer.writeESatz();
    } catch (OperationCanceledException oce) {
      Logger.info("operation cancelled");
      monitor.setStatusText(i18n.tr("Export abgebrochen"));
      monitor.setStatus(ProgressMonitor.STATUS_CANCEL);
    } catch (ApplicationException ae) {
      throw ae;
    } catch (DtausException dta) {
      Logger.error(dta.getMessage(), dta);
      throw new ApplicationException(i18n.tr(dta.getLocalizedMessage()));
    } catch (Exception e) {
      throw new RemoteException(i18n.tr("Fehler beim Export der Daten"), e);
    } finally {
      if (writer != null) {
        try {
          writer.close();
          os = null;
        } catch (Exception e) {
          Logger.error("error while closing dtaus writer", e);
        }
      }
      // Outputstream schliessen, falls das noch nicht geschehen ist
      if (os != null) {
        try {
          os.close();
        } catch (Throwable t) {
          Logger.error("unable to close file", t);
        }
      }
    }
  }