javaitextdata-hiding

Use different Table Header on first page


I'm using iText and create a dynamic table which has a a reoccurring header in the method createTabularHeader:

PdfPTable table = new PdfPTable(6);
// fill it with some basic information
table.setHeaderRows(1);

Yet on the first page I would like to display different information. (but the table structure/size remains the same)

Due to the dynamic content which is obtained in a different method I can't say when a new page starts.

I tried with the most primitive variant - just adding a white rectangle over the text and insert the different text. As it's just on the first page all I have to do is creating that rectangle between both methods. But the white rectangle doesn't have any opacity and can' cover anything.

Yet by trying around I found the method writer.getDirectContent().setColorStroke(BaseColor.WHITE); which set the text to white. Later I just set the BaseColor of my cells manually to black. But the even though the new text is applied after the calling of my createTabularHeader-method its layer is under the layer of the original text and the letters are covering the new text partly.

Using the answer to How to insert invisible text into a PDF? brought me to the idea of using myPdfContentByte.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE); was not so helpful as it resets only on the 2nd page regardless what I do and the regular text on the first page stays invisible.

I'm unable to find a proper solution... How can the table-header be modified only on the first page?


Solution

  • The solution is not really nice, but works... and as some sort of bonus I want to add how you can modify the indentions on the first page.

    public void createPdf() {
        document = new Document();
        try {
            PdfWriter writer = PDFHead.getWriter(document);
            //If it's a letter we have a different indention on the top
            if (letterPDF) {
                document.setMargins(36, 36, 100, 36);
            } else {
                document.setMargins(36, 36, 36, 36);
            }
            document.open();
            document.add(createTabularContent());
            document.close();
    
        } catch (DocumentException | FileNotFoundException ex) {
            try {
                document = new Document();
                PdfWriter.getInstance(document, new FileOutputStream(FILENAME));
                document.open();
                document.add(new Phrase(ex.getLocalizedMessage()));
                document.close();
                Logger.getLogger(Etikette.class.getName()).log(Level.SEVERE, null, ex);
            } catch (FileNotFoundException | DocumentException ex1) {
                Logger.getLogger(Etikette.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
    }
    

    The PDFHead is used to create a regular header (the one which appears on every page, not only on pages with the table):

    public static PdfWriter getWriter(Document document) throws FileNotFoundException, DocumentException {
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        HeaderFooter event = new HeaderFooter("Ing. Mario J. Schwaiger", type + " " + DDMMYYYY.format(new java.util.Date()), 835, isLetterPDF(), customerNumber);
        writer.setBoxSize("art", new Rectangle(36, 54, 559, 788));
        writer.setPageEvent(event);
        return writer;
    }
    

    And in that HeaderFooter-Event I use the fact the function is called after the PDF is basically created (for the page number for instance):

    @Override
        public void onEndPage(PdfWriter writer, Document document) {
            if (isLetter) {
                //That's only for the first page, apparently 1 is too late
                //I'm open for improvements but that works fine for me
                if (writer.getPageNumber() == 0) {
    
                //If it's a letter we use the different margins
                document.setMargins(36, 36, 100, 36);
                }
                if (writer.getPageNumber() == 1) {
                PdfContentByte canvas = writer.getDirectContent();
    
                float llx = 460;
                float lly = 742;
    
                float urx = 36;
                float ury = 607;
    
                //As I add the rectangle in the event here it's 
                //drawn over the table-header. Seems the tableheader
                //is rendered afterwards
                Rectangle rect1 = new Rectangle(llx, lly, urx, ury);
                rect1.setBackgroundColor(BaseColor.WHITE);
                rect1.setBorder(Rectangle.NO_BORDER);
                rect1.setBorderWidth(1);
                canvas.rectangle(rect1);
    
                ColumnText ct = new ColumnText(canvas);
                ct.setSimpleColumn(rect1);
                PdfPTable minitable = new PdfPTable(1);
                PdfPCell cell = PDFKopf.getKundenCol(PDFHeader.getCustomer(customerNumber));
                cell.setBorder(Rectangle.NO_BORDER);
                minitable.addCell(cell);
    
                //A single cell is not accepted as an "Element"
                //But a table including only a single cell is
                ct.addElement(minitable);
                try {
                    ct.go();
                } catch (DocumentException ex) {
                    Logger.getLogger(HeaderFooter.class.getName()).log(Level.SEVERE, null, ex);
                }
    
            //In any other case we reset the margins back to normal
            //This could be solved in a more intelligent way, feel free
            } else {
                document.setMargins(36, 36, 36, 36);
            }
        }
    
        //The regular header of any page...
        PdfPTable table = new PdfPTable(4);
    
        try {
            table.setWidths(new int[]{16, 16, 16, 2});
            table.setWidthPercentage(100);
    
            table.setTotalWidth(527);
            table.setLockedWidth(true);
    
            table.getDefaultCell().setFixedHeight(20);
            table.getDefaultCell().setBorder(Rectangle.BOTTOM);
            table.addCell(header);
            PdfPCell cell;
    
            cell = new PdfPCell(new Phrase(mittelteil));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setBorder(Rectangle.BOTTOM);
            table.addCell(cell);
    
            table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
            table.addCell(String.format("Page %d of ", writer.getPageNumber()));
            cell = new PdfPCell(Image.getInstance(total));
            cell.setBorder(Rectangle.BOTTOM);
            table.addCell(cell);
            table.writeSelectedRows(0, -1, 34, y, writer.getDirectContent());
        } catch (DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }