Как заставить PreviewDialog Apache FOP действительно отображать мой документ?

Как бы я ни искал, я не нашел здесь решения своей проблемы, и я надеюсь, что объединенные умы StackOverflow подтолкнут меня в правильном направлении.

Моя проблема заключается в следующем: я разрабатываю часть пользовательского агента системы обмена сообщениями для печати и предварительного просмотра. Мне дали определенные шаблоны XSLT, которые после преобразования XML создадут документ Formatting Objects. С Apache FOP я смог преобразовать документ FO в PDF, и это хорошо, но я также хотел бы отобразить его в диалоговом окне предварительного просмотра. Apache FOP содержит такой класс с именем PreviewDialog, который требует в своем конструкторе FOUserAgent, который я могу сгенерировать, и объект, реализующий интерфейс Renderable.

Интерфейс Renderable имеет один реализующий класс в пакете FOP, который называется InputHandler и принимает в своем конструкторе стандартный объект io File. Теперь вот где начинается беда. В настоящее время я сохраняю документ FO в виде временного файла и передаю его как объект File экземпляру InputHandler, который затем передается в PreviewDialog. Я вижу, как диалоговое окно появляется на моем экране, а внизу в строке состояния говорится, что он создает документ, и это все, что он делает.

Вот код, который я пытаюсь использовать. Это не производственный код, так что это некрасиво:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.cli.InputHandler;
import org.apache.fop.render.awt.viewer.PreviewDialog;

public class PrintPreview {

    public void showPreview(final File xslt, final File xmlSource) {
        boolean err = false;
        OutputStream out = null;
        Transformer transformer = null;

        final String tempFileName = this.getTempDir()
                + this.generateTempFileName();
        final String tempFoFile = tempFileName + ".fo";
        final String tempPdfFile = tempFileName + ".pdf";
        System.out.println(tempFileName);

        final TransformerFactory transformFactory = TransformerFactory
                .newInstance();
        final FopFactory fopFactory = FopFactory.newInstance();

        try {
            transformer = transformFactory
                    .newTransformer(new StreamSource(xslt));
            final Source src = new StreamSource(xmlSource);
            out = new FileOutputStream(tempFoFile);
            final Result res = new StreamResult(out);

            transformer.transform(src, res);
            System.out.println("XSLT Transform Completed");
        } catch (final TransformerConfigurationException e) {
            err = true;
            e.printStackTrace();
        } catch (final FileNotFoundException e) {
            err = true;
            e.printStackTrace();
        } catch (final TransformerException e) {
            err = true;
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (final IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        System.out.println("Initializing Preview");
        transformer = null;
        out = null;
        final File fo = new File(tempFoFile);
        final File pdf = new File(tempPdfFile);

        if (!err) {

            final FOUserAgent ua = fopFactory.newFOUserAgent();
            try {
                transformer = transformFactory.newTransformer();
                out = new FileOutputStream(pdf);
                out = new BufferedOutputStream(out);

                final Fop fop = fopFactory.newFop(
                        MimeConstants.MIME_PDF, ua,
                            out);

                final Source foSrc = new StreamSource(fo);
                final Result foRes = new SAXResult(fop.getDefaultHandler());

                transformer.transform(foSrc, foRes);

                System.out.println("Transformation Complete");

        } catch (final FOPException e) {
            err = true;
            e.printStackTrace();
        } catch (final FileNotFoundException e) {
            err = true;
            e.printStackTrace();
        } catch (final TransformerException e) {
            err = true;
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (final IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        if (!err) {
            System.out.println("Attempting to Preview");
            final InputHandler inputHandler = new InputHandler(fo);

            PreviewDialog.createPreviewDialog(ua, inputHandler, true);
        }
    }

    // perform the clean up
    // f.delete();

}

private String getTempDir() {

    final String p = "java.io.tmpdir";

    return System.getProperty(p);

}

private String generateTempFileName() {
    final String charset = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890";
    final StringBuffer sb = new StringBuffer();
    Random r = new Random();
    int seed = r.nextInt();
    r = new Random(seed);
    for (int i = 0; i < 8; i++) {
        final int n = r.nextInt(71);
        seed = r.nextInt();
        sb.append(charset.charAt(n));
        r = new Random(seed);
    }

    return sb.toString();
}

}

Любая помощь в этом будет оценена по достоинству.


person JRSofty    schedule 12.01.2011    source источник


Ответы (3)


Ответ, кажется, отказывается от попытки использовать диалог предварительного просмотра в Apache FOP и вместо этого использует Apache PDFBox для создания предварительного просмотра с использованием класса PDFPagePanel для отображения изменений.

person JRSofty    schedule 13.01.2011

На самом деле я не нашел красивого способа скрыть кнопку debug и fop inf, которые отображаются на панели инструментов. Мне пришлось создать свой PreviewDialog, в основном на основе фопового, но без этих двух кнопок.

person lplasse    schedule 25.02.2011

CreatePreviewDialog должен быть создан ДО преобразования в pdf.

    FopFactory fopFactory = FopFactory.newInstance();
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 
    AWTRenderer renderer = new AWTRenderer();      
    renderer.setPreviewDialogDisplayed(false);
    foUserAgent.setRendererOverride(renderer);
    renderer.setUserAgent(foUserAgent);
    PreviewDialog previewDlg = PreviewDialog.createPreviewDialog(foUserAgent, null, false);
    renderer.setStatusListener(previewDlg);
    renderer.clearViewportList();

    TransformerFactory transformFactory = TransformerFactory.newInstance();

    Transformer transformerFo = transformFactory.newTransformer(new StreamSource(xslt));
    FileOutputStream fileoutFo = new FileOutputStream(tempFoFile);
    BufferedOutputStream outFo = new BufferedOutputStream(fileoutFo);
    transformerFo.transform (new StreamSource(xml),new StreamResult(outFo));

    Transformer transformerPdf = transformFactory.newTransformer();
    FileOutputStream fileoutPdf = new FileOutputStream(tempPdfFile);
    BufferedOutputStream outPdf = new BufferedOutputStream(fileoutPdf);

    final Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, 
                                      foUserAgent, outPdf);
    Source srcPdf = new StreamSource(fo);
    Result resPdf = new SAXResult(fop.getDefaultHandler());
    transformerPdf.transform(srcPdf, resPdf);
person lplasse    schedule 23.02.2011
comment
Спасибо за информацию. У меня еще не было возможности попробовать это. В настоящее время я использую решение, которое нашел сам, как только я попробую ваше, возможно, мы просто рефакторим код и изменим решение. Панель PDFBox в порядке, но она не очень хорошо отображается. Я надеюсь, что FOP немного улучшит ситуацию. - person JRSofty; 24.02.2011