Bảng trang đầy đủ TCPDF


11

Tôi đã thử nhiều cách để làm cho bảng phù hợp với trang (A4) như trong hình: nhập mô tả hình ảnh ở đây Tôi đã tìm kiếm rất nhiều nhưng không thể tìm thấy bất cứ điều gì hữu ích trên web. Tôi đang sử dụng bảng động, mọi thứ đều ổn ngoại trừ chiều rộng của bảng. đây là mã của tôi:

$content = '<table><thead><tr><th class="bg-dark text-white" align="center">#</th><th align="center" class="bg-dark text-white">Code</th><th align="left" class="bg-dark text-white">Description</th><th align="center" class="bg-dark text-white">Item Type</th></tr></thead><tbody><tr style="background-color: #f2f2f2;"><td align="center">1</td><td align="center">1001</td><td align="left">Pofak</td><td align="center">Fixed Price</td></tr><tr ><td align="center">2</td><td align="center">1002</td><td align="left">Ice</td><td align="center">Weight</td></tr><tr style="background-color: #f2f2f2;"><td align="center">3</td><td align="center">1003</td><td align="left">Minoo</td><td align="center">Fixed Price</td></tr><tr ><td align="center">4</td><td align="center">1004</td><td align="left">Bastani</td><td align="center">Fixed Price</td></tr><tr style="background-color: #f2f2f2;"><td align="center">5</td><td align="center">1005</td><td align="left">Chocolate</td><td align="center">Weight</td></tr><tr ><td align="center">6</td><td align="center">1006</td><td align="left">Brush</td><td align="center">Fixed Price</td></tr><tr style="background-color: #f2f2f2;"><td align="center">7</td><td align="center">1007</td><td align="left">Apple</td><td align="center">Weight</td></tr><tr ><td align="center">8</td><td align="center">1008</td><td align="left">Water</td><td align="center">Fixed Price</td></tr><tr style="background-color: #f2f2f2;"><td align="center">9</td><td align="center">1009</td><td align="left">Cleaner</td><td align="center">Fixed Price</td></tr><tr ><td align="center">10</td><td align="center">1001</td><td align="left">Pofak</td><td align="center">Fixed Price</td></tr><tr style="background-color: #f2f2f2;"><td align="center">11</td><td align="center">1002</td><td align="left">Ice</td><td align="center">Weight</td></tr><tr ><td align="center">12</td><td align="center">1003</td><td align="left">Minoo</td><td align="center">Fixed Price</td></tr><tr style="background-color: #f2f2f2;"><td align="center">13</td><td align="center">1004</td><td align="left">Bastani</td><td align="center">Fixed Price</td></tr><tr ><td align="center">14</td><td align="center">1005</td><td align="left">Chocolate</td><td align="center">Weight</td></tr><tr style="background-color: #f2f2f2;"><td align="center">15</td><td align="center">1006</td><td align="left">Brush</td><td align="center">Fixed Price</td></tr></tbody></table>';
$newContent = '
    <style type="text/css">
    table{width:100%;}
    table, table td, table th{
        border-collapse: collapse;
        border: solid 1px #ababab;
    }
    .text-dark, table td{
        color: #343a40;
    }
    .text-white{
        color: #ffffff;
    }
    table td,
    table th {
        font-size: 11px;
        padding: 3px;
        line-height: 1.2;
        font-family:arial;
    }

    .bg-dark {
        background-color: #343a40;
    }
    .bg-secondary {
        background-color: #6c757d;
    }
    .bg-white {
        background-color: #ffffff;
    }
    .text-left {
        text-align: left;
    }
    .text-right {
        text-align: right;
    }
    .text-center {
        text-align: center;
    }
    </style>
    ';
    $newContent .= '<page>'.$content.'</page>';

    try {
        $html2pdf = new Html2Pdf('P', 'A4', 'en', true, 'UTF-8', 5);
        $html2pdf->pdf->SetDisplayMode('real');
        $html2pdf->writeHTML($newContent);
        $PDFName = "ItemLists_".date('Y.m.d_H.i.s').".pdf";
        $html2pdf->output($PDFName, 'I');
    } catch (Html2PdfException $x) {
        $html2pdf->clean();

        $formatter = new ExceptionFormatter($x);
        echo $formatter->getHtmlMessage();
    }

cảm ơn nhiều


Đây thực sự là một lỗi trong thư viện Html2PDF. Nhìn vào một cách giải quyết tiềm năng.
EPB

Đáng chú ý, btw, rằng Html2PDF sử dụng trình phân tích cú pháp HTML của riêng nó. style="width: 100%"lưu trữ độ rộng được chuyển đổi chính xác trong MM (Mặc dù thuộc tính width không!) Tuy nhiên Html2PDF dường như không thực sự sử dụng nó trong quá trình kết xuất bảng.
EPB

Câu trả lời:


4

Html2PDF không sử dụng hệ thống phân tích cú pháp / kết xuất HTML của TCPDF. Nó thực hiện theo cách riêng của mình và việc triển khai sẽ không tự động phát triển các cột để lấp đầy 100% dung lượng.

Như vậy, trong Html2PDF, bạn không chỉ cần đặt chiều rộng 100% trên bảng mà còn cần đặt độ rộng phần trăm cho mỗi ô. (Và do một số hành vi kỳ lạ với widththuộc tính trong Html2PDF, hãy sử dụng CSS để đặt độ rộng.)

Bản địa của TCPDF writeHTMLsẽ đặt mỗi cột có cùng chiều rộng mà không có bất kỳ thông số kỹ thuật nào khác. (Ví dụ: bảng 4 cột có tất cả các ô ở mức 25%) Tuy nhiên, nó không hỗ trợ CSS mà bạn đang sử dụng nên việc đánh dấu sẽ cần một chút điều chỉnh để đi theo lộ trình đó.

Để bắt chước hành vi cơ bản này trong Html2PDF, bạn chỉ cần thêm chiều rộng tương đương vào các ô của mình một cách rõ ràng. Ví dụ: thêm một đặc tả chiều rộng cho table td, table thquy tắc kiểu của bạn .

Dưới đây là một ví dụ với các quy tắc CSS sau đây cho bảng bốn cột:

table { width: 100%; }
table th, table td { width: 25%; }

Tất nhiên, nó trông tốt nhất khi bạn chỉ định chiều rộng phù hợp với nội dung của bạn.

Ví dụ với các cột tương đương


CẬP NHẬT

Tôi sẽ để lại một số cuộc thảo luận về TCPDF bên dưới vì nó phần nào dẫn đến việc tạo ra một lớp có khả năng hữu ích cho Html2pdf. TCPDF có một số phương pháp hữu ích để đo chiều dài của chuỗi. Nếu bạn đo kích thước của các chuỗi bên trong các cột, bạn có thể tạo bộ tạo cột tự động của riêng bạn.

Tôi đã tạo một lớp bằng chứng về khái niệm trên github tại https://github.com/b65sol/random-groupes

Đầu tiên, chúng tôi sử dụng lớp để làm trung gian cho việc xây dựng HTML. Điều này là do các lớp cột để thiết lập độ rộng được thêm vào và chúng tôi không phải phân tích HTML để trích xuất nội dung chúng tôi đang đo.

Sau đó, chúng tôi phải chọn một số chiến lược để chọn độ rộng cột của chúng tôi. Ví dụ: bản demo dưới đây đo các cột và tìm tỷ lệ phần trăm chiều rộng tối thiểu cho mỗi cột dựa trên từ dài nhất. (Tránh bẻ khóa từ) Sau đó phân phối bất kỳ không gian thừa nào theo tỷ lệ dựa trên sự khác biệt giữa từ dài nhất và nội dung ô đầy đủ dài nhất. Tôi sẽ không gọi sản phẩm này là sẵn sàng vì nó là một bằng chứng khái niệm, nhưng tôi hy vọng bạn (hoặc những người tìm kiếm khác) thấy nó là điểm khởi đầu hữu ích.

Phần quan trọng cho điều đó dưới đây là: $tablebuilder->determine_column_widths_by_minimum_strategy('100%', 'aaa')

Tham số đầu tiên cung cấp cho chúng tôi tham chiếu kích thước mà chúng tôi đang làm việc (100% trang vì tôi cần điều này để làm cho các phép đo trở nên hữu ích) và lần thứ hai cung cấp một số ký tự đệm đặt sẵn để thêm vào các phép đo của chúng tôi để tính toán cho kiểu văn bản và bảng khác biệt đệm.

Đây là bản demo của nó đang chạy: https://b65sol.com/so/59517311_new.php

Bản thân lớp học có sẵn ở đây: https://github.com/b65sol/random- classes

Mã cho bản demo đó là ở đây:

<?php
require 'vendor/autoload.php';
include 'random-classes/html2pdf-full-table-optimizer.php';
use Spipu\Html2Pdf\Html2Pdf;

//First let's build a random table!
$wordlist = ['Chocolate', 'Cake', 'Brownies', 'Cupcakes', 'Coreshock', 'Battery', 'Lead', 'Acid', 'Remilia'];
$wordlist2 = ['Reinforcement Learning', 'Initial Latent Vectors', 'Bag-of-Words', 'Multilayer Perceptron Classifier',
  'Deconvolutional Neural Network', 'Convolutional Neural Network'];
$number_of_columns = rand(3,11);
$number_of_rows = rand(8, 15);
$possible_column_names = ['Unit', 'Description', 'Variable', 'Moon', 'Cheese', 'Lollipop', 'Orange', 'Gir', 'Gaz', 'Zim', 'Dib'];
$possible_column_content_generators = [
  function() {return rand(10,100); },
  function() {return rand(1000, 1999); },
  function() use ($wordlist) {return $wordlist[rand(0, count($wordlist)-1)]; },
  function() use ($wordlist) {return $wordlist[rand(0, count($wordlist)-1)] . ' '. $wordlist[rand(0, count($wordlist)-1)];},
  function() use ($wordlist2) {return $wordlist2[rand(0, count($wordlist2)-1)];},
];

shuffle($possible_column_names);
$list_of_generators = [];
$column_classes = [];
$column_names = [];
for($i = 0; $i < $number_of_columns; $i++) {
  $list_of_generators[$i] = $possible_column_content_generators[rand(0, count($possible_column_content_generators)-1)];
  $column_classes[$i] = ['text-left', 'text-right', 'text-center'][rand(0,2)];
  $column_names[$i] = $possible_column_names[$i];
}
//Got our random stuff, onward to generator!

try {
    $html2pdf = new Html2Pdf('P', 'A4', 'en', true, 'UTF-8', 5);
    $html2pdf->pdf->SetDisplayMode('real');
    $tablebuilder = new Html2PdfTableOptimizer($html2pdf->pdf, '11px', 'helvetica');

    //run table builder... using random data for testing.
    for($i = 0; $i < $number_of_columns; $i++) {
      /*Add a header cell, content is the first parameter, CSS class attribute is second.*/
      $tablebuilder->add_header_cell($column_names[$i], $column_classes[$i] . ' bg-dark text-white');
    }

    for($i = 0; $i < $number_of_rows; $i++) {
      //Start a row.
      $tablebuilder->start_data_row();
      for($col = 0; $col < $number_of_columns; $col++) {
        //Add content and our column classes for td elements
        $tablebuilder->add_data_row_cell($list_of_generators[$col](), $column_classes[$col]);
      }
      //End the row.
      $tablebuilder->end_data_row();
    }
    //Get the table HTML.
    $render = $tablebuilder->render_html();

    $newContent = '
      <style type="text/css">
      table{width:100%;}
      table, table td, table th{
          border-collapse: collapse;
          border: solid 1px #ababab;
      }
      .text-dark, table td{
          color: #343a40;
      }
      .text-white{
          color: #ffffff;
      }
      table td,
      table th {
          font-size: 11px;
          padding: 3px;
          line-height: 1.2;
          font-family:arial;
      }

      .bg-dark {
          background-color: #343a40;
      }
      .bg-secondary {
          background-color: #6c757d;
      }
      .bg-white {
          background-color: #ffffff;
      }
      .row-even {
        background-color: #d1d1d1;
      }
      .text-left {
          text-align: left;
      }
      .text-right {
          text-align: right;
      }
      .text-center {
          text-align: center;
      }

      '.$tablebuilder->determine_column_widths_by_minimum_strategy('100%', 'aaa').'

      </style>
      ';
      $newContent .= '<page>'.$render.'</page>';

      if(!empty($_GET['html'])) {
        echo $newContent;
      } else {
        $html2pdf->writeHTML($newContent);
        $PDFName = "ItemLists_".date('Y.m.d_H.i.s').".pdf";
        $html2pdf->output($PDFName, 'I');
      }
} catch (Html2PdfException $x) {
    $html2pdf->clean();

    $formatter = new ExceptionFormatter($x);
    echo $formatter->getHtmlMessage();
}

KẾT THÚC CẬP NHẬT


Nếu bạn không muốn chỉ định rõ ràng độ rộng, bạn có thể sử dụng TCPDF writeHTMLthay vì sử dụng Html2PDFthư viện, nhưng tất cả những gì sẽ làm là sử dụng các cột có kích thước bằng nhau. Tôi thực sự nghĩ rằng nó sẽ thực hiện một số tính toán lại kích thước cột nếu bạn chỉ chỉ định một hoặc hai, nhưng tôi không chính xác. Hơn nữa, TCPDF chịu một số hạn chế tương tự như Html2PDF- nếu bạn chỉ định kích thước của một cột, nó sẽ không tự động thay đổi kích thước các cột khác cho phù hợp.

Nó cũng không kích thước các cột theo nội dung theo cách trình duyệt thực hiện. Điều này thực sự khá khó để làm tốt vì vậy tôi không ngạc nhiên khi TCPDF không thử. Một giải pháp có khả năng nỗ lực thấp sẽ là gắn thẻ các cột của bạn với kích thước 'tỷ lệ' và tính toán độ rộng khi đang bay tùy thuộc vào số lượng mỗi cột có kích thước tỷ lệ được chọn. (ví dụ: các cột số là 'nhỏ' và một cột mô tả sẽ là 'lớn' và do đó, nó phá vỡ hai cột nhỏ ở mức 10% mỗi cột và một mô tả duy nhất ở mức 80%. Hai cột nhỏ ở mức 5% và cột lớn ở mức 45% mỗi. Nó sẽ mất một số thử nghiệm.)


cảm ơn vì thời gian của bạn, vấn đề là tôi đang sử dụng bảng động có 10 cột mà người dùng có thể chọn, có thể là 5 cols hoặc 8 cols hoặc có thể là 2 cols đó là một cách khác mà tôi có thể làm được và đó là : table th, table td { <?=floor(100 / count($cols))?>%;}nhưng tôi đang tìm kiếm một giải pháp tốt hơn
Mohsen Newtoa

1
Làm thế nào cam kết với Html2PDFbạn là? Tất cả việc tôi đọc mã và các ví dụ cho thấy đây là cách duy nhất. TCPDF có thể làm điều này với phân tích cú pháp CSS có khả năng kém hơn một chút, nhưng nó có hệ thống bố cục tốt hơn. Tôi có thể đề xuất đánh dấu cho TCPDF thẳng.
EPB

Tôi đã thử TCPDF và tôi nhận ra rằng họ sử dụng cùng một phương pháp như tôi sử dụng nhưng vẫn không giải quyết được vấn đề của tôi, Nếu tôi thay đổi một ô, nó sẽ ảnh hưởng đến các ô khác và chiều rộng của bảng vẫn không vừa với trang, điểm khác biệt giữa TCPDF và HTML2PDF là TCPDF đang sử dụng kích thước bảng mặc định giống như của tôitable th, table td { <?=floor(100 / count($cols))?>%;}
Mohsen Newtoa

Thật vậy, đó là vấn đề tôi gặp phải. Tôi nghĩ rằng nó sẽ cho phép tôi chỉ định kích thước của những cái cụ thể và tự động điều chỉnh phần còn lại khi tôi thiết lập thử nghiệm của mình (trong khi không lý tưởng sẽ trông khá hợp lý với ít nỗ lực), nhưng nó hoàn toàn không ... . Tôi sẽ đào sâu thêm một chút và xem liệu có cách nào để nỗ lực tự động kích thước các cột không. Nó sẽ phải là một số loại tiền xử lý mặc dù không Html2PDFhoặc có TCPDFvẻ như làm điều đó ra khỏi hộp.
EPB

Không chắc chắn nếu nó thông báo cho bạn các bản cập nhật, nhưng tôi đã thêm một lớp có kích thước động các bảng dựa trên văn bản dựa trên nội dung của chúng. Ngoài ra còn có một chiến lược được gọi là determine_column_widths_evenlycho phép bạn chỉ định một vài kích thước đã biết và phân bổ đều cho không gian còn lại.
EPB

0

Làm việc với phía máy chủ của PDF không tốt cho CSS. Bạn đã thử chỉ sử dụng HTML?

Ví dụ:

<table width="100%">
  <!-- your table code -->
</table>

Ngoài ra, bạn có thể thử:

<table style="width: 100%;">
  <!-- your table code -->
</table>

Đây là CodePen thể hiện điều này hoạt động trong trình duyệt. https://codepen.io/tinkish/pen/PowJRbb


Tôi đã thử tất cả những thứ này: <table width="100%"> <table style="width:100%;"> <table class="w100"> <link rel="stylesheet" href="style.css" />nhưng vấn đề là nó hoạt động tốt trên html nhưng khi tôi muốn lưu nó dưới dạng PDF thì nó sẽ giống như hình.
Mohsen Newtoa

0

bức tranh: nhập mô tả hình ảnh ở đây

Tôi nghĩ rằng cách tốt nhất cho loại bảng này là sử dụng cách này:

table th, table td { width:<?=floor(100 / count($cols))?>%;}

trên TCPDF họ chưa làm gì đặc biệt, dù sao thì bảng cũng không vừa trên trang.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.