Domanda

Usiamo iText per generare PDF da Java (basato in parte sui consigli di questo sito). Tuttavia, l'incorporamento di una copia del nostro logo in un formato di immagine come GIF comporta un aspetto un po 'strano quando le persone ingrandiscono e rimpiccioliscono.

Idealmente vorremmo incorporare l'immagine in un formato vettoriale, come EPS, SVG o solo un modello PDF. Il sito web afferma che il supporto EPS è stato abbandonato, che l'incorporamento di un PDF o PS in un PDF può causare errori e non menziona nemmeno SVG.

Il nostro codice utilizza direttamente l'API Graphics2D anziché iText, ma saremmo disposti a uscire dalla modalità AWT e utilizzare iText stesso se ottenesse il risultato. Come si può fare?

È stato utile?

Soluzione

Secondo la documentazione iText supporta i seguenti formati di immagine: JPEG , GIF, PNG, TIFF, BMP, WMF ed EPS. Non so se questo potrebbe essere di aiuto, ma ho usato con successo iTextSharp per incorporare il vettore WMF immagine in un file pdf:

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();
        }
    }
}

Altri suggerimenti

Questo è ciò che ho tratto dai post che ho trovato qui e dagli esempi ufficiali:

/**
 * 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);
}

L'istanza di Image può essere facilmente aggiunta al pdf (nel mio caso come firma).

Ho trovato un paio di esempi dell'autore iText che usano l'API Graphics2D e la libreria Apache Batik per disegnare l'SVG in un PDF.

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

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

Per i miei scopi, ho dovuto prendere una stringa di SVG e disegnarla in un PDF in una determinata dimensione e posizione mantenendo la natura vettoriale dell'immagine (nessuna rasterizzazione).

Volevo bypassare il file SVG che sembra prevalente nelle funzioni SAXSVGDocumentFactory.createSVGDocument (). Ho trovato utile il seguente post per l'utilizzo di una stringa di testo SVG anziché di un file flat.

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

  

Devi creare un StringReader dal tuo String e passarlo al metodo SAXSVGDocumentFactory # createDocument (String, Reader). L'URI che passi come primo parametro come stringa sarà l'URI del documento di base del documento SVG. Questo dovrebbe essere importante solo se il tuo SVG fa riferimento a file esterni.

     

Cordiali saluti,

     

Daniel

Java Source derivato dagli esempi iText:

// 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();

Nota che questo disegnerà un SVG sul PDF su cui stai lavorando. L'SVG appare come un livello mobile sopra il testo. Sto ancora lavorando per spostarlo / ridimensionarlo e mantenerlo in linea con il testo, ma spero che sia al di fuori dell'ambito immediato della domanda.

Spero che questo sia stato di aiuto.

Saluti

EDIT: sono stato in grado di implementare il mio svg come oggetto inline usando quanto segue. Le righe commentate servono per aggiungere un bordo rapido per verificare il posizionamento.

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);

Di recente ho appreso che è possibile inviare l'oggetto Graphics2D direttamente a iText e che i file PDF risultanti sono altrettanto validi della grafica vettoriale scalabile. Dal tuo post, sembra che questo potrebbe risolvere il tuo problema.

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();

Questo ha funzionato per me usando itext 7.1.3 per il rendering dell'immagine SVG di SVGConverter.

PdfWriter writer = new PdfWriter(new FileOutputStream("/home/users/Documents/pdf/new.pdf"));

        PdfDocument pdfDoc = new PdfDocument(writer);

        Document doc = new Document(pdfDoc);

        URL svgUrl = new File(svg).toURI().toURL();

        doc.add(new Paragraph("new pikachu"));                      

        Image image = SvgConverter.convertToImage(svgUrl.openStream(), pdfDoc);                 
        doc.add(image);

        doc.close();

La nuova versione di iText supporta anche i file SVG. Si prega di fare riferimento a questa pagina.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top