Текст върху снимка (html,css) генериране на pdf

Ticketa

Registered
Привет,
За около 7 дни изпробвах над 5 продукта (dompdf, tcpdf, mpdf и още два) които ми "бъгват" целият проект.

Проблема се корени в това , че генерирам Х на брой етикети, всеки 1 етикет си има background снимка. Върху снимката обаче генерирам цена(създадена по формули и маржове, тя е променлива)

Стигнах до заключението да използвам HTML+CSS , НО .. нито един от конверторите не позволява пълноценно използването на CSS например функциите position: absolute й position: relative

Вие използвали ли сте подобен инструмент , който поддържа или има опция за "текст" върху точно кординирано място/позиция? Й ако - да, чрез пример кое бихте ми посочили?

Благодаря!

Примерният ми html:
Код:
style>
@page {
   size: 7in 9.25in;
   margin: 27mm 16mm 27mm 16mm;
}
span {position:absolute; top:250px; left:20px; width:200px; height:25px}
</style>
<table  cellpadding="3">
	<tbody>
		<tr style="margin:1px">
			<td style="margin:1px"><IMG SRC="output-onlinepngtools.png">
<span>
19,50
</span></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
	</tbody>
</table>


Пример с tcpdf
Код:
<?php
// Include the main TCPDF library (search for installation path).
require_once('./tcpdf/tcpdf.php');
// include 1D barcode class (search for installation path)
require_once('./tcpdf/tcpdf_barcodes_1d.php');

date_default_timezone_set('Europe/Sofia');

// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 061');
$pdf->SetSubject('');
$pdf->SetKeywords('');
/*
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 061', PDF_HEADER_STRING);

// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(0);
$pdf->SetFooterMargin(0);
*/
//remove header and footer
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// set margins
//$pdf->setTopMargin(10.0);
$pdf->SetLeftMargin(6.0);
$pdf->SetRightMargin(6.00);

$pdf->setHeaderMargin(6.0);
$pdf->SetFooterMargin(6.0); //13mm


// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

// set some language-dependent strings (optional)
//if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
   // require_once(dirname(__FILE__).'/lang/eng.php');
   // $pdf->setLanguageArray($l);
//}

// ---------------------------------------------------------

// set font
$pdf->SetFont('helvetica', '', 10);

// add a page
$pdf->AddPage();

// define some HTML content with style
$html = '
<style>
@page {
   size: 7in 9.25in;
   margin: 27mm 16mm 27mm 16mm;
}
span {position:absolute; top:250px; left:20px; width:200px; height:25px}
</style>
<table  cellpadding="3">
	<tbody>
		<tr style="margin:1px">
			<td style="margin:1px"><IMG SRC="output-onlinepngtools.png">
<span>
19,50
</span></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
		<tr style="margin:1px">
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
			<td style="margin:1px"><img src="output-onlinepngtools.png" alt="Snow"  /></td>
		</tr>
	</tbody>
</table>
';
$pdf->writeHTML($html, true, false, true, false, '');
$pdf->lastPage();

// ---------------------------------------------------------

//Close and output PDF document
$pdf->Output('example_061.pdf', 'I');
 
А защо не генерираш изображение с цената на него?
http://php.net/manual/en/function.imagecopy.php

PHP:
// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('stamp.png');
$im = imagecreatefromjpeg('photo.jpeg');

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Copy the stamp image onto our photo using the margin offsets and the photo 
// width to calculate positioning of the stamp. 
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));

// Output and free memory
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
 
Обмислях го. Но ако имам 400бр етикети по 5 на ред ,
400/5 = 80реда

1 етикет има около 480 px височина или иначе казано около 5см. Това няма ли да бъде твърде голямо изображение :shock:

Използвам този код за създаване на снимка:
Код:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
  //Set the Content Type
  header('Content-type: image/png');

  // Create Image From Existing File
  $jpg_image = imagecreatefrompng('output-onlinepngtools.png');

  // Allocate A Color For The Text
  $white = imagecolorallocate($jpg_image, 255, 255, 255);
  $black = imagecolorallocate($jpg_image, 0, 0, 0);

  // Set Path to Font File
  $font_path = 'arial.ttf';

  // Set Text to Be Printed On Image
  $text = "12,00";

  // Print Text On Image
  imagettftext($jpg_image, 25, 0, 143, 315, $black, $font_path, $text); //настрани , надолу
  
  // Send Image to Browser
  imagejpeg($jpg_image);

  // Clear Memory
  imagedestroy($jpg_image);
?>

Проблема , е че не мултиплицира етикета до 5 на ред и да прехвърля на нов ред. Трябва да бъдат до максимум 25 на страница тъй като ще се принтират на A4 лист

Където е: 143, 315 са координаторите върху етика с цената
 
Направих го , чрез HTML + css (но след като завърша ще тествам при принтиране как ще излиза).

Но имам един бъг. Например имам 90 броя етикети, чрез функцията calculate_columns (за която помогна колега от туриста) разделям на 4 равни части бройките (например: 22, 24, 22, 22)
В случая , аз имам лимит на страница ДО 20 етикета, а моя код продължава да "натрупва" , как може да се направи когато стигне 20броя , просто да създаде нова страница?

Сега към момента вземам общия брой(например:90 разделям го на 4 и получавам колко страници ми трябват, и започвам да ги пълня)

Явно логиката ми е грешна и трябва първо да вземам колко са бройките след деленето (например: 22, да ги разделя на 4 и да получа 1.1 и да създам 2 страници) и след това да ги запълвам?

Някой може ли да удари рамо?
PHP:
<?php
$mysqli = new mysqli('localhost', 'USER', 'pass', 'DB');
/* check connection */
if ($mysqli->connect_errno) {
   printf("Connect failed: %s\n", $mysqli->connect_error);
   exit();
}
$mysqli->set_charset("utf8");

/* разделяме на 4 и правиме второто число да компенсира остатъка */
function calculate_columns(int $total, int $size, int $prefer = 1): array {
    $columns = [];
    for ($i = 0; $i < $size; $i++) {
        $columns[$i] = floor($total / $size);
    }
    $columns[$prefer] += $total - $columns[$prefer] * $size;
    return $columns;
    /*
     Array ( 
         [0] => 22 
         [1] => 24 
         [2] => 22 
         [3] => 22 
     ) 
     */
}
?><html>
    <head>
        <style>body {
  background: rgb(204,204,204); 
}
page {
  background: white;
  display: block;
  margin: 0 auto;
  margin-bottom: 0.5cm;
  box-shadow: 0 0 0.5cm rgba(0,0,0,0.5);
}
page[size="A4"] {  
  width: 21cm;
  height: 29.7cm; 
}
page[size="A4"][layout="landscape"] {
  width: 29.7cm;
  height: 21cm;  
}
page[size="A3"] {
  width: 29.7cm;
  height: 42cm;
}
page[size="A3"][layout="landscape"] {
  width: 42cm;
  height: 29.7cm;  
}
page[size="A5"] {
  width: 14.8cm;
  height: 21cm;
}
page[size="A5"][layout="landscape"] {
  width: 21cm;
  height: 14.8cm;  
}
@media print {
  body, page {
    margin: 0;
    box-shadow: 0;
  }
}

/* Container holding the image and the text */
.container {
  position: relative;
  text-align: center;
  margin-left:10px;
  color: #000 ;
  font-size:19px !important;
  font-weight: bold; font: arial;
}

/* Centered text */
.centered {
  position: absolute;
  top: 70%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin-left:6px;
  
}</style>
<script>
  //window.print();
</script>
</head>
<body>
<?php
$lstoutput = array();
$sqlquery = $mysqli->query("SELECT * FROM items WHERE id=1");
while($row = $sqlquery->fetch_array()) {
    $lstoutput[] = $row;
}
//колко броя записи да извади? $lstoutput[0]['broi']; 
    $labels = calculate_columns($lstoutput[0]['broi'], 4);
    if($lstoutput[0]['margin1'] != null) {
        $page_much = $labels[0]/20;
        $page_number = '0';
        for( ; $page_number < $page_much ; $page_number++){
            echo '<page size="A4"><table cellpadding="6" style="padding-top: 30px"><tbody>';
                $labels_number = 0;
                for ($labels_number = 0; $labels_number <= $labels[0]; $labels_number++) {
                    if ($labels_number %4 === 0) {
                        echo("</tr>\n<tr style='margin:1px'>");
                    }
                    echo '<td style="margin:1px" class="container"><img src="output-onlinepngtools.png" alt="label" style="width:184px;height:224px" /><div class="centered">'.$lstoutput[0]['margin1'].'</div></td>';
                }
            echo '</tbody></table></page>';
        }
    }
/*
<page size="A4"></page>
<page size="A4" layout="landscape"></page>
<page size="A5"></page>
<page size="A5" layout="landscape"></page>
<page size="A3"></page>
<page size="A3" layout="landscape"></page>*/
?>
    </body>
</html>
 
Но имам един бъг. Например имам 90 броя етикети, чрез функцията calculate_columns (за която помогна колега от туриста) разделям на 4 равни части бройките (например: 22, 24, 22, 22)
В случая , аз имам лимит на страница ДО 20 етикета, а моя код продължава да "натрупва" , как може да се направи когато стигне 20броя , просто да създаде нова страница?

Сега към момента вземам общия брой(например:90 разделям го на 4 и получавам колко страници ми трябват, и започвам да ги пълня)

Явно логиката ми е грешна и трябва първо да вземам колко са бройките след деленето (например: 22, да ги разделя на 4 и да получа 1.1 и да създам 2 страници) и след това да ги запълвам?

Имаш 90 етикета, които разпределяш в страници с по 4 колони по 20 етикета.

PHP:
$columns = 4;
$column_height = 20;
Тогава етикетите за една страница са 4*20 = 80

PHP:
$labels_per_page = $columns * $column_height;

А броят страници е броят на всички етикети, разделен на броя етикети на страница, закръглено нагоре: roundUp(90 / 80) = 2

PHP:
$page_count = $all_labels / $labels_per_page;
 
Всъщност са 5 реда , на 4 колони, например:

label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label

----- какво трябва да се случи, ако броя етикети е например 22 -------

label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
---- нова страница -------
label | label
---- край -------

----- какво трябва да се случи, ако броя етикети е например 45 -------
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
---- нова страница -------
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
label | label | label | label
---- нова страница -------
label | label | label | label
label
---- край -------




Ако следвам твоята логика, как би трябвало да изглежда?

PHP:
$columns = 4;
$rows = 5;
$column_height = 20;
Тогава етикетите за една страница са 4*5*20 = 400

PHP:
$labels_per_page = $columns * $rows * $column_height;

roundUp(90 / 400) = 2

PHP:
$page_count = $all_labels / $labels_per_page;

:shock:
 
PHP:
$rows = 5;
$columns = 4;

$labels_per_page = $rows * $columns; // 20

Ти дава колко най-много искаш на страница.

PHP:
$total_labels = 400;
$total_pages = ceil($total_labels / $labels_per_page); 

// Резултат: 400 / 20 = 20



$total_labels = 90;
$total_pages = ceil($total_labels / $labels_per_page);

// Резултат: 90 / 20 = 4.5 -> ceil(4.5) = 5 страници

Как вече ще си създадеш страницирането, ти си знаеш.
 
Опитах и с този вариант , но не успявам да наглася страницирането: Успешно се създават страниците, редовете и колоните, но имам проблем с контролирането на информацията, която трябва да се попълни т.е. общия брой етикети с различната цена.
(24бр - 7.40
(22бр - 6.50
(22бр - 3.90
(22бр - 4.85
----
Общо 5 страници (с 90 етикета)

Код:
<?php
    $ii = 0;
    for($ii =1; $ii<=2; $ii++){ //създаваме страниците
    echo '<table border="1">';
		$i = 0;
		for($i =1; $i<=5; $i++){ //създаваме редовете
			echo '<tr>'; //<td><img src="asd" alt="label" /></td>
				$x = 0;
				for($x=1; $x<=4; $x++){ //създаваме колоните
					$y = $x + $i;
					$z = ($y>5) ? $y-5 : $y;
					echo '<td><img src="output-onlinepngtools.png" width="200px" height="150px" alt="label" /></td>';
				}
			echo '</tr>';
		}
    echo '</table>';
    }
?>



Получавам някакво страшно разминаване между това , което искам и това което е в реалност (играя си от тази сутрин....)

Какво искам:
http://web-tourist.net/userfiles/7/6914.png

Какво е реално:
http://web-tourist.net/userfiles/7/6913.png

Ужас направо.
Код:
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
/* check connection */
if ($mysqli->connect_errno) {
   printf("Connect failed: %s\n", $mysqli->connect_error);
   exit();
}
$mysqli->set_charset("utf8");

/* разделяме на 4 и правиме второто число да компенсира остатъка */
function calculate_columns(int $total, int $size, int $prefer = 1): array {
    $columns = [];
    for ($i = 0; $i < $size; $i++) {
        $columns[$i] = floor($total / $size);
    }
    $columns[$prefer] += $total - $columns[$prefer] * $size;
    return $columns;
    /*
     Array ( 
         [0] => 22 
         [1] => 24 
         [2] => 22 
         [3] => 22 
     ) 
     */
}
?><html>
    <head>
        <style>body {
  background: rgb(204,204,204); 
}
page {
  background: white;
  display: block;
  margin: 0 auto;
  margin-bottom: 0.5cm;
  //box-shadow: 0 0 0.5cm rgba(0,0,0,0.5);
}
page[size="A4"] {  
  width: 21cm;
  height: 29.7cm; 
}
page[size="A4"][layout="landscape"] {
  width: 29.7cm;
  height: 21cm;  
}
page[size="A3"] {
  width: 29.7cm;
  height: 42cm;
}
page[size="A3"][layout="landscape"] {
  width: 42cm;
  height: 29.7cm;  
}
page[size="A5"] {
  width: 14.8cm;
  height: 21cm;
}
page[size="A5"][layout="landscape"] {
  width: 21cm;
  height: 14.8cm;  
}
@media print {
  body, page {
    margin: 0;
    box-shadow: 0;
  }
}

/* Container holding the image and the text */
.container {
  position: relative;
  text-align: center;
  margin-left:10px;
  color: #000 ;
  font-size:19px !important;
  font-weight: bold; font: arial;
}

/* Centered text */
.centered {
  position: absolute;
  top: 70%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin-left:6px;

}


.A4 {
  background: white;
  width: 21cm;
  height: 29.7cm;
  display: block;
  margin: 0 auto;
  padding: 10px 25px;
  margin-bottom: 0.5cm;
  box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
  overflow-y: scroll;
  box-sizing: border-box;
  font-size: 12pt;
}

@media print {
  .page-break {
    display: block;
    page-break-before: always;
  }
  size: A4 portrait;
}

@media print {
  body {
    margin: 0;
    padding: 0;
  }
  .A4 {
    box-shadow: none;
    margin: 0;
    width: auto;
    height: auto;
  }
  .noprint {
    display: none;
  }
  .enable-print {
    display: block;
  }
}


</style>
<script>
  //window.print();
</script>
</head>
<body>
<?php
$lstoutput = array();
$sqlquery = $mysqli->query("SELECT * FROM items WHERE id=1");
while($row = $sqlquery->fetch_array()) {
    $lstoutput[] = $row;
}
$rows = 5;
$columns = 4;
$labels_per_page = $rows * $columns; // 20
$total_labels = $lstoutput[0]['broi'];
$total_pages = ceil($total_labels / $labels_per_page); 
// Резултат: 90 / 20 = 4.5 -> ceil(4.5) = 5 страници

    $labels = calculate_columns($lstoutput[0]['broi'], 4);
        $page_number = '0';
        for(; $page_number < $total_pages ; $page_number++){ //създаваме нужното количество страници
            echo '<page size="A4"><table cellpadding="6" style="padding-top: 30px"><tbody>';
            if($lstoutput[0]['price1'] != null) { //вземаме първата цена
                $labels_number = 0;
                for ($labels_number = 0; $labels_number <= $labels[0]; $labels_number++) {
                    if ($labels_number %4 === 0) {
                        echo("</tr>\n<tr style='margin:1px'>");
                    }
                    echo '<td style="margin:1px" class="container"><img src="label.png" alt="label" style="border:1px solid #333;width:184px;height:184px" /><div class="centered">'.$lstoutput[0]['price1'].'</div></td>';
                }
            }
            if($lstoutput[0]['price2'] != null) { //вземаме втората цена
                $labels_number = 0;
                for ($labels_number = 0; $labels_number <= $labels[1]; $labels_number++) {
                    if ($labels_number %4 === 0) {
                        echo("</tr>\n<tr style='margin:1px'>");
                    }
                    echo '<td style="margin:1px" class="container"><img src="label.png" alt="label" style="border:1px solid #333;width:184px;height:184px" /><div class="centered">'.$lstoutput[0]['price2'].'</div></td>';
                }
            }
            echo '</tbody></table></page>';
        }
?>
    </body>
</html>
 
Голямо мазало. Трудно може да се проследи кода.

На първо четене, в кода ти няма никакво странициране. Ако извеждаш нещата от базата данни използвай LIMIT клазуата и задавай офсет + по колко записа на страница да са:

[sql]
SELECT ... FROM ... WHERE ... LIMIT $offset, $perPage
[/sql]

Офсета ти се пресмята:

PHP:
$perPage = $rows * $columns; // според твоя код 20


$currentPage= $_GET['page']; // 1

$offset = ($currentPage * $perPage) - $perPage;
// (1 * 20) - 20 = 0

// SQL: SELECT ... FROM ... WHERE ... LIMIT $offset, $perPage;
// При зададения офсет се взима записа "офсета + 1".
// Т.е. при офсет 0, започваш от запис 1 (който е върнат от заявката)

$currentPage= $_GET['page']; // 2

$offset = ($currentPage * $perPage) - $perPage;
// (2 * 20) - 20 = 20
// При заявка с офсет 20, ще ти изкара записите от 21 нататък

Това, което се иска от теб е да си създадеш списъка с броя страници, които са ти нужни (пресметнато), да подадеш линк със зададен параметър за пореден номер на страница (да речем: ?page=1, ?page=2) и според тези данни просто пре-пресмятай какво е нужно да върнеш.

Разгледай в интернет как се прави странициране и внимавай с него.
 
Това , което исках е да имитирам PDF файл , а не да създам странициране , поне не от типа на ?page= (което го умея) Благодаря.

Направих го по следния начин и работи:

PHP:
<?php
$mysqli = new mysqli('localhost', 'USER', 'PASS', 'DB');
/* check connection */
if ($mysqli->connect_errno) {
   printf("Connect failed: %s\n", $mysqli->connect_error);
   exit();
}
$mysqli->set_charset("utf8");

/* разделяме на 4 и правиме второто число да компенсира остатъка */
function calculate_columns(int $total, int $size, int $prefer = 1): array {
    $columns = [];
    for ($i = 0; $i < $size; $i++) {
        $columns[$i] = floor($total / $size);
    }
    $columns[$prefer] += $total - $columns[$prefer] * $size;
    return $columns;
    /*
     Array ( 
         [0] => 22 
         [1] => 24 
         [2] => 22 
         [3] => 22 
     ) 
     */
}
?><html>
    <head>
        <style>body {
  background: rgb(204,204,204); 
}
page {
  background: white;
  display: block;
  margin: 0 auto;
  margin-bottom: 0.5cm;
  //box-shadow: 0 0 0.5cm rgba(0,0,0,0.5);
}
page[size="A4"] {  
  width: 22cm;
  height: 30.7cm; 
}
page[size="A4"][layout="landscape"] {
  width: 30.7cm;
  height: 22cm;  
}
page[size="A3"] {
  width: 30.7cm;
  height: 42cm;
}
page[size="A3"][layout="landscape"] {
  width: 42cm;
  height: 30.7cm;  
}
page[size="A5"] {
  width: 14.8cm;
  height: 22cm;
}
page[size="A5"][layout="landscape"] {
  width: 22cm;
  height: 14.8cm;  
}
@media print {
  body, page {
    margin: 0;
    box-shadow: 0;
  }
}

/* Container holding the image and the text */
.container {
  position: relative;
  text-align: center;
  margin-left:12px;
  color: #000 ;
  font-size:19px !important;
  font-weight: bold; font: arial;
}

/* Centered text */
.centered {
  position: absolute;
  top: 70%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin-left:8px;
  
}



</style>
<script>
  //window.print();
</script>
</head>
<body>
<?php
$nID = isset($_GET['NID']) ? (int)$_GET['NID'] : 0;
$lstoutput = array();
$sqlquery = $mysqli->query("SELECT * FROM items WHERE id=".$nID."");
while($row = $sqlquery->fetch_array()) {
    $lstoutput[] = $row;
}
//колко броя записи да извади? $lstoutput[0]['broi']; 
    $labels = calculate_columns($lstoutput[0]['broi'], 4);
    
            echo '<page size="A4"><table cellpadding="5"><tbody>';
                $labels_number = 0; //създаваме първа страница
                
                for ($labels_number = 1; $labels_number <= $lstoutput[0]['broi']; $labels_number++) { //създаваме масив с общия брой етикети
                    if($labels[0] >= $labels_number) { //създаваме първата цена с нужното количество етикети
                       $price = $lstoutput[0]['margin1'];
                    } elseif ($labels[0]+$labels[1] >= $labels_number) { //втора цена
                       $price = $lstoutput[0]['margin2'];
                    }elseif ($labels[0]+$labels[1]+$labels[2] >= $labels_number) { //трета цена
                       $price = $lstoutput[0]['margin3'];
                    }elseif ($labels[0]+$labels[1]+$labels[2]+$labels[3] >= $labels_number) { //четвърта цена
                       $price = $lstoutput[0]['margin4'];
                    }
                    if ($labels_number %4 == 1) { //при четири етикета на ред създаваме нов ред
                        echo("</tr><tr style='margin:1px'>");
                    }
                    echo '<td style="margin:1px" class="container"><img src="output-onlinepngtools.png" alt="label" style="width:195px;height:215px" /><div class="centered">'.$price.'</div></td>';
                    if ($labels_number %20 == 0) { //при двайсе(20) етикета създаваме нова страница
                        echo('</tbody></table></page><page size="A4"><table cellpadding="5"><tbody>');
                    }
                }
                
               
                
            echo '</tbody></table></page>';
?>
    </body>
</html>



Все пак, ако някой има предложение как мога да го конвертирам HTML -> към -> PDF без да се развали CSS-а ще е супер.

Този сайт има API (https://pdfcrowd.com/#convert_by_url) , за просто един два файла върши работа, иначе е платено - а щом този сайт може да ми "запамети" CSS - значи е възможно да се конвертира без разваляне на структурата.


Оставам отворена темата, ако някой може да предложи по-добър вариант или съвет относно така създадения код.

Също е оставам отворена , ако някой има идея как да създам HTML 2 PDF , но в състояние с работещ CSS

I thank everyone for the help so far!
 
Ticketa каза:
Това , което исках е да имитирам PDF файл , а не да създам странициране , поне не от типа на ?page= (което го умея) Благодаря.

О-о, не съм разбрал какво се опитваш да направиш. Моя грешка.
 

Горе