Watermark in itextsharp is not displaying properly

2019-06-09 21:49发布

问题:

I'm using iTextSharp to populate the data to PDF Templates, which is created in OpenOffice. it populating fine, I'm getting proper PDF, Watermark is not displaying properly.

below is my code:

public void addWaterMark(PdfStamper stamper, int pageNumber, Watermark watermark)
    {
        List<WatermarkField> watermarkFields = watermark.getWatermarkFieldAsReference();
        for (WatermarkField watermarkField : watermarkFields) {
            // setting font and font size for the watermark text
            Font FONT = new Font(FontFamily.HELVETICA, watermarkField.getFontSize(), Font.BOLD, new GrayColor(0.75f));
            // setting alignment for the watermark
            ColumnText.showTextAligned(stamper.getUnderContent(pageNumber), Element.ALIGN_CENTER, new Phrase(watermarkField.getText(), FONT), watermarkField.getXDirection(), watermarkField.getYDirection(), watermarkField.getRotation());
        }

    } 

When i putting in background text-boxes are hiding the watermark.
When i putting in foreground watermark is hiding the text.
Both screen shorts are attaching below.

Please Suggest me the solution. Thanks.

回答1:

In this answer there already are some ideas on how to add watermarks (in the under content, in the over content, both in the under content and in the over content before bitmaps.,,,).

The missing use case, a transparent mark in the over content, can be generated like this:

void addSimpleTransparentPatternToOverContent(File source, File target) throws IOException, DocumentException
{
    PdfReader reader = new PdfReader(source.getPath());
    OutputStream os = new FileOutputStream(target);
    PdfStamper stamper = new PdfStamper(reader, os);

    PdfPatternPainter painter = stamper.getOverContent(1).createPattern(200, 150);
    painter.setColorFill(BaseColor.GREEN);
    painter.beginText();
    painter.setTextMatrix(AffineTransform.getTranslateInstance(0, 50));
    painter.setFontAndSize(BaseFont.createFont(), 100);
    painter.showText("Test");
    painter.endText();

    PdfGState state = new PdfGState();
    state.setFillOpacity(0.5f);

    for (int i = reader.getNumberOfPages(); i > 0; i--)
    {
        PdfContentByte overContent = stamper.getOverContent(i);

        overContent.setGState(state);
        overContent.setColorFill(new PatternColor(painter));
        overContent.rectangle(200, 300, 200, 150);
        overContent.fill();
    }

    stamper.close();
    os.close();
}

In the spirit of that other answer the mark is generated using a pattern to prevent the watermark from appearing in copy&paste outputs.

You can change the transparency / opacity by selecting a different value in state.setFillOpacity(0.5f).



回答2:

This is the actual code.

public void addWaterMark(PdfStamper stamper, int pageNumber, Watermark watermark){
    List<WatermarkField> watermarkFields = watermark.getWatermarkFieldAsReference();
    PdfReader reader = stamper.getReader();
    Rectangle pageSize = reader.getPageSize(1);
    BaseFont font = BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);

    PdfPatternPainter painter = stamper.getOverContent(1).createPattern(pageSize.getWidth(), pageSize.getHeight());
    painter.setColorStroke(new BaseColor(192, 192, 192));
    painter.setLineDash(0.4f, 0.4f, 0.2f);
    painter.beginText();
    painter.setTextMatrix(AffineTransform.getTranslateInstance(0, 50));
    for (WatermarkField watermarkField : watermarkFields) {
        painter.setFontAndSize(font, watermarkField.getFontSize());
        painter.showTextAlignedKerned(Element.ALIGN_MIDDLE, watermarkField.getText(), watermarkField.getXDirection(), watermarkField.getYDirection(),
        watermarkField.getRotation());
    }
    painter.endText();
    PdfGState state = new PdfGState();
    state.setFillOpacity(0.2f);
    PdfContentByte overContent = stamper.getOverContent(pageNumber);
    overContent.setGState(state);
    overContent.setColorFill(new PatternColor(painter));
    overContent.rectangle(pageSize.getLeft(), pageSize.getBottom(), pageSize.getWidth(), pageSize.getHeight());
    overContent.fill();
}