Tabella TCPDF a pagina intera


11

Ho provato molti modi per adattare la tabella alla pagina (A4) come mostrato nell'immagine: inserisci qui la descrizione dell'immagine ho cercato molto ma non sono riuscito a trovare nulla di utile sul web. Sto usando la tabella dinamica, è tutto ok tranne la larghezza della tabella. ecco il mio codice:

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

grazie molto


Questo è in realtà un bug nella libreria Html2PDF. Esaminare una potenziale soluzione alternativa.
EPB

Vale la pena notare, tra l'altro, che Html2PDF utilizza il proprio parser HTML. style="width: 100%"memorizza la larghezza convertita correttamente in MM (sebbene l'attributo width non lo faccia!) Tuttavia Html2PDF non sembra utilizzarlo effettivamente durante il rendering della tabella.
EPB

Risposte:


4

Html2PDF non utilizza il sistema di analisi / rendering HTML TCPDF. Implementa il proprio e la sua implementazione non farà crescere automaticamente le colonne per riempire il 100% dello spazio.

Pertanto, in Html2PDF, non è solo necessario impostare la larghezza del 100% sulla tabella, ma è necessario impostare larghezze percentuali per ciascuna delle celle. (E a causa di un comportamento strano con l' widthattributo in Html2PDF, usa CSS per impostare le larghezze.)

Il nativo di TCPDF writeHTMLimposterà ogni colonna in modo che abbia la stessa larghezza, altrimenti non ci sono specifiche. (Ad esempio, una tabella a 4 colonne ha tutte le celle al 25%) Tuttavia, non supporta il CSS che stai utilizzando, quindi il markup richiederebbe un piccolo ritocco per percorrere quella strada.

Per imitare questo comportamento di base in Html2PDF, potresti semplicemente aggiungere esplicitamente larghezze equivalenti alle tue celle. Ad esempio, aggiungendo una specifica di larghezza alle table td, table thregole di stile.

Ecco un esempio con le seguenti regole CSS per una tabella a quattro colonne:

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

Certo, sembra migliore quando specifichi larghezze che si adattano al tuo contenuto.

Esempio con colonne equivalenti


AGGIORNARE

Lascerò alcune delle discussioni su TCPDF di seguito in quanto portano in qualche modo alla creazione di una classe potenzialmente utile per Html2pdf. TCPDF ha alcuni metodi utili per misurare la lunghezza di una stringa. Se si misura la dimensione delle stringhe all'interno delle colonne, è possibile creare il proprio ridimensionatore di colonne automatico.

Ho creato una classe di prova di concetto su github su https://github.com/b65sol/random-classes

Innanzitutto, usiamo la classe per mediare la costruzione dell'HTML. In questo modo vengono aggiunte le classi di colonne per l'impostazione delle larghezze e non è necessario analizzare HTML per estrarre il contenuto che stiamo misurando.

Quindi dobbiamo scegliere alcune strategie per selezionare le larghezze delle nostre colonne. Ad esempio, la demo seguente misura le colonne e trova le percentuali di larghezza minima per ciascuna in base alla parola più lunga. (Evita i wordbreaks) Quindi distribuisce lo spazio aggiuntivo proporzionalmente in base alla differenza tra la parola più lunga e il contenuto di cella più lungo. Non definirei pronta questa produzione poiché è una prova di concetto, ma spero che voi (o altri ricercatori) la troviate come un utile punto di partenza.

La parte fondamentale per questo di seguito è questa: $tablebuilder->determine_column_widths_by_minimum_strategy('100%', 'aaa')

Il primo parametro ci fornisce il riferimento alle dimensioni con cui stiamo lavorando (il 100% della pagina in quanto ne avevo bisogno per rendere utili le misurazioni), e il secondo fornisce alcuni caratteri di riempimento predefiniti da aggiungere alle nostre misurazioni per tenere conto dello stile del testo e della tabella differenze di imbottitura.

Ecco una demo in esecuzione: https://b65sol.com/so/59517311_new.php

La classe stessa è disponibile qui: https://github.com/b65sol/random-classes

Il codice per quella demo è qui:

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

FINE AGGIORNAMENTO


Se preferisci non specificare esplicitamente le larghezze, puoi usare i TCPDF writeHTMLinvece di usare la Html2PDFlibreria, ma tutto ciò che farà sarà usare colonne di uguali dimensioni. In realtà pensavo che avrebbe fatto un ricalcolo delle dimensioni delle colonne se ne avessi specificato solo una o due, ma non ero corretto. Inoltre, TCPDF presenta alcune delle stesse limitazioni di Html2PDF- se si specifica la dimensione di una colonna, non ridimensionerà automaticamente le altre colonne per adattarle.

Inoltre non dimensiona le colonne in base al contenuto come fa un browser. In realtà questo è piuttosto difficile da fare bene, quindi non sono sorpreso che TCPDF non ci provi. Una soluzione potenzialmente a basso sforzo sarebbe quella di taggare le colonne con una dimensione "proporzionale" e calcolare le larghezze al volo per ciascuna a seconda di quante colonne di ciascuna dimensione proporzionale sono selezionate. (ad esempio, le colonne numeriche sono "piccole" e una colonna descrittiva sarebbe "grande" e quindi suddivide due piccole al 10% ciascuna e una singola descrizione all'80%. Due piccole al 5% e grandi colonne al 45% ciascuno. Ci vorrebbe un po 'di sperimentazione.)


grazie per il tuo tempo, il problema è che sto usando una tabella dinamica, ci sono 10 colonne che possono essere scelte dagli utenti, forse 5 col o 8 col o forse 2 col che è facoltativo, c'è un altro modo in cui posso farlo ed è : table th, table td { <?=floor(100 / count($cols))?>%;}ma sto cercando una soluzione migliore
Mohsen Newtoa il

1
Quanto Html2PDFsei impegnato con te? Tutta la mia lettura del codice e degli esempi suggerisce che questo è l'unico modo. TCPDF può farlo con l'analisi CSS leggermente meno capace, ma ha un sistema di layout migliore. Posso suggerire markup per TCPDF diretto.
EPB

Ho provato TCPDF e mi sono reso conto che usano lo stesso metodo che uso io ma non risolve ancora il mio problema, se cambio una cella si ripercuoterà sulle altre celle e la larghezza della tabella non si adatta alla pagina, la differenza tra TCPDF e HTML2PDF è che TCPDF utilizza le dimensioni di tabella predefinite proprio come le mietable th, table td { <?=floor(100 / count($cols))?>%;}
Mohsen Newtoa

In effetti, questo è anche il problema che ho riscontrato. Ho pensato che mi avrebbe permesso di specificare la dimensione di quelli specifici e di regolare automaticamente il resto quando ho impostato il mio test (che sebbene non ideale sarebbe abbastanza carino con un piccolo sforzo), ma non ... affatto . Farò un po 'più di scavo e vedrò se c'è un modo semplice per dimensionare automaticamente le colonne. Dovrebbe essere una sorta di pre-elaborazione anche se nessuno dei due Html2PDFo TCPDFsembra farlo fuori dalla scatola.
EPB

Non sono sicuro se ti avvisa degli aggiornamenti, ma ho aggiunto una classe che dimensiona dinamicamente le tabelle basate sul testo in base al loro contenuto. C'è anche una strategia chiamata determine_column_widths_evenlyche ti consente di specificare alcune dimensioni conosciute e di distribuire uniformemente lo spazio rimanente.
EPB

0

Lavorare con il lato server di PDF non è eccezionale per i CSS. Hai provato a usare solo HTML?

Per esempio:

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

In alternativa puoi provare:

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

Ecco una CodePen che dimostra questo funzionamento nel browser. https://codepen.io/tinacious/pen/PowJRbb


Ho provato tutti questi: <table width="100%"> <table style="width:100%;"> <table class="w100"> <link rel="stylesheet" href="style.css" />ma il problema è che funziona perfettamente su HTML ma quando voglio salvarlo come PDF sarà come l'immagine.
Mohsen Newtoa,

0

la foto: inserisci qui la descrizione dell'immagine

Penso che il modo migliore per questo tipo di tabelle sia usare in questo modo:

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

su TCPDF non hanno fatto nulla di speciale, la tabella non si adatta comunque alla pagina.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.