Повна сторінка TCPDF


11

Я спробував багато способів зробити так, щоб таблиця підходила до сторінки (A4), як показано на малюнку: введіть тут опис зображення я багато шукав, але не зміг знайти нічого корисного в Інтернеті. Я використовую динамічну таблицю, все нормально, крім ширини таблиці. ось мій код:

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

дуже дякую


Це насправді помилка в бібліотеці Html2PDF. Вивчення потенційного рішення.
EPB

Варто зазначити, btw, що Html2PDF використовує власний HTML-аналізатор. style="width: 100%"зберігає правильно перетворену ширину в MM (хоча атрибут width не робить!) Однак Html2PDF фактично не використовує її під час візуалізації таблиці.
EPB

Відповіді:


4

Html2PDF не використовує HTML-парсер / рендеринг системи TCPDF. Він реалізує свою власну, і її реалізація не збільшуватиме стовпці автоматично, щоб заповнити 100% місця.

Таким чином, у Html2PDF не тільки потрібно встановити 100% ширину на таблиці, але потрібно встановити відсоткові ширини для кожної з комірок. (І через деяку дивну поведінку з widthатрибутом у Html2PDF, використовуйте CSS для встановлення ширини.)

Рідний TCPDF writeHTMLвстановить, що кожен стовпець буде однакової ширини, відсутні будь-які технічні характеристики в іншому випадку. (Наприклад, у таблиці 4-стовпців усі клітинки мають 25%) Однак вона не підтримує CSS, який ви використовуєте, тому для розмітки потрібно буде трохи змінити цей маршрут.

Щоб імітувати цю основну поведінку в Html2PDF, ви можете просто додати еквівалентні ширини до своїх комірок. Наприклад, додавання специфікації ширини до table td, table thправил стилю.

Ось приклад із наведеними нижче правилами CSS для таблиці з чотирма стовпцями:

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

Звичайно, найкраще це виглядає, коли ви задаєте ширину, яка відповідає вашому вмісту.

Приклад з еквівалентними стовпцями


ОНОВЛЕННЯ

Я залишу трохи з дискусії про TCPDF нижче, оскільки це дещо призведе до створення потенційно корисного класу для Html2pdf. TCPDF має деякі корисні методи вимірювання довжини рядка. Якщо ви вимірюєте розмір рядків всередині стовпців, ви можете створити власний автоматичний розмір стовпців.

Я створив клас підтвердження концепції на github на https://github.com/b65sol/random-classes

По-перше, ми використовуємо клас для опосередкування побудови HTML. Це так, що класи стовпців для встановлення ширини додаються, і нам не потрібно розбирати HTML, щоб витягувати вміст, який ми вимірюємо.

Тоді ми повинні вибрати якусь стратегію вибору ширини нашого стовпця. Наприклад, демонстрація нижче демонструє стовпці і знаходить мінімальні відсотки ширини для кожного на основі найдовшого слова. (Уникає розривів слів) Потім розподіляє будь-який додатковий простір пропорційно на основі різниці між найдовшим словом та найдовшим вмістом повної комірки. Я б не назвав це виробництво готовим, оскільки це підтвердження концепції, але я сподіваюся, що ви (або інші шукачі) знайдете це як корисну вихідну точку.

Ключова частина цього нижче: $tablebuilder->determine_column_widths_by_minimum_strategy('100%', 'aaa')

Перший параметр дає нам посилання на розмір, з яким ми працюємо (100% сторінки, як мені це знадобилось, щоб зробити вимірювання корисними), а другий надає кілька попередньо встановлених символів накладки для додавання до наших вимірювань для врахування стилю тексту та таблиці відмінні відмінності.

Ось демонстрація його роботи: https://b65sol.com/so/59517311_new.php

Сам клас доступний тут: https://github.com/b65sol/random-classes

Код для цієї демонстрації тут:

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

Кінець оновлення


Якщо ви не хочете чітко вказувати ширини, ви можете використовувати TCPDF writeHTMLзамість Html2PDFбібліотеки, але все, що потрібно зробити, це використовувати стовпчики однакового розміру. Насправді я думав, що це зробить певний перерахунок розмірів стовпців, якщо ви вказали лише одну чи дві, але я був невірним. Крім того, TCPDF страждає від тих же обмежень, що і Html2PDFякщо - ви вказали розмір одного стовпця, він не змінить розмір інших стовпців відповідно до розміру.

Він також не розміщує стовпці до вмісту, як це робить браузер. Це насправді досить складно зробити, тому я не здивований, що TCPDF не намагається цього зробити. Можливим рішенням з низькими зусиллями буде тегування стовпців за розміром "пропорція" та обчислення ширини на ходу для кожного залежно від того, скільки вибраних стовпців пропорційного розміру. (наприклад, числові стовпці "малі", а стовпчик з описом був би "великий", і тому він розбиває два маленькі по 10% кожен і один опис на 80%. Два малі на 5% і великі стовпці на 45% кожен. Потрібно було б кілька експериментів.)


дякую за ваш час. Проблема в тому, що я використовую динамічну таблицю. Є 10 стовпців, які користувачі можуть вибрати, можливо, 5 cols або 8 cols або, можливо, 2 cols, що це необов'язково. Є ще один спосіб, що я можу це зробити, і це : table th, table td { <?=floor(100 / count($cols))?>%;}але я шукаю кращого рішення
Mohsen Newtoa

1
Наскільки ви віддані Html2PDF? Усі мої читання коду та прикладів підказують, що це єдиний спосіб. TCPDF може це зробити за допомогою трохи менш здатного розбору CSS, але він має кращу систему компонування. Я можу запропонувати розмітку для прямого TCPDF.
EPB

Я спробував TCPDF і зрозумів, що вони використовують такий же метод, як і я, але все-таки це не вирішує мою проблему. Якщо я зміню одну клітинку, це вплине на інші клітини, і ширина таблиці все ще не підходить до сторінки, різниця між TCPDF і HTML2PDF полягає в тому, що TCPDF використовує розмір таблиці за замовчуванням так само, як у менеtable th, table td { <?=floor(100 / count($cols))?>%;}
Mohsen Newtoa

Справді, це проблема, з якою я також зіткнувся. Я подумав, що це дозволить мені вказати розмір лише конкретних і автоматично відрегулювати решту, коли я налаштував тест (що, хоча це не ідеально, виглядає досить приємно з невеликими зусиллями), але це не ... зовсім . Я ще трохи виконую копання і побачу, чи є якийсь спосіб, який потребує автоматичного розміру стовпців. Це повинно бути якоюсь попередньою обробкою, хоча як і ні, Html2PDFабо, TCPDFздається, робити це поза коробкою.
EPB

Не впевнений, чи повідомляє він вас про оновлення, але я додав клас, який динамічно розміщує текстові таблиці на основі їх вмісту. Існує також стратегія під назвою, determine_column_widths_evenlyяка дозволяє вказати кілька відомих розмірів і дозволяє рівномірно розподілити залишки місця.
EPB

0

Робота з сервером PDF не є чудовою для CSS. Ви спробували використовувати лише HTML?

Наприклад:

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

Можна також спробувати:

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

Ось CodePen, який демонструє це, що працює в браузері. https://codepen.io/tinacious/pen/PowJRbb


Я спробував усе це: <table width="100%"> <table style="width:100%;"> <table class="w100"> <link rel="stylesheet" href="style.css" />але проблема полягає в тому, що він добре працює на html, але коли я хочу зберегти його як PDF, він буде схожий на малюнок.
Mohsen Newtoa

0

фото: введіть тут опис зображення

Я думаю, що найкращим способом для такого типу таблиць є використання цього способу:

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

на TCPDF вони не зробили нічого особливого, таблиця все одно не вміщується на сторінці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.