Adding shadow effect on iText elements

2019-07-10 04:47发布

问题:

I have some problem with iText in Java. I need to produce a cell or rectangle with shadow just like in this example:

4 and 60 are in some kind of cell or rectangle with shadow. I don't know how to do it. Any help ?

回答1:

The easiest way probably is to use a Chunk with a generic tag and a PdfPageEvent. This way you'll get an event callback when the Chunk is positioned on the page. The callback will give you the coordinates (rectangle) of the Chunk, allowing you to paint a border and a shadow at the correct location.

An example of such an event handler to paint a black border and a gray shadow:

class ShadowEvent extends PdfPageEventHelper {
    @Override
    public void onGenericTag(PdfWriter writer, Document document,
      Rectangle rect, String text) {
        PdfContentByte canvas = writer.getDirectContent();
        // Paddings for the border
        int paddingHorizontal = 20;
        int paddingVertical = 5;
        // Width of the shadow
        int shadowwidth = 5;
        // Calculate border location and size
        float left = rect.getLeft() - paddingHorizontal;
        float bottom = rect.getBottom() - paddingVertical;
        float width = rect.getWidth() + 2*paddingHorizontal;
        float height = rect.getHeight() + 2*paddingVertical;
        canvas.saveState();
        canvas.setColorFill(BaseColor.GRAY);
        // Draw the shadow at the bottom
        canvas.rectangle(left + shadowwidth, bottom - shadowwidth, width, shadowwidth);
        canvas.fill();
        // Draw the shadow at the right
        canvas.rectangle(left + width, bottom - shadowwidth, shadowwidth, height);
        canvas.fill();
        canvas.setColorStroke(BaseColor.BLACK);
        // Draw the border
        canvas.rectangle(left, bottom, width, height);
        canvas.stroke();
        canvas.restoreState();
    }
}

This shows how to use the generic tag:

Document doc = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(doc, outfile);
pdfWriter.setPageEvent(new ShadowEvent());
doc.open();
Chunk c = new Chunk("60");
c.setGenericTag("shadow");
doc.add(c);
doc.close();

(Note that the text parameter of the onGenericTag method will contain the String that was set to the Chunk with setGenericTag. This is "shadow" in the example above. It allows to differentiate between different tags. Since we're just using 1 tag here, I'm not using the text parameter.)

The result of the example looks like this: