ตารางเต็มหน้า 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 อย่างถูกต้อง (แม้ว่าความกว้างของแอ็ตทริบิวต์จะไม่ได้!) อย่างไรก็ตาม 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%; }

แน่นอนว่ามันดูดีที่สุดเมื่อคุณระบุความกว้างที่เหมาะสมกับเนื้อหาของคุณ

ตัวอย่างที่มีคอลัมน์เทียบเท่า


UPDATE

ฉันจะปล่อยให้บางส่วนของการอภิปรายเกี่ยวกับ 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 พวกเขาไม่ได้ทำอะไรเป็นพิเศษตารางไม่เหมาะกับหน้าอยู่ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.