Search code examples
rotationitext7

Rotate an Itext7 table


I made a table with Itext7 using the Table object and inserted into a Canvas object.

This is the table : enter image description here

Now I would like to rotate the table (but not the page) to achieve this:

enter image description here

How can I rotate the Table or Canvas 270 degrees.

This is the code I use to generate the table (It is part of a larger project, however this is the method that generates the table) :

num_row = num_row + 1; // Indica il numero di riga della tabella        
       PdfDocument_Configurazione_Text cfgText;
       if (intestazione) {
           cfgText = cfg.getCfg_intestazione();
       } else {
           cfgText = cfg.getCfg_riga();
       }
       if (cfgText == null) {
           throw new Exception("Configurazione testo " + (intestazione ? "intestazione" : "riga") + " null");
       }
       campi = campi == null ? new ArrayList<>() : campi;
       Paragraph p;
       PdfFont font = PdfFontFactory.createFont(cfgText.getTipo_font_testo());

       table = new Table(cfg.getTabella_num_col());

       for (int i = 1; i <= cfg.getTabella_num_col(); i++) {
          
           Cell cell = new Cell();
           p = new Paragraph("");
           String str = campi.size() < i ? " " : campi.get(i - 1);            
           p.add(str);
           p.setFont(font);
           p.setFontSize(cfgText.getDim_font_testo());

           if (cfgText.isTesto_bold()) {
               p.setBold();
           }
           if (cfgText.isTesto_italic()) {
               p.setItalic();
           }
           if (cfgText.isTesto_sottolineato()) {
               p.setUnderline();
           }

           if (intestazione) {
               if (cfg.getCol_int_border().containsKey(num_row)) { // Se nella mappa è presente il numero di riga per settaggio bordo
                   for (List border : UtilConvertListMap.convertListBorder(cfg.getCol_int_border().get(num_row))) { // Ciclo all'interno di una lista alla ricerca del bordo               
                       if (border.get(0).equals(String.valueOf(i - 1))) { // Se nella lista è presente un numero di colonna uguale a quello che sta disegnando il programma                        
                           switch (border.get(1).toString().trim()) { // setto i relativi bordi per singola cella 
                               case "BUTTOM":
                                   if (border.get(2).toString().trim().equals("false")) {
                                       cell.setBorderBottom(Border.NO_BORDER);
                                   }
                               case "TOP":
                                   if (border.get(2).toString().trim().equals("false")) {
                                       cell.setBorderTop(Border.NO_BORDER);
                                   }
                               case "LEFT":
                                   if (border.get(2).toString().trim().equals("false")) {
                                       cell.setBorderLeft(Border.NO_BORDER);
                                   }
                               case "RIGHT":
                                   if (border.get(2).toString().trim().equals("false")) {
                                       cell.setBorderRight(Border.NO_BORDER);
                                   }
                           }
                       }
                   }
               }
           } else { // per le righe dati manipolo solo bordi colonne le righe saranno tutte uguali
               if (cfg.getCol_dati_border((i - 1), "BUTTOM") == false) {
                   cell.setBorderBottom(Border.NO_BORDER);
               }
               if (cfg.getCol_dati_border((i - 1), "TOP") == false) {
                   cell.setBorderTop(Border.NO_BORDER);
               }
               if (cfg.getCol_dati_border((i - 1), "LEFT") == false) {
                   cell.setBorderLeft(Border.NO_BORDER);
               }
               if (cfg.getCol_dati_border((i - 1), "RIGHT") == false) {
                   cell.setBorderRight(Border.NO_BORDER);
               }
           }

           if (intestazione) {
               cell.setTextAlignment(TextAlignment.valueOf(cfg.getCol_int_allign(num_row, (i - 1)).toString()));
           } else {
               cell.setTextAlignment(cfg.getCol_dati_allign(i - 1, intestazione));
           }

           if (intestazione) {
               p.setWidth((float) cfg.getCol_int_width(num_row, (i - 1)));
           } else {
               p.setWidth((float) cfg.getCol_dati_width(i - 1));
           }

           cell.setWidth(p.getWidth());
           cell.add(p);

           p.setProperty(Property.OVERFLOW_X, OverflowPropertyValue.valueOf("FIT"));

           table.setHeight((float) cfg.getRig_heigth());
           if (intestazione) {

               table.addCell(cell);
           } else {

               table.addCell(cell);
           }
       }

       MinMaxWidth minMaxWidth = ((TableRenderer) table.createRendererSubTree().setParent(canvas.getRenderer())).getMinMaxWidth();
       float minWidth = minMaxWidth.getMinWidth();
       float maxWidth = minMaxWidth.getMaxWidth();
       rectangle.setWidth(maxWidth);

       canvas.add(table);
       table.flushContent();

This piece of code generates the canvas :

cfg = cfgn;
pages = pdfDocument.getPage(numero_pagina);
pdfCanvas = new PdfCanvas(pages);
rectangle = new Rectangle(cfg.getPos_x_tabella(), cfg.getPos_y_tabella(), 100, 200);
canvas = new Canvas(pdfCanvas, rectangle);
canvas.setBorder(Border.NO_BORDER);

Solution

  • The first idea would be to set the RotationAngle property of the table

    table.setRotationAngle(-Math.PI/2);
    canvas.add(table);
    

    (RotateSomeContent test testForDropVidProperty)

    Unfortunately this property currently (7.2.4-SNAPSHOT) seems not to be supported by the Table class.

    What you can always do, though, is rotate the PdfCanvas on which the table is drawn, e.g. like this:

    PdfCanvas pdfCanvas = new PdfCanvas(page);
    
    // Rectangle for the table in upright page coordinates
    Rectangle rectangle = new Rectangle(100, 100, 400, 700);
    // show rectangle area
    pdfCanvas.saveState();
    pdfCanvas.setFillColor(new DeviceRgb(255, 255, 128));
    pdfCanvas.rectangle(rectangle);
    pdfCanvas.fill();
    pdfCanvas.restoreState();
    
    // apply a translation and a rotation so that the table will be rotated
    // and the origin will be in the lower left corner of the rectangle
    AffineTransform transform = AffineTransform.getTranslateInstance(rectangle.getLeft(), rectangle.getTop());
    transform.rotate(-Math.PI/2);
    pdfCanvas.concatMatrix(transform);
    
    Rectangle rotatedRectangle = new Rectangle(0, 0, rectangle.getHeight(), rectangle.getWidth());
    
    try (   Canvas canvas = new Canvas(pdfCanvas, rotatedRectangle)    ) {
        Table table = new Table(5);
        table.addHeaderCell("DEBITO");
        table.addHeaderCell("INTERESSI DI MORA");
        table.addHeaderCell("ONERI DI RISCOSSIONE");
        table.addHeaderCell("SPESE DI NOTIFICA\nE ACCESSORI");
        table.addHeaderCell("SPESE ESECUTIVE");
        table.addCell("3.304,24");
        table.addCell("0,00");
        table.addCell("183,55");
        table.addCell("8,75");
        table.addCell("0,00");
    
        canvas.add(table);
    }
    

    (RotateSomeContent test testForDropVid)

    The result looks like this:

    screen shot

    (I marked the rectangle area in yellow for illustration only.)