Таблица полных страниц TCPDF

11

Я пытался сделать так, чтобы таблица соответствовала странице (А4), как показано на картинке: введите описание изображения здесь я много искал, но не нашел ничего полезного в Интернете. Я использую динамическую таблицу, все в порядке, кроме ширины таблицы. вот мой код:

$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
Кстати, 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% каждый. Это займет некоторые эксперименты.)

EPB
источник
спасибо за ваше время, проблема в том, что я использую динамическую таблицу, есть 10 столбцов, которые могут выбирать пользователи, может быть 5 или 8 столбцов, или, возможно, 2 столбца, это необязательно, есть другой способ сделать это, и это : table th, table td { <?=floor(100 / count($cols))?>%;}но я ищу лучшее решение
Мохсен Ньютоа
1
Насколько вы преданы Html2PDF? Все мои чтения кода и примеров показывают, что это единственный способ. TCPDF может сделать это с немного менее способным синтаксическим анализом CSS, но имеет лучшую систему компоновки. Я могу предложить разметку для прямого TCPDF.
EPB
Я попробовал TCPDF, и я понял, что они используют тот же метод, что и я, но все равно это не решает мою проблему. Если я изменю одну ячейку, это повлияет на другие ячейки, а ширина таблицы все равно не будет соответствовать странице, Различие между TCPDF и HTML2PDF заключается в том, что TCPDF использует размер таблицы по умолчанию, как у меняtable th, table td { <?=floor(100 / count($cols))?>%;}
Мохсен Ньютоа
Действительно, это проблема, с которой я столкнулся. Я думал, что это позволит мне указать размер только определенных и автоматически отрегулировать остальные, когда я настрою свой тест (который, хотя и не идеальный, выглядел бы достаточно хорошо без особых усилий), но это не ... вообще , Я еще немного покопаюсь и посмотрю, есть ли какой-нибудь простой способ автоматического изменения размера столбцов. Он должен быть какой - то предварительной обработки , хотя , как ни 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, он будет как на картинке.
Мохсен Ньютоа
0

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

Я думаю, что лучший способ для этого типа таблиц заключается в следующем:

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

в TCPDF они не сделали ничего особенного, таблица все равно не помещается на странице.

Мохсен Ньютоа
источник