How do I draw graphics to PDF using iText?

13,959

Solution 1

Does Document doc = new Document(PageSize.A4); make any difference?

I don't know if you need to add a Paragraph like this:

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

Also we use doc.add(ImgRaw); to add images.

Solution 2

I am not an expert in IText, but last week I tryed to draw some circles with it. So this is what I have noticed during my tests:

If you draw graphics, you must (or lets say I must when I tryed it) "wrap" the graphics commands in a section starting with saveState() and ending with restoreState(), es well as I needed to invoke fillStroke() -- if I do not invoke fillStroke() then nothing was drawn.

Example

private void circle(float x, float y, PdfWriter writer) {
    PdfContentByte canvas = writer.getDirectContent();

    canvas.saveState();
    canvas.setColorStroke(GrayColor.BLACK);
    canvas.setColorFill(GrayColor.BLACK);
    canvas.circle(x, y, 2);
    canvas.fillStroke();

    canvas.restoreState();
}

@Test
public void testPossition() throws DocumentException, IOException {
    OutputStream outputStream = FileUtil.openOutputStream("testPosition.pdf");
    //this is my personal file util, but it does not anything more
    //then creating a file and opening the file stream.

    Document document = new Document(PageSize.A4, 50, 50, 50, 50);
    PdfWriter writer = PdfWriter.getInstance(document, outputStream);
    document.open();

    markPosition(100, 100, writer);
    document.add(new Paragraph("Total: 595 x 842 -- 72pt (1 inch)"));

    document.close();
    outputStream.flush();
    outputStream.close();
}

private void markPosition(float x, float y, PdfWriter writer)
        throws DocumentException, IOException {
    placeChunck("x: " + x + " y: " + y, x, y, writer);
    circle(x, y, writer);
}

 private void placeChunck(String text, float x, float y, PdfWriter writer)
       throws DocumentException, IOException {
    PdfContentByte canvas = writer.getDirectContent();
    BaseFont font = BaseFont.createFont(BaseFont.HELVETICA,
                  BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
    canvas.saveState();
    canvas.beginText();
    canvas.moveText(x, y);
    canvas.setFontAndSize(font, 9);
    canvas.showText(text);
    canvas.endText();
    canvas.restoreState();
}

But PdfContentByte (canvas) has much more functions, for example rectangle.

Solution 3

Without going too far into it, I think your general approach is fine. I think what might be happening here is that the Graphics2D origin is different from the PDF origin, so maybe you need to change the call to drawString() so it uses 0,0 as the location??

Solution 4

I think the problem is that directcontent writes directly to the page object. This way you can add backgrounds or backdrop images. Try adding a new page (doc.newPage()) before writing to the directcontent.

Solution 5

Have you tried drawing operations on the g2d object that just use shapes instead of text? That would eliminate the possibility of something odd going on with font selection or something like that.

iText In Action Chapter 12 has exactly what you are looking for - it really is worth picking up. Preview of Chapter 12

Share:
13,959
jimdrang
Author by

jimdrang

Updated on June 09, 2022

Comments

  • jimdrang
    jimdrang about 2 years

    I am trying to complete an example that draws graphics and writes them to PDF, but I keep getting errors that the PDF has no pages. if I add something simple with document.add() after opening it works fine, I just never see the graphics. Here is my code:

    Document document = new Document();
    PdfWriter writer = new PdfWriter();
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition",
        " attachment; filename=\"Design.pdf\"");
    
    writer = PdfWriter.getInstance(document, response.getOutputStream());
    
    document.open();    
    PdfContentByte cb = writer.getDirectContent();
    Graphics2D graphics2D = cb.createGraphics(36, 54);
    graphics2D.drawString("Hello World", 36, 54);
    graphics2D.dispose();   
    document.close();
    

    Do I have to do something else to add the graphic to the document or is my syntax incorrect?