Конвертировать SVG в PDF - PullRequest
27 голосов
/ 29 июля 2011

Как можно было бы преобразовать файл SVG в PDF программно?(Мне нужно изменить SVG в определенных отношениях перед созданием PDF, поэтому простой предварительной конвертации его с помощью инструмента будет недостаточно.)

В идеале, с использованием Java, но Perl или PHP тоже подойдут.

Очевидно, я в основном рассматриваю Apache FOP и Batik с Java.Однако независимо от того, как долго я ищу, я не могу найти простое введение, как это сделать.Вещи типа SVGConverter имеют описания типа «Определяет интерфейс для классов, которые могут преобразовывать часть или весь GraphicContext», но я не знаю, что это значит.

У меня естьэто чувство, что для этого достаточно API, предоставляемого FOP или Batik, но я просто не могу найти его в данный момент (или, возможно, его действительно не существует).

ВС точки зрения поддерживаемых функций SVG мне нужно, файл имеет несколько путей, которые заполнены некоторыми линейными градиентами.

В идеале, если бы я мог передать SVG в качестве документа DOM, это было бы идеально;затем я загрузил бы свой шаблонный файл SVG, изменил его, как указано пользователем, и затем сгенерировал PDF.

Ответы [ 5 ]

18 голосов
/ 11 июля 2013

Спасибо Адриану за показ того, как предполагается использовать API растеризатора Batik. Однако мне нужно было более легкое решение - я не могу писать во временные файлы и хочу меньше зависимостей. Итак, начиная с методов, на которые он указывал, я нашел способ доступа к низкоуровневому коду для преобразования и ничего больше.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.fop.svg.PDFTranscoder;

public class Test {
    public static void main(String[] argv) throws TranscoderException, FileNotFoundException {
        Transcoder transcoder = new PDFTranscoder();
        TranscoderInput transcoderInput = new TranscoderInput(new FileInputStream(new File("/tmp/test.svg")));
        TranscoderOutput transcoderOutput = new TranscoderOutput(new FileOutputStream(new File("/tmp/test.pdf")));
        transcoder.transcode(transcoderInput, transcoderOutput);
    }
}

Команды компиляции и запуска:

javac -cp batik-rasterizer.jar -d build Test.java
java -cp build:batik-rasterizer.jar Test

Важным моментом является то, что TranscoderInput и TranscoderOutput могут работать с любыми InputStream и OutputStream , а не только файловые потоки. Обратите внимание, что один из конструкторов принимает org.w3c.dom.Document, что означает, что вам даже не нужно сериализовать SVG DOM в строку SVG, сохраняя дополнительный шаг.

Эта версия также ничего не записывает в stdout / stderr, в отличие от высокоуровневого API.

Для вывода в формате JPEG, PNG или TIFF замените org.apache.fop.svg.PDFTranscoder на org.apache.batik.transcoder.image.JPEGTranscoder, PNGTranscoder или TIFFTranscoder (обратите внимание, что эти растровые форматы находятся в другом пакете).

(Я не совсем уверен, как Java находит классы org.apache.batk.transcoder.* и org.apache.fop.svg.PDFTranscoder, поскольку я не вижу их в batik-rasterizer.jar.)

Edit:

Хотя простая компиляция из командной строки работает только с batik-rasterizer.jar, она выполняет какую-то магию загрузчика классов, чтобы найти все необходимые классы. В более реалистичном случае (создание проекта с помощью Ant) вы должны найти классы вручную. Их можно найти в batik-1.7.zip из проекта Batik и fop-1.1.zip из проекта FOP . От Batik нужно скомпилировать с batik-transcoder.jar и запустить с

  • batik-transcoder.jar
  • batik-anim.jar
  • batik-awt-util.jar
  • batik-bridge.jar
  • batik-css.jar
  • batik-dom.jar
  • batik-ext.jar
  • batik-gvt.jar
  • batik-parser.jar
  • batik-script.jar
  • batik-svg-dom.jar
  • batik-util.jar
  • batik-xml.jar
  • xml-apis-ext.jar

Из FOP вам нужно скомпилировать с fop.jar и запустить с

  • fop.jar
  • avalon-framework-4.2.0.jar
  • xmlgraphics-commons-1.5.jar
5 голосов
/ 11 августа 2011

Мне наконец-то удалось найти соответствующие строки кода, чтобы решить эту проблему, используя Batik .

. Вам необходимо иметь файл SVG и полученный PDF в виде файлов на диске, т.е.Я не мог найти способ сделать это в памяти (я пишу сервлет HTTP, поэтому у меня нет внутренней потребности писать что-либо в виде файла, в идеале я бы передавал результат в HTTP-клиент).Я использовал File.createTevenFile , чтобы создать файл для выгрузки моего SVG-файла в файл, и для получения результирующего PDF-файла.

Итак, я использовал следующие строки:

import org.apache.batik.apps.rasterizer.DestinationType;
import org.apache.batik.apps.rasterizer.SVGConverter;
import ...

// SVG available as a DOM object (created programatically by my program)
Document svgXmlDoc = ...

// Save this SVG into a file (required by SVG -> PDF transformation process)
File svgFile = File.createTempFile("graphic-", ".svg");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMSource source2 = new DOMSource(svgXmlDoc);
FileOutputStream fOut = new FileOutputStream(svgFile);
try { transformer.transform(source2, new StreamResult(fOut)); }
finally { fOut.close(); }

// Convert the SVG into PDF
File outputFile = File.createTempFile("result-", ".pdf");
SVGConverter converter = new SVGConverter();
converter.setDestinationType(DestinationType.PDF);
converter.setSources(new String[] { svgFile.toString() });
converter.setDst(outputFile);
converter.execute();

И у меня есть следующие JAR-файлы (выполните поиск с помощью Google, чтобы найти проекты и загрузить их):

  • avalon-framework-4.2.0.jar
  • batik-all-1.7.jar
  • commons-io-1.3.1.jar
  • commons-logging-1.0.4.jar
  • fop-0.95.jar
  • log4j-1.2.15.jar
  • xml-apis-ext.jar
  • xmlgraphics-commons-1.3.1.jar
4 голосов
/ 29 июля 2011

вам понадобится библиотека для рендеринга SVG и PDF. Я рекомендую SVG salamander для первых и iText для последних. С svg salamander вы можете читать svg и создавать объект изображения, а с помощью itext вы можете записать это изображение в pdf.

1 голос
/ 23 апреля 2014

Все, что вам нужно, это фантомы.Вам не нужен громоздкий батик для этого вообще;просто дойдите до точки, где вы можете запустить phantomjs, вызвав rasterize.js, используя URL-адрес pdf в качестве источника и местоположение в качестве выходного.В зависимости от того, что вы хотите сделать с .pdf, вам даже не понадобится Java.

http://phantomjs.org/screen-capture.html

Посмотрите на часть, начинающуюся с «Помимо формата PNG, PhantomJS поддерживает JPEG, GIF и PDF».

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

Я использую Altsoft Xml2PDF.Если я правильно понял все ваши потребности и требования, вам лучше попробовать их версию сервера Xml2PDF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...