Drawing vector images on PDF with PDFBox

前端 未结 3 826
夕颜
夕颜 2021-02-13 20:41

I would like to draw a vector image on a PDF with Apache PDFBox.

This is the code I use to draw regular images

PDPage page = (PDPage) document.getDocumen         


        
3条回答
  •  没有蜡笔的小新
    2021-02-13 20:52

    See the library pdfbox-graphics2d, touted in this Jira.

    You can draw the SVG, via Batik or Salamander or whatever, onto the class PdfBoxGraphics2D, which is parallel to iText's template.createGraphics(). See the GitHub page for samples.

    PDDocument document = ...;
    PDPage page = ...; // page whereon to draw
    
    String svgXML = "...";
    double leftX = ...;
    double bottomY = ...; // PDFBox coordinates are oriented bottom-up!
    
    // I set these to the SVG size, which I calculated via Salamander.
    // Maybe it doesn't matter, as long as the SVG fits on the graphic.
    float graphicsWidth = ...;
    float graphicsHeight = ...;
    
    // Draw the SVG onto temporary graphics.
    var graphics = new PdfBoxGraphics2D(document, graphicsWidth, graphicsHeight);
    try {
        int x = 0;
        int y = 0;
        drawSVG(svg, graphics, x, y); // with Batik, Salamander, or whatever you like
    } finally {
        graphics.dispose();
    }
    
    // Graphics are not visible till a PDFormXObject is added.
    var xform = graphics.getXFormObject();
    
    try (var contentWriter = new PDPageContentStream(document, page, AppendMode.APPEND, false)) { // false = don't compress
        // XForm objects have to be placed via transform,
        // since they cannot be placed via coordinates like images.
        var transform = AffineTransform.getTranslateInstance(leftX, bottomY);
        xform.setMatrix(transform);
    
        // Now the graphics become visible.
        contentWriter.drawForm(xform);
    }
    

    And ... in case you want also to scale the SVG graphics to 25% size:

    // Way 1: Scale the SVG beforehand
    svgXML = String.format("%s", .25, svgXML);
    
    // Way 2: Scale in the transform (before calling xform.setMatrix())
    transform.concatenate(AffineTransform.getScaleInstance(.25, .25));
    

提交回复
热议问题