Растяжение внутреннего содержимого внутри ячейки iText 7 PDF - PullRequest
0 голосов
/ 03 июля 2018

Я все еще сражаюсь с iText, и похоже, что он бежит за мной. Я уже задавал вопрос здесь, но, скорее всего, вопрос был настолько абстрактным, что я не мог получить ответы.

Итак, у меня есть таблица с двумя ячейками - notesCell и priceCell:

public void GenerateTable(SimpleProductVM product)
{
    // Create the table
    var productTable = new Table(new float[] { 1, 1 })
        .SetWidth(UnitValue.CreatePercentValue(100))
        .SetKeepTogether(true);

    // Create a cell of the notes
    var notesCell = CreateNotesCell(product.AdditionalAttributes);

    // Create a cell of the price
    var priceCell = CreatePriceCell(product.Price);

    // Add all of the cells
    productTable.AddRange(notesCell, priceCell);

    var writer = new PdfWriter(PathToFile);
    var pdfDocument = new PdfDocument(writer);
    var document = new Document(pdfDocument);

    document.Add(productTable);

    document.Close();
}

В каждой ячейке (notesCell, priceCell) у меня есть внутренняя таблица. Я хочу, чтобы эта внутренняя таблица была растянута по размеру родительской ячейки. Это мой код для создания двух ячеек (notesCell, priceCell):

private Cell CreateNotesCell(IList<ProductAttribute> notes)
{
    // Create a notes cell
    var notesCell = new Cell()
        .SetPadding(10);

    // Create an inner table for the notes
    var tableNotes = new Table(1)
        .SetBackgroundColor(RegularBackgroundColor)
        .SetMargin(10)
        // if I set the width in percent, 
        //then the table is stretched to the width of the parent cell
        .SetWidth(UnitValue.CreatePercentValue(100))
        // But if I set the height in percent,
        // the table is not stretched to the height of the parent cell!!!!
        .SetHeight(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()
        .SetPadding(10);

    // Create an inner table for the price
    var tablePrice = new Table(1)
        .SetBackgroundColor(RegularBackgroundColor)
        .SetMargin(10)
        // if I set the width in percent, 
        //then the table is stretched to the width of the parent cell
        .SetWidth(UnitValue.CreatePercentValue(100))
        // But if I set the height in percent,
        // the table is not stretched to the height of the parent cell!!!!
        .SetHeight(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;
}

Как я указал в комментариях, если вы установите SetWidth(UnitValue.CreatePercentValue (100)) на внутренней таблице, все в порядке - она ​​растягивается по ширине родительской ячейки. Но если я установлю SetHeight(UnitValue.CreatePercentValue(100)), внутренняя таблица не будет растягиваться по высоте родительской ячейки. Вот результат: enter image description here В моем предыдущем вопросе мне посоветовали использовать FormXObject, но я не знаю, как применить его к моей проблеме, потому что использование FormXObject подразумевает установку абсолютных размеров, которых я не знаю изначально: var tableTemplate = new PdfFormXObject(new Rectangle(??, ??));

1 Ответ

0 голосов
/ 03 июля 2018

Мне удалось решить проблему самостоятельно. Теперь у каждого внутреннего стола нет цвета, и я не пытаюсь его растянуть. Это, скорее всего, самое важное. Я уделил много внимания клеткам и решил, что мне нужно с ними работать. Зачем? Потому что каждая ячейка имеет высоту, равную максимальной высоте некоторой ячейки в ряду. И это то, что мне нужно

Итак, я хочу, чтобы каждая ячейка имела цвет, поля, закругленные углы и содержала содержимое в виде внутренней таблицы. Кроме того, каждая ячейка автоматически будет иметь одинаковую высоту - чего я и пытался достичь.

Во-первых, нам нужно создать собственный рендерер для ячеек, который позволяет рисовать ячейки с полями (по умолчанию нет) и с закругленными углами. Это мой рендерер для ячеек:

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();  
    } 
}

Вот и все! Теперь все, что вам нужно сделать, это создать ячейки, добавить их поля и этот пользовательский рендер:

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;
}

И вуаля, мы получаем ячейки с полями, закругленными углами, а главное - они растянуты по высоте:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...