2016-05-04 34 views
3

2つのシンプルなSVGドキュメントをPDFに変換して、各ドキュメントがPDFの1ページに収まるようにしたいとします。JavaとApache Batikを使用したSVGからの複数ページのPDF生成

私の最初のSVGドキュメントは以下のように見える2つの長方形があります

1st SVG doc

を2つ目は黒い円です。

コードは以下のようになります。

import java.io.*; 
import org.apache.batik.anim.dom.*; 
import org.apache.batik.transcoder.*; 
import org.w3c.dom.*; 

public class MultiPagePdf { 

    public static void main(String[] args) { 

    MultiPagePDFTranscoder transcoder = new MultiPagePDFTranscoder(); 
    try { 
     final DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); 
     SVGOMDocument doc1 = (SVGOMDocument) impl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null); 

     // 1st rectangle in doc1 
     Element el = doc1.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "rect"); 
     el.setAttributeNS(null, "width", "60"); 
     el.setAttributeNS(null, "height", "60"); 
     el.setAttributeNS(null, "fill", "none"); 
     el.setAttributeNS(null, "stroke", "blue"); 
     SVGOMSVGElement docEl = (SVGOMSVGElement) doc1.getDocumentElement(); 
     docEl.appendChild(el); 

     // 2nd rectangle in doc1 
     Element ell = doc1.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "rect"); 
     ell.setAttributeNS(null, "x", "50"); 
     ell.setAttributeNS(null, "y", "50"); 
     ell.setAttributeNS(null, "width", "25"); 
     ell.setAttributeNS(null, "height", "25"); 
     ell.setAttributeNS(null, "fill", "green"); 
     docEl.appendChild(ell); 

     final DOMImplementation impl2 = SVGDOMImplementation.getDOMImplementation(); 
     SVGOMDocument doc2 = (SVGOMDocument) impl2.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null); 
     // circle in doc2 
     Element el2 = doc2.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "circle"); 
     el2.setAttributeNS(null, "cx", "130"); 
     el2.setAttributeNS(null, "cy", "100"); 
     el2.setAttributeNS(null, "r", "50"); 
     SVGOMSVGElement docEl2 = (SVGOMSVGElement) doc2.getDocumentElement(); 
     docEl2.appendChild(el2); 

     OutputStream outputStream = new FileOutputStream(new File("/C:/Users/ah/Documents/simpleMulti.pdf")); 
     TranscoderOutput transcoderOutput = new TranscoderOutput(outputStream); 

     Document[] doccs = { doc1, doc2 }; 
     transcoder.transcode(doccs, null, transcoderOutput); // generate PDF doc 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
} 

私は両方のSVG文書を印刷してきたし、彼らが必要として、彼らが見て:

第一SVGドキュメント:

<?xml version="1.0" encoding="UTF-8"?> 
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0"> 
    <rect fill="none" width="60" height="60" stroke="blue"/> 
    <rect fill="green" x="50" width="25" height="25" y="50"/> 
</svg> 

第二SVGドキュメント:

<?xml version="1.0" encoding="UTF-8"?> 
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" version="1.0"> 
    <circle r="50" cx="130" cy="100"/> 
</svg> 

Apache FOPを使用してa code that should be doing what I'm afterが見つかりました。 PDFを生成する次のコードがあります。

import java.io.*; 
import java.util.*; 
import org.apache.batik.transcoder.*; 
import org.apache.fop.*; 
import org.apache.fop.svg.*; 
import org.w3c.dom.*; 

public class MultiPagePDFTranscoder extends AbstractFOPTranscoder { 

    protected PDFDocumentGraphics2D graphics = null; 
    protected Map<String, Object> params = null; 

    public MultiPagePDFTranscoder() { 
    super(); 
    } 

    protected void transcode(Document[] documents, String uri, TranscoderOutput output) throws TranscoderException { 
    graphics = new PDFDocumentGraphics2D(isTextStroked()); 
    graphics.getPDFDocument().getInfo().setProducer("Apache FOP Version " + Version.getVersion() + ": PDF Transcoder for Batik"); 

    try { 
     OutputStream out = output.getOutputStream(); 
     if (!(out instanceof BufferedOutputStream)) { 
     out = new BufferedOutputStream(out); 
     } 
     for (int i = 0; i < documents.length; i++) { 
     Document document = documents[i]; 
     super.transcode(document, uri, null); 
     int tmpWidth = 300; 
     int tmpHeight = 300; 
     if (i == 0) { 
      graphics.setupDocument(out, tmpWidth, tmpHeight); 
     } else { 
      graphics.nextPage(tmpWidth, tmpHeight); 
     } 

     graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); 
     graphics.transform(curTxf); 
     this.root.paint(graphics); 
     } 
     graphics.finish(); 
    } catch (IOException ex) { 
     throw new TranscoderException(ex); 
    } 
    } 
} 

PDFファイルが生成されましたが、2つの問題があります。

  1. SVG要素の翻訳とスケールが正しくありません。

  2. 2番目のページには、最初のドキュメントが存在します(私は複数のページを試しましたが、すべての以前のドキュメントは現在のページにあります)。私は、Apacheのバティック1.8でのApache FOP 2.1を使用

The generated PDF document.

どちらの問題についても助けてください。 私は、SVGを複数ページのPDFに変換するという私の全体的なタスクの他のソリューションにもオープンしています。

答えて

1

私にも同様の問題がありました。私が行ったのは、Batik(org.apache.batik.apps.rasterizer.SVGConverter)のSVGConverterアプリケーションを使用して単一のSVGをPDFに変換し、PDFBox(org.apache.pdfbox。 multipdf.PDFMergerUtility)。単一ページのPDF(複数可)に

コンバートSVG:

File outputFile = new File(pdfPath); 
SVGConverter converter = new SVGConverter(); 
converter.setDestinationType(DestinationType.PDF); 
converter.setSources(new String[] { svgPath }); 
converter.setDst(outputFile); 
converter.execute(); 

は一緒にPDFを参加:

File pdffile = new File(multipagepdfPath); 
PDFMergerUtility pdf = new PDFMergerUtility(); 
pdf.setDestinationFileName(pdffile.getPath()); 
pdf.addSource(page1pdffile); 
pdf.addSource(page2pdffile); 
pdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly()); 
//The memory settings depend on if you want to use RAM or Temp files. 

あなたがよりよい解決策を見つけた場合は私に知らせてください。 私が持っていた主な問題は、PDFファイルに変換してサイズを正しく保持するコンバータアプリがBatikの唯一のアプリケーションだということでした。

+0

お返事ありがとうございます。 :) – artofdoe

+0

それぞれのPDFを別々に作成せずに、そのようなPDFを作成し、最後にすべてを1つにマージする方が良い解決策を見つけましたか?パフォーマンスはどうですか?私は約3 000ページでPDFを生成する必要があります。各ページは同じSVGに基づいていますが、内容が変更されています。 – kabra

0

rsvg-convertは複数のsvgドキュメントを1つのPDFに変換できます。

rsvg-convert -f pdf -o out.pdf file1.svg file2.svg file3.svg 

またはフォルダ内のすべてのファイルの

rsvg-convert -f pdf -o out.pdf *.svg 

かかわらのJavaでこれを行う方法を知ってはいけません。ちょっと考えました...

関連する問題