New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paging support in PDF added #41

Merged
merged 4 commits into from Apr 27, 2016

Conversation

Projects
None yet
@gyfke
Contributor

gyfke commented Apr 27, 2016

content: url()

Added support for images in css content property so you can reuse embedded images
Example:

    img.logo {
        content: url('data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAA...
    }
...
    <img class="logo">
...

Paging in PDF

Implemented css property page-break-inside. It supports two values: auto (default) and avoid

  1. With default values there is no rules defined to transfer html-blocks or words to the next page. And pages can be splitted right through the text
    1
  2. With td { page-break-inside: avoid; } words which are located in the edge of pages will be transferred to the new page.
    The same is for th, p, span and I guess for any text in any other tags (though I’ve checked only aforementioned)
    2
  3. With table { page-break-inside: avoid; } if table row is not fitted to the page, then the whole row will be transferred to the next page.
    If row is bigger than page then it doesn’t make sense to transfer it and the value of page-break-inside will be ignored.
    3

Known cosmetic issues:

  1. If table's page-break-inside=auto and cell’s page-break-inside=avoid then an empty part of table cell can be rendered at the end of page
    And all the text will be transferred to the next one
    4
  2. If table's page-break-inside=avoid and the row is bigger than the rest of page but can be fitted to the next page it will be transferred to the next page and will leave a lot of space on the previous one
    5

Headers and footers

Added support for position: fixed, elements with fixed position are rendered on every page and can be used as headers/footers/watermarks.
It ignores page margins, so if you need to place 50px-height header and footer on the page with 20px margins you need to set top/bottom margins to 70px to leave proper margins for the main content. Example:

var config = new PdfGenerateConfig()
{
    MarginBottom = 70,
    MarginLeft = 20,
    MarginRight = 20,
    MarginTop = 70,
};
...
.header {
    position: fixed;
    left: 20px;
    top: 20px;
}

.footer{
    position: fixed;
    left: 20px;
    top: 750px;
}
<body>
    <div class="header">
        logo
    </div>
    <div class="footer">
        disclaimer
    </div>

    <p>
        page content...
...

image

@ArthurHub ArthurHub merged commit 48dd0c3 into ArthurHub:master Apr 27, 2016

1 check passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
@ArthurHub

This comment has been minimized.

Owner

ArthurHub commented Apr 27, 2016

NICE!
Great work!
Can I interest you in taking this project as a direct contributor?

@michalczukm

This comment has been minimized.

michalczukm commented Jun 22, 2016

@ArthurHub could you publish nuget package update with this fix :) ?
We're actually having this problem in HtmlRenderer.PdfSharp 1.5.0.6

@Ixonal

This comment has been minimized.

Ixonal commented Jul 5, 2016

I'm looking to get this functionality as well, so it'd be much appreciated if the nuget package were to be updated.

@netmann

This comment has been minimized.

netmann commented Sep 19, 2016

page-break-inside: avoid doesn't include <br/> tag inside <p></p> element during page height calculation. So page break doesn't work properly when <br/> element is used.

e.g. <p>Lorem ipsum dolor sit <br/> amet, consectetur adipiscing elit</p>

I would be grateful for fix

@amreimer

This comment has been minimized.

amreimer commented Oct 5, 2016

I downloaded the demo code, which includes all the changes described here, however the resulting PDFs do not break as the description states. I used the "Breaking pages 1" and "Breaking Pages 2" sample code. I would be EXTREMELY excited if this code did work as described and illustrated above, it is exactly what I'm looking for. Until then I am trying all kinds of styles/methods.

I even downloaded all the code and built it myself without nuget with the same results.

renderer-1
renderer-2
renderer-3

@HumanRob

This comment has been minimized.

HumanRob commented Oct 25, 2016

@amreimer yes I've also been unable to get it to work - even when downloading and building the code myself. table { page-break-inside: avoid; } seems to work as expected, but I can't get td { page-break-inside: avoid; } to work at all - also tried it with span and p elements.

I'd be happy to look into fixing this myself, but because I can't get the feature to work at all it's kind of hard to know where to begin!

For the time being, to prevent words getting cut in half across pages I've had to wrap each paragraph in a table with page-break-inside: avoid; set, which almost but not quite achieves the same result at the cost of horribly mangling my html!

If anyone could provide steps to get this feature working, or even ideas on where I should start bug hunting, please let me know.

@PawelMaj

This comment has been minimized.

Collaborator

PawelMaj commented Nov 15, 2016

@HumanRob @amreimer Hey! I have recently decided to join this project and started looking into the page-breaking code in specific (I have my own self interests in making it work haha). That being said, I think the words will break a page correctly if the immediate parent element has that attribute on it and if the parent element is smaller than the size of the page.

Should work
<td style="page-break-inside: avoid;">Hello</td>

Will fail
<td style="page-break-inside: avoid;"><span>Hello</span></td>

Unfortunately I am a bit busy the next few weeks, but when I am free I will do my best to implement some generic page breaking that works with nested elements. Also if you only really care about making sure words are not split in half you can change the following code:

CssRect.cs ln307

From:

if (!box.IsFixed && box.PageBreakInside == CssConstants.Avoid)
{
     word.BreakPage();
}

To:

if (!box.IsFixed)
{
     word.BreakPage();
}

If I am correct (I may be wrong, I have only started to get into this code) this change will make sure that no words will ever be split on a page break.

@grandpaSam

This comment has been minimized.

grandpaSam commented Dec 13, 2016

@PawelMaj I believe you actually mean:

CssLayoutEngine.cs ln307

@luislhg

This comment has been minimized.

luislhg commented Jan 31, 2017

It is on CssLayoutEngine.cs ln307
And PawelMaj works as expected! Finally got this working, thanks! :)

@SwiftDoge

This comment has been minimized.

SwiftDoge commented Feb 28, 2017

I was having the issue of pages being split right through the text and adding this bit of css seems to have fixed the problemtable, tr, td { page-break-inside: avoid; font-size: 14px; }. This works without updating the html-rendered to the 1.5.1-beta1 version which is quite confusing to me, how is that possible? Did I just get lucky with my particular pdf? (Just a disclaimer I have close to no idea how this html-renderer works so apologies if this is a silly question )

@grandpaSam

This comment has been minimized.

grandpaSam commented Mar 3, 2017

@gyfke
I seem to be having and issue with fixed position. On the second page my header seems to draw over the content. I would like to have a header on each page which I believe the position fixed attribute is supposed to accomplish. This seems to work well on the first page where I can apply a margin on the body. But on the second page the margin no longer is applied and the header will draw over the content of the page. Am I using position fixed incorrectly?

@cjfjones

This comment has been minimized.

cjfjones commented Apr 24, 2017

@gyfke @grandpaSam - I'm having exactly the same issue, whereby on the first page, the margins are in relation to the fixed content (i.e. the header and footer). On the subsequent pages the margins are in relation to the page itself, therefore my subsequent pages have overlapping objects.

p.s. I am using this in combination with the paging tables.

@vip32

This comment has been minimized.

vip32 commented May 30, 2017

@ArthurHub is this available in current 1.5.0.6?

@tyeth

This comment has been minimized.

@tyeth
note to self...

@grandpaSam

This comment has been minimized.

grandpaSam commented Jul 12, 2017

I noticed that the example program has the same header margin problem as in the i described in my previous comment.

@emilmork

This comment has been minimized.

emilmork commented Jan 15, 2018

Is there any chance this changes with page-break will get to an actual nuget package ? :)

Great work with this package anyway 👍

@ksingamreddy

This comment has been minimized.

ksingamreddy commented Mar 13, 2018

For page-break I tried with following code

td { page-break-inside: avoid; }
table { page-break-inside: avoid; }

which is working perfectly but I am getting some additional extra edges at end of the page as shown in the attachment.

edges
Is there any way to get rid of extra edges ?

@RylaiSlyfe

This comment has been minimized.

RylaiSlyfe commented Sep 18, 2018

Bumping this. Am using the 1.5.1 prerelease and the page break for tables is working as expected, but with normal text it's still cut off
2018-09-18 10_54_33

@HenningKlokkeraasen

This comment has been minimized.

HenningKlokkeraasen commented Oct 26, 2018

I experience the same issue as RylaiSlyfe.
I worked around it by wrapping all texts in a <table>, and styling it with
table,
th,
td {
page-break-inside: avoid;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment