eKoopmans / html2pdf.js

Client-side HTML-to-PDF rendering using pure JS.
MIT License
4.02k stars 1.37k forks source link

repeating table header on page break #281

Open lodossDev opened 4 years ago

lodossDev commented 4 years ago

Hi guys, I have a table like below very simple, I am trying to get repeating table headers for every time it goes to a new page, how can I do this, currently it just overflows to the next page with a row looking as it is being cut-off?

<table class="tg">
    <thead>
        <tr>
            <th class="tg-baqh" colspan="6">Results</th>
        </tr>
        <tr>
            <td class="tg-hmp3">No</td>
            <td class="tg-hmp3">Competition</td>
            <td class="tg-hmp3">John</td>
            <td class="tg-hmp3">Adam</td>
            <td class="tg-hmp3">Robert</td>
            <td class="tg-hmp3">Paul</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="tg-0lax">1</td>
            <td class="tg-0lax">Swimming</td>
            <td class="tg-lqy6">1:30</td>
            <td class="tg-lqy6">2:05</td>
            <td class="tg-lqy6">1:15</td>
            <td class="tg-lqy6">1:41</td>
        </tr>
        <tr>
            <td class="tg-hmp3">2</td>
            <td class="tg-hmp3">Running</td>
            <td class="tg-mb3i">15:30</td>
            <td class="tg-mb3i">14:10</td>
            <td class="tg-mb3i">15:45</td>
            <td class="tg-mb3i">16:00</td>
        </tr>
        <tr>
            <td class="tg-0lax">3</td>
            <td class="tg-0lax">Shooting</td>
            <td class="tg-lqy6">70%</td>
            <td class="tg-lqy6">55%</td>
            <td class="tg-lqy6">90%</td>
            <td class="tg-lqy6">88%</td>
        </tr>
        <tr>
            <td class="tg-0lax">3</td>
            <td class="tg-0lax">Shooting</td>
            <td class="tg-lqy6">70%</td>
            <td class="tg-lqy6">55%</td>
            <td class="tg-lqy6">90%</td>
            <td class="tg-lqy6">88%</td>
        </tr>
    </tbody>
</table>

Image of table pdf output

simon-c-wong commented 4 years ago

There's a built in div that simulates a page break: <div class='html2pdf__page-break'></div>

I'm also creating a table similar to yours but in addition to using the page break div, I calculate the section height and if it's more than the page's height (1016px) or what's remaining if you have other data, I append the page break.

albert-kam commented 4 years ago

Any official support for this feature yet ?

anil826 commented 4 years ago

Any support?

gabyzenack commented 3 years ago

same problem, any fix?

revatim commented 3 years ago

I am having a similar issue, Is there any workaround for this ?

abrhbruno commented 3 years ago

Hi, all.

I had a similar problem when generating a pdf report with complex styles, and also with a custom header and footer.

In order to solve this I did the following tasks: 1) I prepared my report by creating an element with all pdf report's content I wanted, with limited width to fit on pdf default width I was using. On each element I put a class in order to select everything by class. 2) I created an angular component with the page width and height I wanted. This page have a header, footer, page break with all the styles I wanted. 3) After that, I used the idea from issue #83 to calculate the sizes of each element to decide if it would fit on current page or if I needed to generate another one. This generated all pages I wanted as groups of html string elements. 4) With all the html pages collected, I just needed to iterate through them to generate a new component instance for each page I wanted. 5) When I had all the pages generated on this root element helper, I passed it to html2pdf generator and all the magic happened.

Check this stackblitz for details on this idea: https://stackblitz.com/edit/angular-a83z6y

If you use this idea of a separate component, you can save the table header element and use it to insert a new header every time you create a new page.

frabanzo commented 2 years ago

Hi @abrhbruno , can you show the code that solves the issue?

vstar001 commented 2 years ago

hi @eKoopmans please tell me the solution for the repeat table header on next page and the extra blank page issue

I have uploading a coding pdf file myfile (4).pdf mycode pdf screenshort

ghost commented 2 years ago

Hi, all.

I had a similar problem when generating a pdf report with complex styles, and also with a custom header and footer.

In order to solve this I did the following tasks:

  1. I prepared my report by creating an element with all pdf report's content I wanted, with limited width to fit on pdf default width I was using. On each element I put a class in order to select everything by class.
  2. I created an angular component with the page width and height I wanted. This page have a header, footer, page break with all the styles I wanted.
  3. After that, I used the idea from issue text is cut in the middle #83 to calculate the sizes of each element to decide if it would fit on current page or if I needed to generate another one. This generated all pages I wanted as groups of html string elements.
  4. With all the html pages collected, I just needed to iterate through them to generate a new component instance for each page I wanted.
  5. When I had all the pages generated on this root element helper, I passed it to html2pdf generator and all the magic happened.

Check this stackblitz for details on this idea: https://stackblitz.com/edit/angular-a83z6y

If you use this idea of a separate component, you can save the table header element and use it to insert a new header every time you create a new page.

the link you provide is not working

ghost commented 2 years ago

please help i am trying to repeat headers and footer on every page break

ghost commented 2 years ago

hi @eKoopmans please tell me the solution for the repeat table header on next page and the extra blank page issue

I have uploading a coding pdf file myfile (4).pdf mycode pdf screenshort

yes I also facing this issue and I want to header and footer on every page please help

wamiqreh commented 2 years ago

For Workaround : What I did was modify the html2pdf's toContainer method to repeat the header of the table if the the table is breaking into next page the line i added was this jQuery(t).parent().parent().find('thead').find('tr').clone().insertAfter(jQuery(h)); I used jQuery but pure JavaScript can also be used but please note this is a dirty solution and could be error prone but it solves my purpose for now

 if (A.before) {
                    h = lt("div", {
                        style: {
                            display: "block",
                            height: e - s.top % e + "px"
                        }
                    });
                    t.parentNode.insertBefore(h, t)
                    jQuery(t).parent().parent().find('thead').find('tr').clone().insertAfter(jQuery(h)); ///This is what i added
                }
vstar001 commented 2 years ago

For Workaround : What I did was modify the html2pdf's toContainer method to repeat the header of the table if the the table is breaking into next page the line i added was this jQuery(t).parent().parent().find('thead').find('tr').clone().insertAfter(jQuery(h)); I used jQuery but pure JavaScript can also be used but please note this is a dirty solution and could be error prone but it solves my purpose for now

 if (A.before) {
                    h = lt("div", {
                        style: {
                            display: "block",
                            height: e - s.top % e + "px"
                        }
                    });
                    t.parentNode.insertBefore(h, t)
                    jQuery(t).parent().parent().find('thead').find('tr').clone().insertAfter(jQuery(h)); ///This is what i added
                }

it worked or not

albertomanzano11 commented 2 years ago

@vstar001 I solved on my projects using this options:

<vue3-html2pdf
        :show-layout="false"
        :float-layout="true"
        :enable-download="false"
        :preview-modal="false"
        filename="memoria-del-projecte.pdf"
        :pdf-quality="1"
        :manual-pagination="true"
        pdf-format="a4"
        pdf-orientation="portrait"
        pdf-content-width="800px"
        ref="html2Pdf"
        @beforeDownload="beforeDownload($event)"
      >

---

.set({
          ...options,
              margin: [0,15, 15, 15],
             filename: 'pdfFileName.pdf',
             image:        { type: 'jpeg', quality: 0.98 },
             html2canvas:  { scale: 1, letterRendering: true },
             jsPDF:        { unit: 'pt', format: 'letter', orientation: 'portrait' },
            pagebreak: { after: 'section', mode: ['avoid-all', 'css', 'legacy'] }
        })

I had a 60 pages PDF, so i divide my PDF into sections and break after each section.

<section class="pdf-item">
    <div class="myStyle keeptogether">
       ....your content
     </div>
</section>

<section class="pdf-item">
    <div class="myStyle keeptogether">
       ....your content
     </div>
</section>

The other problem i had was those super long text's I used this class for those super text's, in order to break if text was too long.

.keeptogether {page-break-inside:avoid; break-inside: avoid;}
.myStyle {

// for me had to do some teeeks on wordbreaking
   overflow-wrap: break-word;
    word-wrap: break-word;
    -ms-word-break: keep-all;
    word-break: keep-all;
    -ms-hyphens: auto;
    -moz-hyphens: auto;
    -webkit-hyphens: auto;
    hyphens: auto;
     }
sangeethavisvanathan commented 2 months ago

Is there any update on the issue? Can anybody help me with the solution?

LeeManh commented 4 weeks ago

any solution ?