2015-05-06 5 views
3

Im работает над созданием PDF-файлов с XHTML с использованием библиотеки летающих тарелок (старый, но с открытым исходным кодом). Я получил эту работу, но я также хочу добавить SVG-изображения. Ive начал работать над интеграцией batik, чтобы попытаться заставить его работать, но у меня проблемы. Изображения SVG не рисуются. XHTML по-прежнему отображается, но, похоже, он не показывает SVG. Я получил SVG для рендеринга в отдельных PDF-файлах, но никогда не с результатами летающих тарелок. Я добавил обычный ReplacedElementFactory (который также работает с обычными изображениями, но havent включил этот код). Только соответствующий метод (который действительно дозвонились и все) выглядит следующим образом:Как добавить изображение SVG в PDF, построенное с помощью библиотеки HTML и Flying Saucer (и Batik)?

@Override 
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) { 
    Element element = blockBox.getElement(); 
    if (element == null) { 
     return null; 
    } 
    String nodeName = element.getNodeName(); 
    if ("img".equals(nodeName)) { 
     SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); 

     SVGDocument svgImage = null; 
     try { 
      svgImage = factory.createSVGDocument(new File("logo.svg").toURL() 
        .toString()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     Element svgElement = svgImage.getDocumentElement(); 
     Document htmlDoc = element.getOwnerDocument(); 
     Node importedNode = htmlDoc.importNode(svgElement, true); 
     element.appendChild(importedNode); 
     return new SVGReplacedElement(svgImage, cssWidth, cssHeight); 
    } 
    return this.superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight); 
} 

После этого я стараюсь рисовать его:

import java.awt.Graphics2D; 
import java.awt.Point; 

import org.apache.batik.bridge.BridgeContext; 
import org.apache.batik.bridge.DocumentLoader; 
import org.apache.batik.bridge.GVTBuilder; 
import org.apache.batik.bridge.UserAgent; 
import org.apache.batik.bridge.UserAgentAdapter; 
import org.apache.batik.gvt.GraphicsNode; 
import org.w3c.dom.svg.SVGDocument; 
import org.xhtmlrenderer.css.style.CalculatedStyle; 
import org.xhtmlrenderer.layout.LayoutContext; 
import org.xhtmlrenderer.pdf.ITextOutputDevice; 
import org.xhtmlrenderer.pdf.ITextReplacedElement; 
import org.xhtmlrenderer.render.BlockBox; 
import org.xhtmlrenderer.render.PageBox; 
import org.xhtmlrenderer.render.RenderingContext; 

import com.lowagie.text.pdf.PdfContentByte; 
import com.lowagie.text.pdf.PdfTemplate; 

public class SVGReplacedElement implements ITextReplacedElement { 

private Point location = new Point(0, 0); 
private SVGDocument svg; 
private int cssWidth; 
private int cssHeight; 

public SVGReplacedElement(SVGDocument importedNode, int cssWidth, int cssHeight) { 
    this.cssWidth = cssWidth; 
    this.cssHeight = cssHeight; 
    this.svg = importedNode; 
} 

@Override 
Methods.... 

@Override 
public void paint(RenderingContext renderingContext, ITextOutputDevice outputDevice, 
     BlockBox blockBox) { 

    UserAgent userAgent = new UserAgentAdapter(); 
    DocumentLoader loader = new DocumentLoader(userAgent); 
    BridgeContext ctx = new BridgeContext(userAgent, loader); 
    ctx.setDynamicState(BridgeContext.DYNAMIC); 
    GVTBuilder builder = new GVTBuilder(); 

    blockBox.paintDebugOutline(renderingContext); 

    PdfContentByte cb = outputDevice.getWriter().getDirectContent(); 

    float width = cssWidth/outputDevice.getDotsPerPoint(); 
    float height = cssHeight/outputDevice.getDotsPerPoint(); 

    PdfTemplate map = cb.createTemplate(width, height); 

    Graphics2D g2d = map.createGraphics(width, height); 

    GraphicsNode mapGraphics = builder.build(ctx, svg); 
    mapGraphics.paint(g2d); 
    g2d.dispose(); 

    PageBox page = renderingContext.getPage(); 
    float x = blockBox.getAbsX() + page.getMarginBorderPadding(renderingContext, CalculatedStyle.LEFT); 
    float y = (page.getBottom() - (blockBox.getAbsY() + cssHeight)) + page.getMarginBorderPadding(
      renderingContext, CalculatedStyle.BOTTOM); 

    cb.addTemplate(map, x, y); 
} 
} 

Интересно, что blockBox.paintDebugOutline(renderingContext); делает рисовать контуры, где изображения должны быть. Отладка Eclipse также показала, что правильные файлы связаны с элементами IMG. CSS-выглядит следующим образом:

.header { 
position: absolute; 
display: inline-block; 
right: 0; 
top: 0; 
width: 150px; 
height: 54px; 
} 

Я также попытался с display:block;. Примеры верстку я пробовал:

<img class='header' src='icon.svg' alt='Logo'/> 
<svg class='header' type='image/svg+xml' data='icon.svg' /> 
<object class='header' type='image/svg+xml' data='icon.svg' /> 

Большое спасибо за ваше внимание и обратной связи (и, возможно, ответы)

EDIT: Первоначально проблемы были немного разные, но я решил, что. SVGImage не может быть добавлен к фактическому документу. Теперь он просто не рисует. Я добавил CSS для отображения: block и т. Д., Как указано в руководствах.

EDIT: Очиститель Код

EDIT: Добавлено больше на то, что я пытался

ответ

1

Я не знаю, почему именно, но заменив код в SVGReplacedElement.paint (...) зафиксировал его.

Новый код:

@Override 
public void paint(RenderingContext renderingContext, ITextOutputDevice outputDevice, 
     BlockBox blockBox) { 
    PdfContentByte cb = outputDevice.getWriter().getDirectContent(); 
    float width = (float) (cssWidth/outputDevice.getDotsPerPoint()); 
    float height = (float) (cssHeight/outputDevice.getDotsPerPoint()); 

    PdfTemplate template = cb.createTemplate(width, height); 
    Graphics2D g2d = template.createGraphics(width, height); 
    PrintTranscoder prm = new PrintTranscoder(); 
    TranscoderInput ti = new TranscoderInput(svg); 
    prm.transcode(ti, null); 
    PageFormat pg = new PageFormat(); 
    Paper pp = new Paper(); 
    pp.setSize(width, height); 
    pp.setImageableArea(0, 0, width, height); 
    pg.setPaper(pp); 
    prm.print(g2d, pg, 0); 
    g2d.dispose(); 

    PageBox page = renderingContext.getPage(); 
    float x = blockBox.getAbsX() + page.getMarginBorderPadding(renderingContext, CalculatedStyle.LEFT); 
    float y = (page.getBottom() - (blockBox.getAbsY() + cssHeight)) + page.getMarginBorderPadding(
      renderingContext, CalculatedStyle.BOTTOM); 
    x /= outputDevice.getDotsPerPoint(); 
    y /= outputDevice.getDotsPerPoint(); 

    cb.addTemplate(template, x, y); 
} 

получил его здесь: http://www.samuelrossille.com/posts/2013-08-13-render-html-with-svg-to-pdf-with-flying-saucer.html

Может быть что-то делать с новым UserAgent и DocumentLoader и т.д., я создал, которые не были связаны с исходным документом. В любом случае это работает сейчас. Надеюсь, это поможет кому-то в будущем. Если люди хотят комментировать или возвращать вопрос о том, почему это работает сейчас, это может помочь другому прочтению этого позже.

+2

Извините, если вы читаете этот ответ и не можете ничего с ним поделать. Я принял свой собственный дерьмовый ответ, поэтому другие не тратят время на слишком много внимания. Пожалуйста, позвоните мне, если у вас есть вопросы, и вы хотите получить дополнительную информацию. – Daxterwous

+0

Большое спасибо за обмен - указал мне в правильном направлении! –

+0

Я знаю, что это не самый структурированный ответ, но рад, что это немного помогло. – Daxterwous

Смежные вопросы