wicked_pdf icon indicating copy to clipboard operation
wicked_pdf copied to clipboard

Best way to exclude header and footer from first page

Open fteem opened this issue 10 years ago • 10 comments

Hello,

I'm having a very hard time removing the header and footer on the cover page of a document that's being generated with wicked_pdf within a Rails app.The controller's action renders the pdf document, using:

   *snipped*
      render pdf: @document.document_type,                                          
        page_size: 'A4',                                                            
        layout: false,                                                              
        orientation: @document.landscape ? 'Landscape' : 'Portrait',                
        encoding: 'UTF8',                                                                                                             
        header: {html: {template: 'documents/_header'}, spacing: 35 },              
        footer: {html: {template: 'documents/_footer'}, spacing: 0 },               
        margin: {top: 30, bottom: 20, left: 0, right: 0},                            
        show_as_html: params[:html].present?                                        
    *snipped*

I'm aware that wicked relies on wkhtmltopdf to convert html to pdf. I checked their discussions and the the only one that I found suggest usage of JS. This is my version of the JS I found there.

  function hideHeader() {                                                           
    var vars={};                                                                    
    var x=document.location.search.substring(1).split('&');                                            
    for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}          

    if(vars['page'] == 1){                                                          
      var elt = document.getElementById("document-header");                         
      elt.parentNode.removeChild(elt);                                              
    }                                                                               
  }

When the header and footer is removed, the content of the PDF moves upwards which results to breaking the layout of the rest of the pages.

For example, there are couple of pages where the main content of the page "slips under" the header: 533ee02000779111d8ed843a 2014-04-04 18-43-43 2014-04-04 18-44-38

I used to sort this out with a top margin in the render action, but if I use it, the margin will be applied to the first page too, which will result with a blank white block in the top of the document. Other possible solution is removing that margin on the first page using JavaScript. Is that possible?

Thanks in advance for any help or advice on this.

fteem avatar Apr 04 '14 16:04 fteem

Because headers and footers are repeated on every page, my first thought is that you should ditch setting up the header and footers in the controller for wicked_pdf, and instead in your body:

<div id="pdf-header" style="display:none;">
  <%= render template: 'documents/_header' %>
</div>

Then use JavaScript to unhide it only on the first page, or alternately, hide it on every page but the first. Same deal with the footer.

Please let me know if this helps (or not)!

unixmonkey avatar Apr 04 '14 18:04 unixmonkey

Hi, in order to do what you suggested I need to know where every page begins/ends. But, there will be couple of pages in the document that I'm not sure where they will begin/end because I'm generating some tables using Underscore.js/Handlebars. So, this isn't an option for me.

Is there another way to achieve this, or maybe, a way to target the top margin using JS?

Thanks!

fteem avatar Apr 07 '14 07:04 fteem

If the problem with your first approach is that the content "slips up" after removal, then instead of:

elt.parentNode.removeChild(elt);

You do something a little less drastic than removing the element entirely.

Perhaps just remove the content with elt.innerHTML = '';, and/or set the css to visibility: hidden;, and use CSS to give it the height, width and padding desired.

unixmonkey avatar Apr 07 '14 13:04 unixmonkey

I thought about not removing the element and hiding it instead. Using visibility: hidden means that there will be blank areas on the cover page where the cover/header should be placed.

I guess that adding proper margins to the elements on the cover page could "push" the document downwards so the pages don't break.

Any other ideas? Thanks!

fteem avatar Apr 08 '14 07:04 fteem

Have you tried the :cover option? If the gem and binary version are compatible it works.

danimataonrails avatar Apr 16 '14 09:04 danimataonrails

@danimataonrails the :cover option seems to be using a separate source:

:cover                          => 'URL, Pathname, or raw HTML string',

In my project, we don't use a separate cover page. But still want the first page to be without header and footer.

nengxu avatar Sep 19 '14 18:09 nengxu

any success?

mentero avatar Feb 02 '15 15:02 mentero

In the end, we went with generating the cover and the body as separate documents and merging them into one before sending it to the user.

fteem avatar Feb 02 '15 20:02 fteem

Achieved the result quickly by using "cover" option.

grammakov avatar Jun 21 '18 15:06 grammakov

You can use some javascript to detect the current page and then add display none to your header only in first page. Following the Page Numbering instructions from WickedPDF documentation.

This is working in my PDF.

<!DOCTYPE html>
<html>
<head>
  <script type="text/javascript">
    function headerCheck() {
      var x=document.location.search.substring(1).split('&');
      for (var i in x) {
        if(x[i] == "page=1") {
          document.getElementsByClassName("header")[0].style.display = "none";
        }
      }
    }
  </script>
</head>
<body onload="headerCheck()">
  <div class='header'>
    <h1><%= cellar.name %></h1>
  </div>
</body>
</html>

adriacarro avatar Jun 03 '21 10:06 adriacarro