Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print on a specific paper

Tags:

css

printing

I'm having problems with printing some text on a A4 paper that has 24 labels.

Basically, in every row there are 3 labels in which comes the name, surname and adress of a person and that label will be used for mails ( it's a sticky label that is sticked on a mail).

70*36mm cell

So this is the paper. Its characteristics:

  1. There are 10 rows.
  2. The first and last row are the smallest and have height:0.5mm;.
  3. In first and last row there are no cells.
  4. All the rest rows have height:36mm;.
  5. All the cells have width:70mm; and height:36mm;.
  6. In every cell comes a text that is text-align:center; and vertical-align:middle;.

I'm using normalize.css for css reset.

CSS

html,body,table{
  width: 100%;
  height: 100%;
}

.first, .last{
  width: 100%;
  height: 5mm;
}

.row{
  width: 100%;
  height: 36mm;
}

.cell{
  width: 70mm;
  height: 36mm;
  text-align: center;
  vertical-align: middle;
}

I'm using Chrome and I turned off the margins on printing.

But still, the last two rows are printed on the next page. I need all 10 rows on the same page and that their position is fixed ( doesn't shift ) in case if there are multiple pages.

How to fix/achieve that ? Or is there a simpler solution ?

Here is an example of the code.

like image 583
Vucko Avatar asked Nov 03 '22 00:11

Vucko


1 Answers

I've used FPDF class to create a pdf for my labels.

require_once ABSPATH . '/path/to/fpdf.php';


class PDF_MC_Table extends FPDF{
    var $widths;
    var $aligns;

    function SetWidths($w){
        //Set the array of column widths
        $this->widths=$w;
    }   
    function SetAligns($a){
        //Set the array of column alignments
        $this->aligns=$a;
    }   
    function Row($data){
        //Calculate the height of the row
        $nb=0;
        for($i=0;$i<count($data);$i++)
            $nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));
        $h = 36;// again trial and error until you fnd the desired height of your label
        //Issue a page break first if needed
        $this->CheckPageBreak($h);
        //Draw the cells of the row
        for($i=0;$i<count($data);$i++){
            $w=$this->widths[$i];
            $a=isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
            //Save the current position
            $x=$this->GetX();
            $y=$this->GetY();
            //Draw the border. reset the parameters of the function below as you desire.
            $this->Rect($x,$y,$w,$h);
            //Print the text. reset the parameters of the function below as you desire. changing the values will resize the boxs.
            $this->MultiCell($w,3,$data[$i],0,$a);
            //Put the position to the right of the cell. reset the parameters of the function below as you desire. changing the $x and $y will shift the cells.
            $this->SetXY($x+$w,$y);
        }
        //Go to the next line
        $this->Ln($h+3);
    }

    function CheckPageBreak($h){
        //If the height h would cause an overflow, add a new page immediately
        if($this->GetY()+$h>$this->PageBreakTrigger)
            $this->AddPage($this->CurOrientation);
    }

    function NbLines($w,$txt){  
        //Computes the number of lines a MultiCell of width w will take
        $cw=&$this->CurrentFont['cw'];
        if($w==0)
            $w=$this->w-$this->rMargin-$this->x;
        $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
        $s=str_replace("\r",'',$txt);
        $nb=strlen($s);
        if($nb>0 and $s[$nb-1]=="\n")
            $nb--;
        $sep=-1;
        $i=0;
        $j=0;
        $l=0;
        $nl=1;
        while($i<$nb){
            $c=$s[$i];
            if($c=="\n"){
                $i++;
                $sep=-1;
                $j=$i;
                $l=0;
                $nl++;
                continue;
            }
            if($c==' ')
                $sep=$i;
            $l+=$cw[$c];
            if($l>$wmax){
                if($sep==-1){
                    if($i==$j)
                        $i++;
                }
                else
                    $i=$sep+1;
                $sep=-1;
                $j=$i;
                $l=0;
                $nl++;
            }
            else
                $i++;
        }
        return $nl;
    }
}

$pdf=new PDF_MC_Table();
$pdf->SetMargins(4, 2);
$pdf->AddPage();
$pdf->SetFont('Arial','',8);
// displays the empty row in the top
$pdf->SetRightMargin(2);
$pdf->SetLeftMargin(4);
$pdf->Cell(0,10,'',1);
$pdf->Ln(10);

$pdf->SetWidths(array(50,50,50));// these are the widths of your cells. this is a trial and error process. increase the values until you find the suitable ones.

$count = 0;


$lables = array(); // your labels array

$l = array();
$j = 0;

// i used this foreach for breaking my plain array into a 2dimentional array- an array of arrays consisting 3 labels in each.

foreach($lables as $i=>$lbl  ){
    $l[$j][] = $lbl;

    if($i%3==2){$j++;} // $i=0,1,2 > $j=0; $i=3,4,5 > $j=2 etc this will break the main labels array as 2D array.
}
// displays the empty row in the bottom.
$pdf->Ln(1);
    $pdf->Cell(0,10,'',1);

$pdf->Output();

for further information about the class and methods please refer to http://www.fpdf.org/ At best you need to understand three methods- Multicell(), Cell() and Rect() methods. There are pretty nice explanation of these methods with examples in the site.

Here i've posted my solution and i've changed some code based on your problem. Most of the things are self explanatory. If you need further assist please feel free to comment. Thanks.

like image 161
maksbd19 Avatar answered Nov 12 '22 14:11

maksbd19