2015-06-22 14 views
6

Dưới đây là câu trả lời của chúng tôi:Làm thế nào để có được số trang trong pdf được tạo ra bởi html với wkhtmltopdf

Chúng tôi hiện đang sử dụng wkhtmltopdf để tạo ra một file PDF từ một mẫu html nhất định.

Một số thông tin cơ bản:

Chúng tôi đang sử dụng Sulu CMF để xây dựng back-end của chúng tôi, mà là dựa trên Symfony2. Gói KnpSnappy được sử dụng làm trình bao bọc Symfony cho wkhtmltopdf.

Làm thế nào chúng ta tạo ra các file PDF:

Như nhiều file PDF chia sẻ cùng một tiêu đề và chân trang chúng tôi đã tạo ra một BasePDFBundle trong đó cung cấp một PDFManager để xây dựng PDF một cách nhanh chóng bởi một mẫu TWIG nhất định. Theo mặc định, đầu trang và chân trang chung (thường là với tên và biểu trưng của khách hàng) được bao gồm.

Các chân số vấn đề/trang ở chân (hoặc tiêu đề):

Nó rất hữu ích để thêm số trang vào một tập tin PDF ví dụ. cho các đơn đặt hàng, tuy nhiên hầu hết nội dung của chúng tôi được thêm động (ví dụ: danh sách sản phẩm). Vì kiểu dáng của PDF có thể thay đổi và nội dung tự động được thêm vào nên phải có cách nhanh chóng và dễ dàng để thêm hiện tại và tổng số trang vào tệp PDF được tạo. Đây là những gì chúng tôi đã làm:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 
<html> 
<head> 
    <base href="{{ app.request.schemeAndHttpHost }}" /> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <link rel="stylesheet" href="{{ asset('bundles/pdfbase/css/pdfstyles.css') }}"/> 
</head> 
<body class="footer"> 
    <div class="footer-container"> 
     <div class="footer-widget"> 
      <b>FooBar Company Name</b> 
     </div> 
     <div class="text-align-right"> 
      <span class="page"></span>/<span class="topage"></span> 
     </div> 
    </div> 

    <script type="text/javascript"> 
    (function() { 
     // get all url parameters and transform it to a list 
     // pdf generator adds a param for current and the total page sum 
     // add the value to the html elements 
     var urlParams = document.location.search.substring(1).split('&'); 
     var urlParamsList = {}; 
     var pagingElements = ['topage', 'page']; 

     for (var i in urlParams) { 
     var param = urlParams[i].split('=', 2); 
     urlParamsList[param[0]] = unescape(param[1]); 
     } 

     for (var i in pagingElements) { 
     var elem = document.getElementsByClassName(pagingElements[i]); 
     for (var j = 0; j < elem.length; ++j) { 
      elem[j].textContent = urlParamsList[pagingElements[i]]; 
     } 
     } 
    })(); 
    </script> 
</body> 

Có tên biến của pagetopage có thể tốt hơn, tuy nhiên họ cũng giống như các wrapper KnpSnappy sử dụng khi sáp nhập các mẫu cành lá vào mẫu PDF thức. Đây là cách dễ nhất để có được số trang hiện tại và tổng số trang vì bạn có thể cho phép trình bao bọc thực hiện tất cả các phép tính.

Cuối cùng, bạn chỉ cần thay thế văn bản của thẻ html và thats it!

Sự khác nhau giữa máy tính và máy chủ địa phương của bạn:

Như wkhtmltopdf mở một trình duyệt ảo để "render" các mẫu cành lá này có thể dẫn đến sai sót trong hệ pdf của bạn trên máy chủ của bạn. Chúng tôi phát hiện ra rằng không nên sử dụng các thẻ sự kiện như <body onload="doSomething()"> mà bạn nên kích hoạt mã javascript của mình như chúng tôi đã làm trong ví dụ ở trên.

+1

Tôi có thiếu câu hỏi không? Hay đây có phải là câu trả lời để tìm câu hỏi không? –

+0

cũng câu hỏi được trả lời trực tiếp =) – notsure

+0

Điểm mấu chốt là _not_ sử dụng 'onload =" doSomething "'. Tất cả các ví dụ tôi đã nhìn thấy đã sử dụng cách tiếp cận đó và nó không hoạt động. Điều này có. Cảm ơn! – codemonkey

Trả lời

0

Nếu bạn đang sử dụng KnpSnappy làm trình bao bọc của wkhtmltopdf thì bạn có thể thiết lập các tùy chọn khác nhau cho pdf của mình.

xem "Footers Và Headers:" trong tài liệu hướng dẫn wkhtmltopdf, đây http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

[trang] thay thế bởi số lượng các trang hiện đang được in

[toPage] thay thế bởi số lượng trang cuối cùng được in

Sau đây là mẫu của bộ điều khiển Symfony2, kiểm tra chân-html tùy chọn trong mảng $ pdfOptions, nơi tôi ha đã sử dụng cả hai trình giữ chỗ để in số trang ở chân trang của mỗi trang của tệp pdf.

<?php 

namespace Rm\PdfBundle\Controller; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 

/** 
* Pdf controller 
*/ 
class PdfController extends Controller 
{ 
    /** 
    * Serve pdf 
    * 
    * @Route("/article/{slug}", name="rm_pdf_view") 
    * @Method({"GET"}) 
    */ 
    public function viewAction(Request $request, $slug) 
    { 

     // build html 
     $html = $this->renderView('RmPdfBundle:Pdf:view.html.twig', array(
      'data' => $yourDataToTemplate, 
     )); 


     // prepare pdf options 
     $pdfOptions = array(

      'footer-html'  => '<p>Page : [page] of [pageTo]</p>', 

      'footer-font-size' => '10', 
      'page-size'  => 'A4', 
      'orientation'  => 'Portrait', 
      'margin-top'  => 10, 
      'margin-bottom' => 20, 
      'margin-left'  => 15, 
      'margin-right'  => 15, 
      ); 

     // file name of pdf 
     $pdfFileName = "nameOfYourPdfFile.pdf"; 

     // server pdf file to user using knp_snappy.pdf service 
     return new Response(
      $this->get('knp_snappy.pdf')->getOutputFromHtml($html, $pdfOptions), 
      200, 
      array(
       'Content-Type'   => 'application/pdf', 
       'Content-Disposition' => 'attachment; filename="'.$pdfFileName.'"', 
      ) 
     ); 

    } 
} 
Các vấn đề liên quan