Skip to main content

Export

In manchen Situationen gibt es die Anforderung das aktuell im Viewer angezeigte Dokument in einer Drittanwendung weiterzuverarbeiten. Für solche Anforderungen bietet das jadice web toolkit die Möglichkeit ein Dokument serverseitig in die Formate PDF, TIFF und Postscript zu exportieren. Die exportierte Datei kann dann an eine Drittanwendung übergeben werden. Zu beachten dabei ist, dass die Exportfunktion für die Druckdatenaufbereitung entwickelt wurde. Daher liegt der primäre Fokus auf der Gewährleistung eines optisch einwandfreien Exportergebnisses, nicht auf anderen Aspekten, wie beispielsweise der Durchsuchbarkeit der resultierenden Daten.

Unterstützte Exportformate

Das jadice web toolkit unterstützt direkt die folgenden Formate für die Erstellung von Exports:

Postscript (PS)

Postscript wird häufig für den Druck verwendet. Einige Drucker unterstützen dieses Format ohne weitere Konvertierung.

Portable Document Format (PDF)

Das Portable Document Format (PDF) ist für den konsistenten Austausch von Dokumenten entwickelt worden.

Tagged Image File Format (TIFF)

TIFF ist primär ein Format für Bilddaten.

Die Exporter-API

Um Exports zu erzeugen, stellt das jadice web toolkit eine entsprechende API zur Verfügung. Diese ermöglicht es, Dokumente, welche im Web-Client zur Anzeige gebracht werden, über den Server in ein gewünschtes Format zu überführen.

Exporter selbst ist ein allgemeines Interface, das eine grundsätzliche API für die Erstellung von Exportdatenströmen bereitstellt.

Eine konkrete Instanz eines Exporter kann über die ExporterFactory erstellt werden. Diese Klasse stellt eine Reihe von Methoden für die Erzeugung von Exporter für verschiedene Formate bereit.

ExporterFactory. createPostscriptExporter

Erstellt einen Exporter für die Ausgabe in das Postscript Format.
Achtung: Um Postscript erzeugen zu können, muss die eingesetzte JVM eine Postscript-Unterstützung bieten. Ist dies nicht der Fall, ist der Rückgabewert der Methode null.

ExporterFactory. createPDFExporter

Erstellt einen Exporter für die Ausgabe in das PDF Format.
Hierbei ist zu beachten, dass der generierte Datenstrom für die Aufbereitung und Erstellung von Dokumenten für den Druck entwickelt wurde. Daher liegt der primäre Fokus auf der Gewährleistung eines optisch einwandfreien Druckergebnisses, nicht auf anderen Aspekten, wie beispielsweise der Durchsuchbarkeit der resultierenden Daten.

ExporterFactory. createPDFExporter(AbstractOpenAction)

Erstellt einen Exporter für die Ausgabe in das PDF Format. Die erzeugte Exporter-Instanz bettet die übergebene "Open Action" in den generierten Datenstrom ein. Wird der Datenstrom mit einem PDF Viewer geöffnet, der Open Actions unterstützt (z.B. Internet Explorer 11, Chrome, Firefox, Edge oder Acrobat Reader), blendet dieser z.B. im Falle einer PrintOpenAction direkt ohne weitere Benutzeraktion seinen Druckdialog ein.

ExporterFactory. createRasterizingPDFExporter

Erstellt einen Exporter für eine gerasterte Ausgabe im PDF Format.
Der generierte Datenstrom besteht rein aus gerasterten Daten, so dass z.B. die Durchsuchbarkeit der resultierenden Daten nicht mehr gegeben ist. Ein typischer Anwendungsfall für diese Art von Export ist das Schwärzen von Dokumentpassagen, um sicherzustellen, dass etwaige Textinhalte unter einer schwärzenden Maskierung nicht mehr zugänglich sind.

ExporterFactory. createPDFaExporter(AbstractOpenAction, Conformance)

Erstellt einen Exporter für die Ausgabe in das PDF/A Format. Die erzeugte Exporter-Instanz bettet die übergebene "Open Action" in den generierten Datenstrom ein (s.o.). Zudem wird ein Conformance-Level benötigt, nach welchem das PDF/A-Dokument erzeugt wird.

ExporterFactory. createTIFFExporter

Erstellt einen Exporter für die Ausgabe in das TIFF Format.

Abhängigkeiten

Um die Export-Funktion nutzen zu können, muss die entsprechende Maven-Dependency eingebunden werden:

com.levigo.jadice.webtoolkitwebtoolkit-export

Verwendung der Exporter-API

Die Verwendung der Exporter- API folgt im Allgemeinen einem einfachen Ablaufschema.

Ablauf einer Export-Datenstrom-Erzeugung mit der Exporter-API:

Document document = // document reference created elsewhere (1)
OutputStream out = new FileOutputStream(new File("outfile.pdf")); // (2)

Exporter exporter = ExporterFactory.createPDFExporter(); // (3)

document.getPages().getReadWriteLock().readLock().lock(); // (4)
try {

printer.getSourcePages().addAll(document.getPages());

} finally {
document.getPages().getReadWriteLock().readLock().unlock();
}

exporter.export(out); // (5)

out.close(); // (6)
  1. Das zu druckende Document. Diese Document Instanz kann aus verschiedensten Quellen stammen. Die gebräuchlichste Art ist die Verwendung der Document-Referenz innerhalb einer ServerOperation. Details zu dieser Vorgehensweise sind im Kapitel „Export mittels einer ServerOperation “ zu finden.
  2. Ein java.io.OutputStream , welcher als Ausgabeziel verwendet werden soll. In diesem Beispiel wird der Datenstrom in eine lokale Datei geschrieben. Auf einem ähnlichen Weg könnten Druckdaten über das Netzwerk an einen Printserver verschickt werden.
  3. Erstellen eines Exporter. In diesem Beispiel wird ein PDF Exporter erzeugt.
  4. Setzen der zu exportierenden Seiten. Hierbei ist es wichtig, die Seitenliste mit einem ReadWriteLock zu sperren, um Modifikationen von anderen Threads an diesem Document vorzubeugen.
  5. Ausführen des eigentlichen Exports. Hierbei werden die Exportdaten in den mit out benannten OutputStream geschrieben.
  6. Wurde der Export durchgeführt, muss der OutputStream noch geschlossen werden. Wird dies nicht gemacht, kann nicht sichergestellt werden, dass die verwendete java.io.OutputStream -Implementation keine Daten mehr im Hauptspeicher zwischenpuffert.

Export mittels einer ServerOperation

Der empfohlene Weg für das Exportieren eines Dokumentes aus der Webanwendung heraus ist die Verwendung einer ServerOperation. Hierfür bietet das jadice web toolkit bereits vorbereitete ServerOperation Basisklassen an. Diese haben den Vorteil, dass die Erstellung einer Exporter Instanz bereits vorbereitet ist.

Standardmäßig stehen folgende Basisklassen zur Verfügung:

AbstractPostscriptExportServerOperation

Export eines Dokuments als Postscript-Datenstrom.

AbstractPDFExportServerOperation

Export eines Dokuments als PDF-Datenstrom.

AbstractTIFFExportServerOperation

Export eines Dokuments als TIFF -Datenstrom.

AbstractExportServerOperation

Export eines beliebigen der oben aufgeführten Datenströme.

Implementation einer ServerOperation

Die Erstellung einer konkreten Implementation für diese abstrakten Basisklassen unterscheidet sich hauptsächlich in der Wahl der Basisklasse, die erweitert wird. Exemplarisch wird im Folgenden ein generisches Beispiel vorgestellt, das alle der drei oben aufgeführten Export-Formate erstellen kann. Falls nicht alle der aufgeführten Datenstrom-Formate erzeugt werden müssen, sollte eine Variante für den spezifischen Datenstrom gewählt werden.

public class ExportServerOperation
extends AbstractExportServerOperation<ExportParameters, ServerOperationMessage, Exporter> {

private final ExportRepository repository;

public ExportServerOperation(final ExportRepository repository) {
this.repository = repository;
}

@Override
protected void doExport(final Request<ExportParameters> request, // (1)
final ResponseChannel<ServerOperationMessage> responseChannel, final Exporter exporter)
throws Exception {

final ExportParameters.Type type = request.getParameters().getType();

responseChannel.send(new ExportStartedMessage()); // (2)

final EventList<Page> pages = request.getDocument().getPages();
// ensuring that there will be not concurrent writing access to the document
pages.getReadWriteLock().readLock().lock();
try {
// attach all pages that will be printed
exporter.getSourcePages().addAll(pages); // (3)
} finally {
// allow modifications
pages.getReadWriteLock().readLock().unlock();
}

final File file = File.createTempFile("export-", type.getExtension());
final FileOutputStream output = new FileOutputStream(file); // (4)

// export the document into a file
exporter.export(output); // (5)

output.close(); // (6)

// register the output file containing the print
final ExportMeta meta = new ExportMeta(file);
meta.setMimeType(type.getMimeType());
final String id = repository.register(meta);
// send registration id to the client
// the client may download the file by using this id
responseChannel.send(new ExportCompletedMessage(id)); // (7)

}

@Override
protected Exporter createExporter(final Request<ExportParameters> request) {

switch (request.getParameters().getType()){
case PDF: return ExporterFactory.createPDFExporter();
case PDF_SHOW_PRINT_DIALOG_ON_OPEN :
return ExporterFactory.createPDFExporter(new PrintOpenAction()); // (8)
case POSTSCRIPT: return ExporterFactory.createPostscriptExporter();
case TIFF: return ExporterFactory.createTIFFExporter();
}

throw new IllegalArgumentException("Unknown format type specified");
}
}
  1. Diese Methode muss von der implementierenden Klasse implementiert werden.

  2. Um dem Client den Beginn der Verarbeitung zurück zu melden, wird eine ExportStartedMessage übermittelt.

  3. Setzen der zu exportierenden Seiten. Hierbei ist es wichtig, die Seitenliste mit einem ReadWriteLock zu sperren, um Modifikationen von anderen Threads an diesem Document vorzubeugen.

  4. Ein java.io.OutputStream, welcher als Ausgabeziel verwendet werden soll. Hier könnte beispielsweise ein java.io.OutputStream erstellt werden, welcher Druckdaten über das Netzwerk an einen Printserver verschickt.

  5. Ausführen des eigentlichen Exports. Hierbei werden die Daten in den mit output benannten OutputStream geschrieben.

  6. Wurde der Exportvorgang durchgeführt, muss der OutputStream noch geschlossen werden. Wird dies nicht gemacht, kann nicht sichergestellt werden, dass die verwendete java.io.OutputStream -Implementation keine Daten mehr im Hauptspeicher zwischenpuffert.

  7. Um dem Client eine erfolgreiche Verarbeitung zurück zu melden, wird eine ExportCompletedMessage übermittelt.

  8. Einbetten einer Print "Open Action" in das generierte PDF. Wird das PDF in einem Viewer geöffnet, der Open Actions unterstützt, zeigt dieser automatisch nach dem Öffnen des Datenstroms seinen Druckdialog.

Registrieren der ServerOperation

Das Registrieren der im vorherigen Beispiel implementierten ExportServerOperation erfolgt identisch zu allen anderen Arten von ServerOperations.

In den meisten Fällen wird hierfür in einem WebtoolkitServletContextListener die ServerOperation bei der ServerOperationRegistry mit der zugehörigen ServerOperationParameters Klasse als Key registriert.

ApplicationServletContextListener

    public class ApplicationServletContextListener extends WebtoolkitServletContextListener {

@Override
protected void contextInitialized(ServletContextEvent sce, WebtoolkitServerContext webtoolkitContext) {

final ExportRepository repository = ExportRepository.get(sce.getServletContext());

final ServerOperationRegistry serverOperationRegistry = webtoolkitContext.getServerOperationRegistry();
serverOperationRegistry.register(ExportParameters.class, new ExportServerOperation(repository));
}
}

Ausführen der ServerOperation

Wurde die ServerOperation in der ServerOperationRegistry registriert, kann diese vom Client aus aufgerufen werden. In der Demo Basicviewer wird hierzu ein zugehöriger Button in der Toolbar angelegt.

Triggern des Exports über einen Button:

toolbar.add(new JadiceDefaultButton(ActionFactory.createExportPDFAction(actionRegistry, context)));