Git Product home page Git Product logo

Comments (6)

MarcinZiabek avatar MarcinZiabek commented on May 24, 2024

Thank you for reaching out 😄

I am not entirely sure of what behavior you want to achieve. Would you please provide some visual examples?

from questpdf.

MercinaM avatar MercinaM commented on May 24, 2024

Examples

In all of the examples, the part of the content with the red background color is user-generated. This is the part of the content that we do not want to span multiple pages unless we have no other option.

Example 1

The content is short enough to comfortably fit inside the first page..

image

Example 2

The content is too long to fit inside the first page, but is short enough to fit inside a single page. Using ShowEntire, we can ensure the content is displayed in a single page in its entirety.

Page 1:

image

Page 2:

image

Example 3

This is where we run into a problem. The content is too long to fit into a single page. Since we're using ShowEntire to achieve the desired result for the second example, QuestPDF now throws an exception.

image

Instead of this behavior, ideally we'd like to have a method available (i.e. TryShowEntire), which would behave the same way as ShowEntire did in examples 1 and 2, but in this case, instead of throwing an exception, would simply render the content as if ShowEntire wasnt used:

Page 1:

image

Page 2:

image

Obviously I have very little idea about the inner workings of the library, and if what I'm asking for is even feasible. But if it is, it would greatly help us out.

Code used to generate the examples

private List<string> Paragraphs = new List<string>()
{
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ultricies dignissim commodo. Suspendisse cursus ultrices mi eu cursus. Nulla ultrices tortor aliquet erat faucibus tempus vel eu magna. Fusce non elit rhoncus, congue elit sed, tristique dolor. Pellentesque diam odio, luctus ac lectus id, pretium luctus eros. Ut eu blandit velit. Pellentesque at faucibus sem. Morbi ac diam id augue porta dapibus eget quis ipsum. Aenean volutpat diam in blandit egestas. Mauris sagittis semper nibh id dignissim. Nullam tempus mi ac augue dapibus, gravida laoreet nulla cursus. Aenean finibus, sapien ac aliquet molestie, dui ante tristique ante, sit amet viverra metus erat vel est. Integer ut congue dui.",

    "Praesent mattis diam eget congue convallis. Phasellus velit eros, gravida eget enim at, iaculis sollicitudin nisl. Mauris pulvinar arcu non velit vehicula, sit amet molestie elit lobortis. Nam eleifend felis quis lorem malesuada, eu feugiat urna cursus. Nulla vehicula a ante dignissim facilisis. Cras elit lacus, ornare vel suscipit at, dapibus ac nisi. Phasellus ac arcu posuere, pretium augue sed, euismod purus. Nullam lacinia, ligula convallis aliquet aliquam, odio erat dictum urna, ut mattis massa nulla vel mi. Quisque cursus nisi arcu, aliquam blandit neque euismod sed. Vestibulum elementum sapien hendrerit justo tempus pharetra. Nam ac malesuada ante. Sed eget libero arcu. Vivamus sit amet placerat dolor, vitae sagittis tortor.",

    "In vitae iaculis erat, ultricies convallis risus. Donec quis pharetra quam. Mauris semper erat in malesuada vehicula. Phasellus at nulla vulputate, posuere tellus et, pellentesque nunc. Morbi elementum dui fermentum tempus tempus. Praesent a cursus ex. Sed pellentesque maximus libero. Quisque rhoncus velit a pulvinar tempus. Integer at est non justo interdum scelerisque. Donec urna ipsum, tempus non ante eu, viverra interdum orci. Duis vitae porta libero, ac molestie sem. Nunc id arcu vel dolor tincidunt lacinia. Etiam ac diam accumsan, vulputate ante nec, scelerisque augue. Donec sed pellentesque augue, semper finibus dolor.",

    "Vivamus vel rutrum dui. Duis mattis mi ac convallis mollis. Donec a nisl et dui consequat malesuada. Aliquam a lacus odio. Vivamus et lectus in elit mattis porta. Donec a suscipit est. Donec blandit, ligula nec bibendum tempor, metus mi mollis eros, varius rutrum justo arcu in neque. Morbi varius molestie massa, in mollis ipsum volutpat eu. Nunc venenatis enim sit amet eros gravida, eget venenatis turpis commodo. In molestie vitae mauris ac congue. Cras facilisis, metus vitae consequat fringilla, lacus felis scelerisque ligula, quis auctor nisl nulla quis velit. Duis maximus, nisi id egestas feugiat, leo elit aliquam nisl, efficitur sagittis ipsum lectus cursus libero. Mauris at finibus sem.",

    "Nullam fermentum rutrum elementum. Nullam porttitor, dolor a dapibus auctor, quam dolor facilisis nunc, a pulvinar nisi lectus vel diam. Curabitur tempor, massa vel blandit consequat, turpis urna blandit justo, quis mattis justo libero nec velit. Cras imperdiet nulla eu nisl tincidunt, a euismod ligula pellentesque. Proin iaculis mi at orci finibus, non sagittis ante ornare. Nullam vitae risus id sem ornare malesuada eget ut odio. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis sit amet urna vitae nisi hendrerit imperdiet. Sed id est sapien. Pellentesque in odio ut nunc interdum dictum. Phasellus eu elementum lacus, et interdum ipsum. Praesent nec lacus congue lacus cursus euismod nec vitae massa."
};

public void Compose(IDocumentContainer container)
{
    container.Page(page =>
    {
        page.Margin(10f, Unit.Millimetre);
        page.DefaultTextStyle(TextStyle
            .Default
            .FontFamily(Fonts.SegoeUI)
            .FontSize(12f)
            .LineHeight(1.2f)
            .NormalWeight());

        page.Header()
            .Background("#FFFF00")
            .DefaultTextStyle(style => style.FontSize(48f))
            .Text("Page Header");
        
        page.Content()
            .Column(column =>
            {
                column.Item()
                    .Background("#00FFFF")
                    .PaddingVertical(5f, Unit.Millimetre)
                    .Text(text =>
                    {
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Line("This part is not user generated");
                        text.Span("This part is not user generated");
                    });

                column.Item()
                    .Background("#FF0000")
                    .ShowEntire()
                    .PaddingVertical(5f, Unit.Millimetre)
                    .Text(string.Join('\n', Paragraphs.Take(5)));

                column.Item()
                    .Background("#00FFFF")
                    .PaddingVertical(5f, Unit.Millimetre)
                    .Text("This part is not user generated");

                column.Item()
                    .Background("#00FFFF")
                    .Table(table =>
                    {
                        table.ColumnsDefinition(columns =>
                        {
                            columns.RelativeColumn(2f);
                            columns.RelativeColumn(5f);
                            columns.RelativeColumn(3f);
                            columns.RelativeColumn(2f);
                        });

                        table.Header(header =>
                        {
                            header.Cell().Text("Column 1").Bold();
                            header.Cell().Text("Column 2").Bold();
                            header.Cell().Text("Column 3").Bold();
                            header.Cell().Text("Column 4").Bold();
                        });

                        for (var i = 0; i < 30; i++)
                        {
                            table.Cell().Text(i.ToString());
                            table.Cell().Text(i.ToString());
                            table.Cell().Text(i.ToString());
                            table.Cell().Text(i.ToString());
                        }
                    });
            });

        page.Footer()
            .Background("#FFFF00")
            .DefaultTextStyle(style => style.FontSize(9f))
                .Text("Page Footer");
    });
}

from questpdf.

MarcinZiabek avatar MarcinZiabek commented on May 24, 2024

My suggestion is to use the EnsureSpace with a value slightly smaller than the content height (page height - header - footer). If I am not mistaken, it may produce the desired outcome.

from questpdf.

MercinaM avatar MercinaM commented on May 24, 2024

Well, as I mentioned in the original post, I don't know in advance how large the the header or footer are going to be. For a simplified example of our use case, lets presume the user can modify the following properties:

public struct HeaderSettings {
    public HeaderType Type { get; set; } // Text or Image
    public string Text { get; set; } // Used when header type is "Text".
    public float FontSize { get; set; } // Used when header type is "Text".
    public byte[] Image { get; set; } // Used when header type is "Image".
}
public struct FooterSettings {
    public FooterType Type { get; set; } // Text or Image
    public string Text { get; set; } // Used when footer type is "Text".
    public float FontSize { get; set; } // Used when footer type is "Text".
    public byte[] Image { get; set; } // Used when footer type is "Image".
}

I have no idea how big the header or footer are going to be. That also means there is no easy way for me to safely use EnsureSpace.

The only way I could think of to safely use EnsureSpace is to essentially do a dry run, where I only render the header and footer, and use a dynamic component that renders nothing and just measures the available space on the page. If I then take the calculated height value (and perhaps subtract a millimetre or so), it should probably be safe to use in EnsureSpace.

from questpdf.

MarcinZiabek avatar MarcinZiabek commented on May 24, 2024

I wonder... we could create a variant of EnsureSpace that attempts to use all available vertical space as its argument.

I already have trouble with naming: ShowEntire, EnsureSpace... and how that third option could be named?

from questpdf.

Prototipo-Erick-Santander avatar Prototipo-Erick-Santander commented on May 24, 2024

I think this is something like a feature I would also need for my current project, I need to show a table, and I need the table to be shown in its entirety unless absolutely impossible, I don't know how many rows the table will have, and the rows can have different heights. Using ShowEntire mostly works but can throw stray exceptions once in a while, I think that a 'safe' version of the ShowEntire, something like a TryShowEntire() that would try to fit the content on the current page, if that is not enough, tries to fit it in 1 page, if it still does not fit, it just breaks the content to 2 or more pages.

As @MercinaM said I was about to implement this using Dynamic Component, but a more native way to do this would be greatly appreciated.

from questpdf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.