Tabel halaman penuh TCPDF

11

Saya mencoba banyak cara untuk membuat tabel agar sesuai dengan halaman (A4) seperti yang ditunjukkan pada gambar: masukkan deskripsi gambar di sini Saya mencari banyak tetapi tidak dapat menemukan sesuatu yang berguna di web. Saya menggunakan tabel dinamis, semuanya ok kecuali lebar tabel. ini kode saya:

$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();
    }

terimakasih banyak

Mohsen Newtoa
sumber
Ini sebenarnya adalah bug di pustaka Html2PDF. Mencari solusi potensial.
EPB
Perlu dicatat, btw, bahwa Html2PDF menggunakan pengurai HTML itu sendiri. style="width: 100%"menyimpan lebar yang dikonversi dengan benar dalam MM (Meskipun atribut lebar tidak!) Namun Html2PDF tampaknya tidak benar-benar menggunakannya selama rendering tabel.
EPB

Jawaban:

4

Html2PDF tidak menggunakan sistem parser / render HTML TCPDF. Itu mengimplementasikannya sendiri, dan implementasinya tidak akan menumbuhkan kolom secara otomatis untuk mengisi 100% dari ruang.

Dengan demikian, di Html2PDF, Anda tidak hanya perlu mengatur lebar 100% di atas meja, tetapi Anda perlu mengatur lebar persentase untuk masing-masing sel. (Dan karena beberapa perilaku aneh dengan widthatribut di Html2PDF, gunakan CSS untuk mengatur lebarnya.)

Asli TCPDF writeHTMLakan mengatur setiap kolom menjadi lebar yang sama tidak ada spesifikasi apa pun sebaliknya. (Misalnya, tabel 4-kolom memiliki semua sel di 25%) Namun, itu tidak mendukung CSS yang Anda gunakan sehingga markup akan membutuhkan sedikit penyesuaian untuk pergi ke rute itu.

Untuk meniru perilaku dasar ini di Html2PDF, Anda bisa menambahkan lebar yang setara ke sel Anda secara eksplisit. Misalnya, menambahkan spesifikasi lebar ke table td, table thaturan gaya Anda .

Berikut ini contoh dengan aturan CSS berikut untuk tabel empat kolom:

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

Tentu saja, ini terlihat paling baik ketika Anda menentukan lebar yang sesuai dengan konten Anda.

Contoh dengan kolom yang setara


MEMPERBARUI

Saya akan meninggalkan beberapa diskusi tentang TCPDF di bawah karena sedikit mengarah pada penciptaan kelas yang berpotensi berguna untuk Html2pdf. TCPDF memiliki beberapa metode yang berguna untuk mengukur panjang string. Jika Anda mengukur ukuran string di dalam kolom, Anda dapat membuat sizer kolom otomatis Anda sendiri.

Saya membuat kelas proof-of-concept di github di https://github.com/b65sol/random-classes

Pertama, kami menggunakan kelas untuk memediasi pembangunan HTML. Ini adalah kelas kolom untuk mengatur lebar yang ditambahkan dan kita tidak perlu menguraikan HTML untuk mengekstraksi konten yang kita ukur.

Maka kita harus memilih beberapa strategi untuk memilih lebar kolom kita. Misalnya, demo di bawah ini mengukur kolom dan menemukan persentase lebar minimum untuk masing-masing berdasarkan kata terpanjang. (Hindari wordbreaks) Kemudian bagikan ruang ekstra apa pun secara proporsional berdasarkan perbedaan antara kata terpanjang dan konten sel penuh terpanjang. Saya tidak akan menyebut produksi ini siap karena ini merupakan konsep bukti, tetapi saya harap Anda (atau pencari lainnya) menemukannya sebagai titik awal yang bermanfaat.

Bagian penting untuk itu di bawah ini adalah ini: $tablebuilder->determine_column_widths_by_minimum_strategy('100%', 'aaa')

Parameter pertama memberi kita referensi ukuran yang sedang kami kerjakan (100% dari halaman karena saya membutuhkan ini untuk membuat pengukuran berguna), dan yang kedua memberikan beberapa karakter padding yang telah ditetapkan untuk ditambahkan ke pengukuran kami untuk memperhitungkan gaya teks dan tabel perbedaan padding.

Berikut ini adalah demo menjalankannya: https://b65sol.com/so/59517311_new.php

Kelas itu sendiri tersedia di sini: https://github.com/b65sol/random-classes

Kode untuk demo itu ada di sini:

<?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();
}

AKHIR PEMBARUAN


Jika Anda memilih untuk tidak menentukan lebar secara eksplisit, Anda bisa menggunakan TCPDF writeHTMLdaripada menggunakan Html2PDFperpustakaan, tetapi semua yang akan dilakukan adalah menggunakan kolom berukuran sama. Saya benar-benar berpikir itu akan melakukan perhitungan ulang ukuran kolom jika Anda hanya menentukan satu atau dua, tetapi saya salah. Selanjutnya, TCPDF menderita beberapa batasan yang sama seperti Html2PDF- jika Anda menentukan ukuran satu kolom, itu tidak akan secara otomatis mengubah ukuran kolom lainnya agar sesuai.

Itu juga tidak ukuran kolom untuk konten seperti browser. Ini sebenarnya cukup sulit untuk dilakukan dengan baik sehingga saya tidak terkejut TCPDF tidak mencobanya. Solusi yang berpotensi rendah upaya adalah memberi tag pada kolom Anda dengan ukuran 'proporsi' dan menghitung lebar dengan cepat untuk masing-masing tergantung pada berapa banyak dari setiap kolom ukuran proporsional yang dipilih. (mis. kolom numerik adalah 'kecil', dan kolom uraian akan 'besar' sehingga memecah dua kolom kecil masing-masing 10% dan satu deskripsi 80%. Dua kolom kecil 5% dan kolom besar 45%) masing-masing. Butuh beberapa percobaan.)

EPB
sumber
terima kasih atas waktu Anda, masalahnya adalah saya menggunakan tabel dinamis ada 10 kolom yang dapat dipilih oleh pengguna, mungkin 5 cols atau 8 cols atau mungkin 2 cols yang opsional ada cara lain yang bisa saya lakukan dan itu adalah : table th, table td { <?=floor(100 / count($cols))?>%;}tapi saya sedang mencari solusi yang lebih baik
Mohsen Newtoa
1
Seberapa berkomitmen Html2PDFAnda? Semua bacaan saya tentang kode dan contoh menunjukkan ini adalah satu-satunya cara. TCPDF dapat melakukan ini dengan parsing CSS yang sedikit kurang mampu, tetapi memiliki sistem tata letak yang lebih baik. Saya dapat menyarankan markup untuk TCPDF lurus.
EPB
Saya mencoba TCPDF dan saya menyadari bahwa mereka menggunakan metode yang sama seperti yang saya gunakan tetapi masih tidak menyelesaikan masalah saya, Jika saya mengubah satu sel itu akan berpengaruh pada sel-sel lain dan lebar tabel masih tidak cocok dengan halaman, perbedaan antara TCPDF dan HTML2PDF adalah bahwa TCPDF menggunakan ukuran tabel default seperti milik sayatable th, table td { <?=floor(100 / count($cols))?>%;}
Mohsen Newtoa
Memang, itulah masalah yang saya temui juga. Saya pikir itu akan memungkinkan saya untuk menentukan ukuran hanya yang spesifik dan secara otomatis menyesuaikan sisanya ketika saya mengatur tes saya (yang sementara tidak ideal akan terlihat cukup bagus dengan sedikit usaha), tetapi tidak ... sama sekali . Saya akan melakukan sedikit lebih banyak penggalian dan melihat apakah ada cara mudah untuk mengukur ukuran kolom secara otomatis. Itu harus menjadi semacam preprocessing meskipun tidak muncul Html2PDFatau TCPDFtampaknya melakukannya di luar kotak.
EPB
Tidak yakin apakah ini memberi tahu Anda tentang pembaruan, tetapi saya menambahkan kelas yang secara dinamis mengukur tabel berbasis teks berdasarkan kontennya. Ada juga strategi yang disebut determine_column_widths_evenlyyang memungkinkan Anda menentukan beberapa ukuran yang diketahui dan mendistribusikannya secara merata ke ruang yang tersisa.
EPB
0

Bekerja dengan sisi server PDF tidak bagus untuk CSS. Sudahkah Anda mencoba menggunakan HTML saja?

Sebagai contoh:

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

Atau Anda dapat mencoba:

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

Berikut adalah CodePen yang menunjukkan ini berfungsi di browser. https://codepen.io/tinacious/pen/PowJRbb

Tina
sumber
Saya mencoba semua ini: <table width="100%"> <table style="width:100%;"> <table class="w100"> <link rel="stylesheet" href="style.css" />tetapi masalahnya adalah, ia bekerja dengan baik pada html tetapi ketika saya ingin menyimpannya sebagai PDF, itu akan seperti gambar.
Mohsen Newtoa
0

gambar: masukkan deskripsi gambar di sini

Saya pikir cara terbaik untuk jenis tabel ini menggunakan cara ini:

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

pada TCPDF mereka belum melakukan sesuatu yang istimewa, tabelnya tidak muat pada halaman.

Mohsen Newtoa
sumber