Задать каталог распознавателя URL при использовании сгенерированного документа XHTML? - PullRequest
2 голосов
/ 14 марта 2012

Вот мой текущий рабочий процесс:

  1. Загрузка POJO из базы данных.
  2. Передача их в Velocity, рендеринг HTML-шаблона в памяти.
  3. Затем рендерингвыводимый HTML в PDF с использованием Flying Saucer и iText.

Проблема возникает, когда я пытаюсь разрешить относительные URL-адреса, такие как изображения и тому подобное.Поскольку мой документ находится в памяти, он вообще не знает, как разрешать изображения или таблицы стилей.Как я могу установить документ для него в объект String в памяти, все еще передавая ему каталог для загрузки ресурсов?

String velocityOutput = VelocityEngineUtils.mergeTemplateIntoString(...);

ByteArrayOutputStream output = new ByteArrayOutputStream(...);

ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(velocityOutput);
renderer.layout();
renderer.createPDF(output);

Мне нужно делать все в памяти, так как я просто создаю отчет для отправки клиентам по электронной почте.Как я могу <img src="..."/> разрешить относительный URL в моем HTML-шаблоне при генерации в PDF?

Ответы [ 2 ]

2 голосов
/ 16 марта 2012

Вы должны реализовать интерфейс UserAgentCallback и установить для него значение renderer.getSharedContext().setUserAgentCallback(myUserAgentCallback);

Из Javadoc:

Пользовательский агент в этом случае отвечает за извлечение внешних ресурсов.

Чтобы понять, как создать свой собственный UAC, лучше взглянуть на некоторые из реализации, поставляемые с библиотекой, такие как {@link org.xhtmlrenderer.swing.NaiveUserAgent}.

1 голос
/ 16 марта 2012

В итоге я просто загрузил свой документ в экземпляр Java Document и затем отправил его в Flying Saucer с каталогом ресурсов за один вызов:

Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(new ByteArrayInputStream(templateOutput.getBytes("UTF-8")));

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(document, templateResourceDirectory);
    renderer.layout();

OutputStream result = new ByteArrayOutputStream();

renderer.createPDF(result);

Одна вещь, на которую следует обратить особое внимание, этотот факт, что Flying Saucer требуется файловый URI с префиксом file:// и что для правильной работы ему требуется косая черта в конце пути к файлу:

/var/www/cache         # FAIL
file:///var/www/cache  # ALSO FAIL
file:///var/www/cache/ # WIN
...