Преобразование SVG в PDF
Как можно конвертировать SVG файл в PDF файл программно? (Мне нужно изменить SVG в определенных отношениях перед созданием PDF файла, поэтому просто предварительно преобразовать его с помощью инструмента будет недостаточно).
В идеале использование Java, но Perl или PHP тоже было бы неплохо.
Очевидно, я в основном рассматриваю Apache FOP и Batik с Java. Однако сколько бы времени я ни искал, я не могу найти простого представления о том, как это сделать. Такие вещи, как SVGConverter, имеют такие описания, как "Определяет интерфейс для классов, которые могут конвертировать часть или весь GraphicContext", действительно знаю, что это значит.
У меня такое чувство, что для этого достаточно API, предоставляемый FOP или Batik, но я просто не могу его найти в данный момент (или, возможно, его действительно нет).
В отношении поддерживаемых функций SVG, которые мне нужны, в файле есть несколько путей, которые заполняются некоторыми линейными градиентами.
В идеале, если бы я мог передать SVG в качестве документа DOM, который был бы идеальным; то я бы загрузил файл шаблона SVG, изменил его, как указано пользователем, а затем сгенерировал PDF.
Ответы
Ответ 1
Благодаря Adrian для того, чтобы показать, как предполагается использовать 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
Ответ 2
Наконец-то мне удалось найти соответствующие строки кода для решения этой проблемы с помощью Batik.
У вас должен быть SVG файл и полученный PDF файл в виде файлов на диске, т.е. я не смог найти способ сделать это в памяти (я пишу HTTP-сервлет, поэтому у меня нет неотъемлемой необходимости писать что-либо как файл, в идеале я бы передал результат клиенту HTTP). Я использовал File.createTemporaryFile, чтобы создать файл для выгрузки моего 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
- фат-0.95.jar
- log4j-1.2.15.jar
- XML-АПИС-ext.jar
- xmlgraphics-Обще-1.3.1.jar
Ответ 3
вам понадобится libray для рендеринга svg и pdf.
Я рекомендую SVG salamander для первого, и iText для последнего. С svg salamander вы можете прочитать svg и создать объект изображения, а с помощью itext вы можете записать это изображение в pdf.
Ответ 4
Я использую Altsoft Xml2PDF. Если я правильно понял все ваши потребности и требования, вам лучше попробовать свою версию сервера Xml2PDF.
Ответ 5
Все, что вам нужно, это фантомы. Для этого вам не нужен громоздкий Батик; просто перейдите в точку, где вы можете запускать phantomjs, вызывая rasterize.js, используя URL-адрес pdf в качестве источника и местоположение в качестве вывода. В зависимости от того, что вы хотите делать с .pdf, вам даже не нужна Java.
http://phantomjs.org/screen-capture.html
Посмотрите на часть, начинающуюся с "Помимо формата PNG, PhantomJS поддерживает JPEG, GIF и PDF".