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

值得一提的是,Html2PDF使用它自己的HTML解析器。style="width: 100%"将正确转换的宽度存储在MM中(尽管width属性没有!),但是Html2PDF在表呈现期间似乎并未真正使用它。
EPB

Answers:


4

Html2PDF不使用TCPDF的HTML解析器/渲染系统。它实现了它自己的实现,并且它的实现不会自动增加列以填充100%的空间。

因此,在Html2PDF中,不仅需要在表格上设置100%的宽度,而且还需要为每个单元格设置百分比宽度。(由于widthHtml2PDF中的属性有些奇怪的行为,请使用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列或8列或2列,这是可选的,我可以用另一种方式来做到这一点, :table th, table td { <?=floor(100 / count($cols))?>%;}但我正在寻找更好的解决方案
Mohsen Newtoa

1
您有多致力于Html2PDF?我对代码和示例的所有阅读都表明这是唯一的方法。TCPDF可以使用功能稍差的CSS解析来实现此目的,但是它具有更好的布局系统。我可以建议直接使用TCPDF的标记。
EPB

我尝试了TCPDF,但我意识到它们使用的方法与我使用的方法相同,但仍然不能解决我的问题,如果我更改一个单元格,它将影响其他单元格,并且表格宽度仍不适合页面, TCPDF和table th, table td { <?=floor(100 / count($cols))?>%;}
HTML2PDF之间的区别

确实,这也是我遇到的问题。我认为这可以让我指定特定尺寸的尺寸,并在设置测试时自动调整其余尺寸(虽然不理想,但稍加努力就可以看起来相当不错),但是根本没有... 。我将做更多的挖掘工作,看看是否有一些省力的方法可以自动调整列的大小。它可能必须是某种预处理,因为Html2PDF要么都不TCPDF做,要么看起来是开箱即用的。
EPB

不知道它是否通知您更新,但是我添加了一个类,该类根据其内容动态调整基于文本的表的大小。还有一种称为的策略determine_column_widths_evenly,可让您指定一些已知的大小并使其均匀地分配剩余空间。
EPB

0

对于CSS,使用PDF的服务器端并不是很好的选择。您是否尝试过仅使用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上,他们没有做任何特别的事情,表无论如何都不适合页面。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.