2009-01-02 5 views
10

Wir verwenden iText, um PDFs aus Java zu generieren (basierend teilweise auf Empfehlungen auf dieser Website). Wenn Sie jedoch eine Kopie unseres Logos in ein Bildformat wie GIF einbetten, wird es beim Ein- und Auszoomen etwas komisch.Vektorgrafiken in iText PDF

Im Idealfall möchten wir das Bild in einem Vektorformat wie EPS, SVG oder nur eine PDF-Vorlage einbetten. Die Website behauptet, dass die EPS-Unterstützung gelöscht wurde, dass das Einbetten einer PDF oder PS in eine PDF-Datei zu Fehlern führen kann, und erwähnt SVG nicht einmal.

Unser Code verwendet die Graphics2D-API statt iText direkt, aber wir wären bereit, aus dem AWT-Modus auszubrechen und iText selbst zu verwenden, wenn es das Ergebnis erreicht. Wie kann das gemacht werden?

Antwort

8

Nach dem documentation iText unterstützt die folgenden Bildformate: JPEG, GIF, PNG, TIFF, BMP, WMF und EPS. Ich weiß nicht, ob dies eine Hilfe sein könnte, aber ich habe erfolgreich verwendet iTextSharp Vektor WMF Bild in einer PDF-Datei einbetten:

C#:

using System; 
using System.IO; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 

public class Program 
{ 

    public static void Main() 
    { 
     Document document = new Document(); 
     using (Stream outputPdfStream = new FileStream("output.pdf", FileMode.Create, FileAccess.Write, FileShare.None)) 
     using (Stream imageStream = new FileStream("test.wmf", FileMode.Open, FileAccess.Read, FileShare.Read)) 
     { 
      PdfWriter.GetInstance(document, outputPdfStream); 
      Image wmf = Image.GetInstance(imageStream); 
      document.Open(); 
      document.Add(wmf); 
      document.Close(); 
     } 
    } 
} 
+1

Ich bekomme eine Ausnahme, wenn ich Ihren Code versuchte, dies funktioniert nicht für mich, ich lese kürzlich, dass eps nicht unterstützt wird, müssen Sie es in WMF konvertieren – Deumber

3

Ich habe kürzlich erfahren, dass Sie Ihr Graphics2D-Objekt direkt an iText senden können, und die resultierenden PDF-Dateien sind genauso gut wie skalierbare Vektorgrafiken. Es klingt so, als würde Ihr Problem gelöst werden.

Document document = new Document(PageSize.LETTER); 
PdfWriter writer = null; 
try { 
    writer = PdfWriter.getInstance(document, new FileOutputStream(your file name)); 
} catch (Exception e) { 
    // do something with exception 
} 

document.open(); 

PdfContentByte cb = writer.getDirectContent(); 
PdfTemplate tp = cb.createTemplate(width, height); 
Graphics2D g2 = tp.createGraphics(width, height, new DefaultFontMapper()); 

// Create your graphics here - draw on the g2 Graphics object 

g2.dispose(); 
cb.addTemplate(tp, 0, 100); // 0, 100 = x,y positioning of graphics in PDF page 
document.close(); 
+0

Das machen wir bereits - mit Graphics2D auf die Seite zu zeichnen. Was wir brauchen, ist ein Bild in einem Vektorformat hinzuzufügen. –

4

ich ein paar Beispiele von der iText gefunden Autor, der die Graphics2D-API und die Apache Batik-Bibliothek verwendet, um die SVG in eine PDF zu zeichnen.

http://itextpdf.com/examples/iia.php?id=269

http://itextpdf.com/examples/iia.php?id=263

Für meine Zwecke, ich brauchte eine Reihe von SVG zu nehmen und dass in einem PDF zu einer bestimmten Größe und Lage zu zeichnen, während der Vektor Natur des Bildes beibehalten (keine Rasterung) .

Ich wollte die SVG-Datei umgehen, die in den SAXSVGDocumentFactory.createSVGDocument() - Funktionen vorherrschend scheint. Ich fand den folgenden Beitrag hilfreich für die Verwendung einer SVG-Textzeichenfolge anstelle einer flachen Datei.

http://batik.2283329.n4.nabble.com/Parse-SVG-from-String-td3539080.html

Sie haben einen String aus Ihrem String erstellen und an die SAXSVGDocumentFactory # create (String, Reader) Methode übergeben. Der URI, den Sie als ersten Parameter als String übergeben, ist der Basisdokument-URI des SVG-Dokuments. Dies sollte nur wichtig sein, wenn Ihr SVG auf externe Dateien verweist.

Mit freundlichen Grüßen,

Daniel

Java Quelle abgeleitet von den iText Beispiele:

// SVG as a text string. 
String svg = "<svg>...</svg>"; 

// Create the PDF document. 
// rootPath is the present working directory path. 
Document document = new Document(); 
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(rootPath + "svg.pdf"))); 
document.open(); 

// Add paragraphs to the document... 
document.add(new Paragraph("Paragraph 1")); 
document.add(new Paragraph(" ")); 

// Boilerplate for drawing the SVG to the PDF. 
String parser = XMLResourceDescriptor.getXMLParserClassName(); 
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser); 
UserAgent userAgent = new UserAgentAdapter(); 
DocumentLoader loader = new DocumentLoader(userAgent); 
BridgeContext ctx = new BridgeContext(userAgent, loader); 
ctx.setDynamicState(BridgeContext.DYNAMIC); 
GVTBuilder builder = new GVTBuilder(); 
PdfContentByte cb = writer.getDirectContent(); 

// Parse the SVG and draw it to the PDF. 
Graphics2D g2d = new PdfGraphics2D(cb, 725, 400); 
SVGDocument chart = factory.createSVGDocument(rootPath, new StringReader(svg)); 
GraphicsNode chartGfx = builder.build(ctx, chart); 
chartGfx.paint(g2d); 
g2d.dispose(); 

// Add paragraphs to the document... 
document.add(new Paragraph("Paragraph 2")); 
document.add(new Paragraph(" ")); 

document.close(); 

Beachten Sie, dass dies ein SVG zum PDF ziehen werden Sie gerade arbeiten. Das SVG wird als schwebende Ebene über dem Text angezeigt. Ich arbeite immer noch daran, sie zu verschieben/zu skalieren und sie mit Text zu verknüpfen, aber hoffentlich liegt das außerhalb des unmittelbaren Bereichs der Frage.

Hoffe, das konnte helfen.

Prost

EDIT: Ich konnte meinen svg als Inline-Objekt implementieren die folgenden verwenden. Die kommentierten Zeilen dienen zum Hinzufügen eines schnellen Rahmens, um die Positionierung zu überprüfen.

SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); 
UserAgent userAgent = new UserAgentAdapter(); 
DocumentLoader loader = new DocumentLoader(userAgent); 
BridgeContext ctx = new BridgeContext(userAgent, loader); 
ctx.setDynamicState(BridgeContext.DYNAMIC); 
GVTBuilder builder = new GVTBuilder(); 
SVGDocument svgDoc = factory.createSVGDocument(rootPath, new StringReader(svg)); 
PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width")), Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height"))); 
Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight()); 
GraphicsNode chartGfx = builder.build(ctx, svgDoc); 
chartGfx.paint(g2d); 
g2d.dispose(); 
Image svgImg = new ImgTemplate(svgTempl); 
svgImg.setAlignment(Image.ALIGN_CENTER); 
//svgImg.setBorder(Image.BOX); 
//svgImg.setBorderColor(new BaseColor(0xff, 0x00, 0x00)); 
//svgImg.setBorderWidth(1); 
document.add(svgImg); 
+1

Hallo, ich versuche, einen Weg zu finden, etwas ähnliches zu tun Rendern Sie SVG-Dateien in ein PDF-Dokument. Welche Version von Itext verwenden Sie? Ich habe festgestellt, dass Konstruktoren privat sind für Klasse com.lowagie.text.pdf.PdfGraphics2D, zumindest in iText 2.1.2, und ich konnte eine solche Klasse in IText 5.5.4 nicht finden. Vielen Dank! - Jose Tepedino vor 6 Minuten –

+0

@JoseTepedino Es tut mir leid, aber ich habe das seit Jahren nicht mehr berührt (seit ich die Antwort geschrieben habe). Ich würde mir vorstellen, dass ich eine Version verwende, die im September 2012 veröffentlicht wurde, also wäre das wahrscheinlich iText 5.3.2, das im August 2012 entsprechend ihren GitHub-Veröffentlichungen veröffentlicht wurde - https://github.com/itext/itextpdf/releases /Tag/5.3.2. Ich hoffe, das hilft. – clayzermk1

+0

danke für deine Nachricht! Ich habe ein wenig Fortschritte gemacht, indem ich eine API-Seite gefunden habe, die besagt, dass die PdfGraphics2D-Klasse aus dem Paket com.itextpdf.awt seit iText 5.0.2 existiert: http://developers.itextpdf.com/reference/com.itextpdf.awt.PdfGraphics2D . Ich habe noch etwas zu tun, aber es ist ein guter Anfang, die richtige Version zu finden. Danke! –

6

das, was ich von dem Pfosten abgeleitet ich hier und die offiziellen Beispiele gefunden:

/** 
* Reads an SVG Image file into an com.itextpdf.text.Image instance to embed it into a PDF 
* @param svgPath SVG filepath 
* @param writer PdfWriter instance 
* @return Instance of com.itextpdf.text.Image holding the SVG file 
* @throws IOException 
* @throws BadElementException 
*/ 
private static Image getSVGImage(String svgPath, PdfWriter writer) throws IOException, BadElementException { 
    SVGDocument svgDoc = new SAXSVGDocumentFactory(null).createSVGDocument(null, new FileReader(svgPath)); 

    // Try to read embedded height and width 
    float svgWidth = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width").replaceAll("[^0-9.,]","")); 
    float svgHeight = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height").replaceAll("[^0-9.,]","")); 

    PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, svgWidth, svgHeight); 
    Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight()); 
    GraphicsNode chartGfx = (new GVTBuilder()).build(new BridgeContext(new UserAgentAdapter()), svgDoc); 
    chartGfx.paint(g2d); 
    g2d.dispose(); 

    return new ImgTemplate(svgTempl); 
} 

Das Bild kann beispielsweise die leicht auf die pdf hinzugefügt werden (in meinem Fall als Signatur).

+1

Klassen im Code oben könnten mit Hilfe der nächsten Maven Abhängigkeit importiert: ' org.apache.xmlgraphics Batik-gvt 1,7 ' –