2013-07-06 34 views
8

Tôi có ví dụ sau:Phantomjs không làm footers với một phong cách tùy chỉnh

var page = require('webpage').create(), 
    system = require('system'); 

if (system.args.length < 3) { 
    console.log('Usage: printheaderfooter.js URL filename'); 
    phantom.exit(1); 
} else { 
    var address = system.args[1]; 
    var output = system.args[2]; 
    page.viewportSize = { width: 600, height: 600 }; 
    page.paperSize = { 
     format: 'A4', 
     margin: "1cm" 
     footer: { 
      height: "1cm", 
      contents: phantom.callback(function(pageNum, numPages) { 
       if (pageNum == numPages) { 
        return ""; 
       } 
       return "<h1 class='footer_style'>Footer" + pageNum + "/" + numPages + "</h1>"; 
      }) 
     } 
    }; 
    page.open(address, function (status) { 
     if (status !== 'success') { 
      console.log('Unable to load the address!'); 
     } else {     
      window.setTimeout(function() { 
       page.render(output); 
       phantom.exit(); 
      }, 200); 
     } 
    }); 
} 

Trong ví dụ trên, chúng tôi sử dụng lớp footer_style trông thích trong file css của tôi như sau:

.footer_style { 
    text-align:right; 
} 

Nhưng tiếc là không hoạt động. Tôi đang cố gắng tạo tệp pdf như sau:

./phantomjs rasterize.js index.html test.pdf 

Trả lời

3

Từ kinh nghiệm trước đây của tôi, các ma không hỗ trợ kiểu trong đầu trang/chân trang tùy chỉnh.

Giải pháp duy nhất mà tôi tìm thấy là áp dụng một phong cách nội tuyến như thế này:

var page = require('webpage').create(), 
    system = require('system'); 

if (system.args.length < 3) { 
    console.log('Usage: printheaderfooter.js URL filename'); 
    phantom.exit(1); 
} else { 
    var address = system.args[1]; 
    var output = system.args[2]; 
    page.viewportSize = { width: 600, height: 600 }; 
    page.paperSize = { 
     format: 'A4', 
     margin: "1cm", 
     footer: { 
     height: "1cm", 
     contents: phantom.callback(function(pageNum, numPages) { 
      return "<h1 style='text-align:right'>Footer" + pageNum + "/" + numPages + "</h1>"; 
     }) 
     } 
}; 
page.open(address, function (status) { 
    if (status !== 'success') { 
     console.log('Unable to load the address!'); 
    } else {     
     window.setTimeout(function() { 
      page.render(output); 
      phantom.exit(); 
     }, 200); 
    } 
}); 
} 

Lưu ý: Một dấu phẩy là mất tích trong mã của bạn sau khi margin: "1cm"

+0

Vâng tôi biết giải pháp này nhưng tôi cần làm việc này bằng cách sử dụng các lớp css – Erik

9

Chúng ta biết rằng các lớp học không làm việc nhưng inline phong cách làm. Những gì chúng ta có thể làm là thay thế lớp bằng kiểu được tính toán. Đây là một chức năng sẽ lấy một đoạn html, tạo thành phần tử tạm thời trong phần thân bằng html, tính toán kiểu cho mỗi phần tử với một lớp, thêm kiểu nội tuyến được tính toán và trả về html mới.

function replaceClassWithStyle(html) { 
    return page.evaluate(function(html) { 
     var host = document.createElement('div'); 
     host.innerHTML = html; 
     document.body.appendChild(host); // if not appended, values will be blank 
     var elements = host.getElementsByTagName('*'); 
     for (var i in elements) { 
      if (elements[i].className) { 
       elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText); 
      } 
     } 
     document.body.removeChild(host); 
     return host.innerHTML; 
    }, html); 
} 

Sau đó chỉ cần gọi hàm này trong footer của bạn:

page.paperSize = { 
    footer: { 
     contents: phantom.callback(function(pageNum, numPages) { 
      if (pageNum == numPages) { 
       return ""; 
      } 
      return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + "/" + numPages + "</h1>"); 
     }) 
    } 
}; 

Bạn sẽ cần phải di chuyển tất cả điều này trong page.open().

Tôi đã thử nghiệm nó và chân trang được căn chỉnh về bên phải.

+0

Điều này giống như giải pháp lý tưởng để hiển thị đầu trang/chân trang, nhưng trong v1.9.7 điều này dường như 'trống' tài liệu.body sau appendChild. Có thể là lỗi PhantomJS. Bạn đã thử nghiệm phiên bản này trong phiên bản nào? –

+2

Đã khắc phục sự cố đó^và một số vấn đề khác: http://stackoverflow.com/a/27296129/678265 –

4

Tôi có bản cập nhật cho mak's excellent answer cho PhantomJS 1.9.7.

Phiên bản này sửa lỗi:

  • vỡ lỗi mà 'trống là tài liệu gốc (PhantomJS 1.9.7)
  • Phong cách mixups khi phong cách được lồng nhau (làm traversal sâu-đầu tiên thay vì)
  • Cũng làm việc khi thẻ không có lớp học
/** 
* Place HTML in the parent document, convert CSS styles to fixed computed style declarations, and return HTML. 
* (required for headers/footers, which exist outside of the HTML document, and have trouble getting styling otherwise) 
*/ 
function replaceCssWithComputedStyle(html) { 
    return page.evaluate(function(html) { 
    var host = document.createElement('div'); 
    host.setAttribute('style', 'display:none;'); // Silly hack, or PhantomJS will 'blank' the main document for some reason 
    host.innerHTML = html; 

    // Append to get styling of parent page 
    document.body.appendChild(host); 

    var elements = host.getElementsByTagName('*'); 
    // Iterate in reverse order (depth first) so that styles do not impact eachother 
    for (var i = elements.length - 1; i >= 0; i--) { 
     elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText); 
    } 

    // Remove from parent page again, so we're clean 
    document.body.removeChild(host); 
    return host.innerHTML; 
    }, html); 
} 
Các vấn đề liên quan