Stretching internal content inside the cell iText 7 PDF

前端 未结 1 1248
误落风尘
误落风尘 2021-01-25 13:38

I still fight with iText, and it looks like he\'s running over me. I already asked the question here, but most likely the question was so abstract that I could not get answers.

相关标签:
1条回答
  • 2021-01-25 14:07

    I managed to solve the problem myself. Now every inner table has no color, and I'm not trying to stretch it. This is most likely the most important. I paid much attention to cells and decided that I need to work with them. Why? Because each cell has a height equal to the maximum height of some cell in the row. And this is what I need

    So, I want each cell to have a color, have margins, have rounded corners, and contain the content in the form of an internal table. In addition, each cell will have the same height automatically - what I was trying to achieve.

    First, we need to create a custom Renderer for cells, that allows you to draw cells with margins(no by default) and with rounded corners. This is my Renderer for cells:

    public class RoundCornerСellRenderer : CellRenderer
    {
        public RoundCornerСellRenderer(Cell modelElement) : base(modelElement)
        {
        }
    
        public override IRenderer GetNextRenderer() =>
            new RoundCornerСellRenderer((Cell)GetModelElement());
    
        protected override Rectangle ApplyMargins(Rectangle rect, UnitValue[] margins, bool reverse)
        {
            var values = margins.Select(x => x.GetValue()).ToList();
            return rect.ApplyMargins(values[0], values[1], values[2], values[3], reverse);
        }
    
        public override void DrawBackground(DrawContext drawContext)
        {
            // Apply the margins
            var area = ApplyMargins(GetOccupiedAreaBBox(), GetMargins(), false);
    
            // Get background color
            var background = GetProperty<Background>(Property.BACKGROUND);
            var color = background.GetColor();
    
            // Draw the rectangle with rounded corners
            var canvas = drawContext.GetCanvas();
            canvas.SaveState();
            canvas.RoundRectangle(area.GetX(), area.GetY(), area.GetWidth(), area.GetHeight(), 5);
            canvas.SetFillColor(color);
            canvas.Fill();
            canvas.RestoreState();  
        } 
    }
    

    That's all! Now all you have to do is create cells, add them margins and this custom renderer:

    private Cell CreateNotesCell(IList<ProductAttribute> notes)
    {
        // Create a notes cell
        var notesCell = new Cell()
            .SetBackgroundColor(RegularBackgroundColor)
            .SetPadding(10)
            .SetMargins(20, 10, 20, 20);
    
        // Set the our custom renderer for the cell
        notesCell.SetNextRenderer(new RoundCornerСellRenderer(notesCell));
    
        // Create an inner table for the notes
        var tableNotes = new Table(1)
            .SetWidth(UnitValue.CreatePercentValue(100));
    
        // Add a header of the inner table
        tableNotes.AddHeaderCell(new TextCell("Примечание",
            BoldFont, TitleForegroundColor, false));
    
        // Fill the inner table
        foreach(var note in notes)
            tableNotes.AddCell(new TextCell($"{note.Name}: {string.Join(", ", note.Options)}", 
                LightFont, RegularForegroundColor));
    
        // Add the inner table to the parent cell
        notesCell.Add(tableNotes);
    
        return notesCell;
    }
    
    private Cell CreatePriceCell(decimal price)
    {
        // Create a price cell
        var priceCell = new Cell()
            .SetBackgroundColor(RegularBackgroundColor)
            .SetPadding(10)
            .SetMargins(20, 20, 20, 10);
    
        // Set the our custom renderer for the cell
        priceCell.SetNextRenderer(new RoundCornerСellRenderer(priceCell));
    
        // Create an inner table for the price
        var tablePrice = new Table(1)
            .SetWidth(UnitValue.CreatePercentValue(100));
    
        // Add a header of the inner table
        tablePrice.AddHeaderCell(new TextCell("Цена",
            BoldFont, TitleForegroundColor, false, TextAlignment.RIGHT));
    
        // Fill the inner table
        tablePrice.AddCell(new TextCell(price.ToString(), 
            LightFont, RegularForegroundColor, true, TextAlignment.RIGHT));
    
        // Add the inner table to the parent cell
        priceCell.Add(tablePrice);
    
        return priceCell;
    }
    

    And voila, we get cells with margins, rounded corners, and most importantly - they are stretched in height:

    0 讨论(0)
提交回复
热议问题