use PDF::API2;
use PDF::Table;
use Image::Size;
+use File::Basename;
use utf8;
use Encode;
+use JSON::PP;
use Data::Dumper;
my $pdf = PDF::API2->new();
+my $strpdfdata ="";
+my $pdfdata =();
+open(DATA,dirname($0).'/dkspdf.json');
+while (my $l = <DATA>){
+ $strpdfdata .= $l;
+}
+close(DATA);
+$pdfdata = JSON::PP::decode_json($strpdfdata);
#
-use constant mm => 25.4 / 72;
-use constant in => 1 / 72;
-use constant pt => 1;
+# use constant mm => 25.4 / 72;
+# use constant in => 1 / 72;
+# use constant pt => 1;
$pdf->preferences({-fitwindow => 1});
my $fntbold = $pdf->corefont('Helvetica-Bold');
my $fnt = $pdf->corefont('Helvetica');
#
+
my $page = $pdf->page();
$page->mediabox('A4');
+unlink(dirname($0).'/pdftest.pdf');
#height: 842
#width; 595
#
-my $y=755;
-my $x=50;
-my $gfx = $page->gfx();
-my ($iw, $ih) = imgsize('/Users/kilian/Pictures/dks_1000.png');
-my $nimgw = 160;
-my $nimgh = ($nimgw/$iw) * $ih;
-print "New Imagesize: w:".$nimgw." h:".$nimgh."\n";
-$gfx->translate($x,$y);
-my $img = $pdf->image_png('/Users/kilian/Pictures/dks_1000.png');
-$gfx->image($img,0,0,$nimgw,$nimgh);
-
-$gfx->translate(-$x,-$y);
-my $red_line = $page->gfx();
-$red_line->strokecolor('black');
-$red_line->linewidth(1);
-$red_line->move( 50, 753 );
-$red_line->line( 285, 753 );
-$red_line->stroke;
-my $dkstext = $page->text();
-$dkstext->translate(200, 743);
-$dkstext->font($fnt,9);
-$dkstext->text_center('Database Knowledge Solutions - Simplify IT!');
-my $dksfooter = $page->text();
-$dksfooter->translate(297.5, 40);
-$dksfooter->font($fnt,10);
-$dksfooter->text_center('DKS, Société à responsabilité limitée, RC Luxembourg,B168572 - TVA: LU 2537 5617 - No. Aut: 10024550 / 0');
-$dksfooter->translate(297.5, 25);
-$dksfooter->text_center('IBAN: LU25 0020 1100 2783 8700; BIC: BILLLULL');
-
-
-my $adr_line = $page->gfx();
-$adr_line->strokecolor('black');
-$adr_line->linewidth(1);
-$adr_line->move( 52, 662 );
-$adr_line->line( 280, 662 );
-$adr_line->stroke;
-$x=550;
-$y = 820;
-my $fz=11;
-my $txt = $page->text();
- $txt->font($fntbold,$fz);
- $txt->translate($x, $y);
- $txt->text_right('DKS s.à r.l.');
- $txt->font($fnt,$fz);
- $y = $y -$fz-3;
- $txt->translate($x, $y);
- $txt->text_right("8b, rue du Moulin");
- $y = $y -$fz-3;
- $txt->translate($x, $y);
- $txt->text_right("6914 Roodt/Syre");
- $y = $y - (2*($fz+3));
- $txt->translate($x, $y);
- $txt->text_right("Tel: +352 691 504574");
- $y = $y -$fz-3;
- $txt->translate($x, $y);
- $txt->text_right("info\@dks.lu / www.dks.lu");
-#
-$y = $y - (4*($fz+3));
-$txt->translate($x, $y);
-$txt->font($fntbold,30);
-$txt->text_right("Rechnung");
-
-my $pdftbladdress = new PDF::Table;
-my $inv_data3 = [ ["An:"], ["Kilian Saffran"], ["4, rue Principale"], ["L-3770 Tétange"] ];
-
-my $tbl_props3 = { x => 50, w => 230, font => $fnt, font_size => $fz, start_y => 680, start_h => 620, next_y => 750, next_h => 500, padding => 2, padding_bottom => 3, padding_top => 3, padding_right => 5, column_props => [{ min_w => 200, max_w => 200, justify => 'left' }], header_props => [{ font_size => $fz, font => $fntbold, bg_color => 'white', font_color => 'black', repeat => 1, justify => 'left' }], border => 0 };
-my ($lastpage, $tblpages, $final_y) = $pdftbladdress->table($pdf,$page,$inv_data3,%{$tbl_props3});
-
-print $lastpage." - ".$tblpages." - ".$final_y."\n";
-
-my $pdftblinvdata = new PDF::Table;
-
-my $inv_data = [ ["Rechnungs-Nr.","00000000-0000"], ["Datum","00.00.0000"], ["Fälligkeit","00.00.0000"], ["Kunden-Nr.","00000000"], ["Ust-Id","LU 0000 0000"] ];
-
-my $tbl_props2 = {x => 390, w => 175, font => $fnt, font_size => $fz, start_y => 680, start_h => 620, next_y => 750, next_h => 500, padding => 2, padding_bottom => 3, padding_top => 3, padding_right => 5, column_props => [ { min_w => 70, max_w => 70, justify => 'left' }, { min_w => 90, max_w => 90, justify => 'left', font => $fntbold } ], border => 0};
-($lastpage, $tblpages, $final_y) = $pdftblinvdata->table( $pdf, $page, $inv_data, %{$tbl_props2} );
-print $lastpage." - ".$tblpages." - ".$final_y."\n";
-#print Dumper($tbl_props2);
-my $pdftable = new PDF::Table;
-
- my $some_data =[ ["Product / Dienstleistung", "Anzahl","EinzelPreis","Netto-Preis"], ["Computer Installation Donec super long text goes here to provoke a text block Donec super long text goes here to provoke a text block Donec super long text goes here to provoke a text block", "1 Stunde","55,00 €","55,00 €"], ["Computer Installation", "1 Stunde","55,00 €","55,00 €"], ["Computer Installation", "1 Stunde","55,00 €","55,00 €"] ];
- my $tbl_propsm = {x => 50, w => 500, font => $fnt, font_size => $fz, start_y => 570, start_h => 300, next_y => 750, next_h => 500, padding => 2, padding_left => 5, padding_bottom => 10, padding_top => 5, padding_right => 5, header_props => { font_size => $fz, font => $fntbold, bg_color => '#e6e6e6', font_color => 'black', repeat => 1, justify => 'center' }, column_props => [ { }, { min_w => 40, max_w => 40, justify => 'right' }, { min_w => 20, max_w => 20, justify => 'right' }, { min_w => 50, max_w => 50, justify => 'right', font => $fnt } ], border => 0.5};
-
- ($lastpage, $tblpages, $final_y) = $pdftable->table( $pdf, $page, $some_data, %{$tbl_propsm} );
- print $lastpage." - ".$tblpages." - ".$final_y."\n";
-
-my $pdftotalsum = new PDF::Table;
-my $total_data = [ ["Gesamt Netto :","165,00 €"], ["MwSt. (17%) :","28,05 €"], ["Gesamt Brutto :","193,05 €"] ];
-my $tbl_props4 = {x => 349.5, w => 201, font => $fnt, font_size => $fz, start_y => $final_y, start_h => 150, next_y => 750, next_h => 500, padding => 2, padding_left => 5, padding_bottom => 10, padding_top => 5, padding_right => 5, column_props => [ { justify => 'right' }, { min_w => 70, max_w => 70, justify => 'right', font => $fntbold } ], border => 0.5};
-
- ($lastpage, $tblpages, $final_y) = $pdftotalsum->table( $pdf, $page, $total_data, %{$tbl_props4} );
- print $lastpage." - ".$tblpages." - ".$final_y."\n";
-
-$pdf->saveas('/Users/kilian/pdftest.pdf');
+my $endpoints = ();
+foreach my $s (sort keys(%{$pdfdata->{section}})){
+ $endpoints->{$s} = {final_y => '', lastpage => 1,pages => 1};
+ if ($pdfdata->{section}->{$s}->{type} eq "image"){
+ #print "Add Image $s\n";
+
+ $endpoints->{$s}->{y} = &addimage($pdf,$page,$pdfdata->{section}->{$s},$pdfdata->{data}->{$s});
+ } elsif ($pdfdata->{section}->{$s}->{type} eq "line"){
+ #print "Add Line $s\n";
+ $endpoints->{$s}->{y} = &addline($page,$pdfdata->{section}->{$s});
+ } elsif ($pdfdata->{section}->{$s}->{type} eq "text"){
+ #print "Add Text $s\n";
+ $endpoints->{$s}->{y} = &addtext($pdf,$page,$pdfdata->{section}->{$s},$pdfdata->{data}->{$s});
+ } elsif ($pdfdata->{section}->{$s}->{type} eq "table"){
+ #print "Add Table $s\n";
+ ($endpoints->{$s}->{lastpage}, $endpoints->{$s}->{pages}, $endpoints->{$s}->{y}) = &addtable($pdf,$page,$pdfdata->{section}->{$s},$pdfdata->{data}->{$s});
+ }
+}
+
+$pdf->saveas(dirname($0).'/pdftest.pdf');
$pdf->end;
+#Functions
+
+sub addimage(){
+ my $pdf = shift;
+ my $page = shift;
+ my $section = shift;
+ my $data = shift;
+ my $gfx = $page->gfx();
+ my ($iw, $ih) = imgsize($data->{src});
+ my $nimgw = $section->{width};
+ my $nimgh = ($nimgw/$iw) * $ih;
+ #print "New Imagesize: w:".$nimgw." h:".$nimgh."\n";
+ $gfx->translate($section->{x},$section->{y});
+ my $img = $pdf->image_png($data->{src});
+ $gfx->image($img,0,0,$nimgw,$nimgh);
+ $gfx->translate(0,0);
+ $gfx->save;
+ return $nimgh + $section->{y};
+}
+
+sub addline(){
+ my $page = shift;
+ my $section = shift;
+ my $line = $page->gfx();
+ $line->translate($section->{x},$section->{y});
+ $line->strokecolor($section->{color});
+ $line->linewidth($section->{width});
+ $line->move( $section->{start}->{x}, $section->{start}->{y} );
+ $line->line( $section->{end}->{x}, $section->{end}->{y} );
+ $line->stroke;
+ $line->save;
+ return $section->{end}->{y};
+}
+
+sub addtext(){
+ my $pdf = shift;
+ my $page = shift;
+ my $section = shift;
+ my $data = shift;
+
+ my $textobj = $page->text();
+
+ #print "X:".$section->{x}." Y:".$section->{y}."\n";
+ $textobj->translate($section->{x}, $section->{y});
+ $textobj->font($pdf->corefont($section->{font}->{name}),$section->{font}->{size});
+ foreach my $d (@{$data->{text}}){
+ if ($section->{align} eq "center"){
+ $textobj->text_center($d);
+ } elsif ($section->{align} eq "right"){
+ $textobj->text_right($d);
+ } else {
+ $textobj->text($d);
+ }
+ $section->{y} = $section->{y} - $section->{lineheight};
+ $textobj->translate($section->{x}, $section->{y});
+ }
+ $textobj->save;
+ return $section->{y};
+}
+
+sub addtable(){
+ my $pdf = shift;
+ my $page = shift;
+ my $section = shift;
+ my $data = shift;
+ my $pdftbl = new PDF::Table;
+ delete($section->{type});
+ if (exists($section->{font})){
+ $section->{font} = $pdf->corefont($section->{font});
+ }
+ if (exists($section->{start_y})){
+ if ($section->{start_y} =~ /^%%.*%%$/){
+ my ($sec,$k) = $section->{start_y} =~ /^%%(.+):(.+)%%$/;
+ $section->{start_y} = $endpoints->{$sec}->{$k};
+ }
+ }
+ #print "HeadProps\n";
+ if (exists($section->{header_props})){
+ foreach (my $i=0;$i<scalar(@{$section->{header_props}});$i++){
+ my $tmpdata = @{$section->{header_props}}[$i];
+ if (exists($tmpdata->{font})){
+ $tmpdata->{font} = $pdf->corefont($tmpdata->{font});
+ }
+ @{$section->{header_props}}[$i] = $tmpdata;
+ }
+ }
+ #print "ColProps\n";
+ if (exists($section->{column_props})){
+ foreach (my $i=0;$i<scalar(@{$section->{column_props}});$i++){
+ my $tmpdata = @{$section->{column_props}}[$i];
+ if (exists($tmpdata->{font})){
+ $tmpdata->{font} = $pdf->corefont($tmpdata->{font});
+ }
+ @{$section->{column_props}}[$i] = $tmpdata;
+ }
+ }
+ #print Dumper($section);
+ #print ref %{$section}."\n";
+ my ($lastpage, $tblpages, $final_y) = $pdftbl->table($pdf,$page, $data->{text}, %{$section});
+ return ($lastpage, $tblpages, $final_y);
+}
+
--- /dev/null
+{
+ "section":{
+ "12headerimg":{"x":50,"y":755,"width":160,"type":"image"},
+ "02headerline":{"type":"line","color":"black","width":1,"start":{"x":50,"y":753},"end":{"x":285,"y":753}},
+ "03dkstext":{"type":"text","align":"center","font":{"name":"Helvetica","size":9},"x":200,"y":743},
+ "04dksfooter":{"type":"text","align":"center","font":{"name":"Helvetica","size":10},"x":297.5,"y":25,"lineheight":15},
+ "05adrline":{"type":"line","color":"black","width":1,"start":{"x":52,"y":662},"end":{"x":280,"y":662}},
+ "06header_right":{"type":"text","align":"right","font":{"name":"Helvetica","size":11},"x":550,"y":820,"lineheight":14},
+ "07reporttype":{"type":"text","align":"right","font":{"name":"HelveticaBold","size":30},"x":550,"y":704,"lineheight":14},
+ "08tbladdress":{"type":"table","x":"50","w":"230","font":"Helvetica","font_size":"11","start_y":"680","start_h":"620","next_y":"750","next_h":"500","padding":"2","padding_bottom":"3","padding_top":"3","padding_right":"5","column_props":[{ "min_w":"200", "max_w":"200", "justify":"left" }],"header_props":[{ "font_size":"11", "font":"HelveticaBold", "bg_color":"white", "font_color":"black", "repeat":"1", "justify":"left" }],"border":"0"},
+ "09tblinvoicedata":{"type":"table","x":"390","w":"175","font":"Helvetica","font_size":"11","start_y":"680","start_h":"620","next_y":"750","next_h":"500","padding":"2","padding_bottom":"3","padding_top":"3","padding_right":"5","column_props":[ { "min_w":"70","max_w":"70","justify":"left" },{ "min_w":"90","max_w":"90","justify":"left","font":"HelveticaBold" } ],"border":"0"},
+ "10tblproductdata":{"type":"table","x":"50","w":"500","font":"Helvetica","font_size":"11","start_y":"570","start_h":"300","next_y":"750","next_h":"500","padding":"2","padding_left":"5","padding_bottom":"10","padding_top":"5","padding_right":"5","header_props":[{"font_size":"11","font":"HelveticaBold","bg_color":"#e6e6e6","font_color":"black","repeat":"1","justify":"center" }],"column_props":[ { },{ "min_w":"40","max_w":"40","justify":"right" },{ "min_w":"20","max_w":"20","justify":"right" },{ "min_w":"50","max_w":"50","justify":"right","font":"Helvetica" } ],"border":"0.5"},
+ "11totalsums":{"type":"table","x":"349.5","w":"201","font":"Helvetica","font_size":"11","start_y":"%%10tblproductdata:y%%","start_h":"150","next_y":"750","next_h":"500","padding":"2","padding_left":"5","padding_bottom":"10","padding_top":"5","padding_right":"5","column_props":[ { "justify":"right" },{ "min_w":"70","max_w":"70","justify":"right","font":"HelveticaBold" } ],"border":"0.5"}
+ },
+ "data":{
+ "12headerimg":{"src":"/Users/kilian/Pictures/dks_1000.png"},
+ "03dkstext":{"text":["Database Knowledge Solutions - Simplify IT!"]},
+ "04dksfooter":{"text":["DKS, Société à responsabilité limitée, RC Luxembourg,B168572 - TVA: LU 2537 5617 - No. Aut: 10024550 / 0","IBAN: LU25 0020 1100 2783 8700; BIC: BILLLULL"]},
+ "06header_right":{"text":["DKS s.à r.l.","8b, rue du Moulin","6914 Roodt/Syre","Tel: +352 691 504574","info@dks.lu / www.dks.lu"]},
+ "08tbladdress":{"text":[ ["An:"], ["Kilian Saffran"], ["4, rue Principale"], ["L-3770 Tétange"] ]},
+ "07reporttype":{"text":["Rechnung"]},
+ "09tblinvoicedata":{"text":[ ["Rechnungs-Nr.","00000000-0000"], ["Datum","00.00.0000"], ["Fälligkeit","00.00.0000"], ["Kunden-Nr.","00000000"], ["Ust-Id","LU 0000 0000"] ]},
+ "10tblproductdata":{"text":[ ["Product / Dienstleistung", "Anzahl","EinzelPreis","Netto-Preis"], ["Computer Installation Donec super long text goes here to provoke a text block Donec super long text goes here to provoke a text block Donec super long text goes here to provoke a text block", "1 Stunde","55,00 €","55,00 €"], ["Computer Installation", "1 Stunde","55,00 €","55,00 €"], ["Computer Installation", "1 Stunde","55,00 €","55,00 €"] ]},
+ "11totalsums":{"text":[ ["Gesamt Netto :","165,00 €"], ["MwSt. (17%) :","28,05 €"], ["Gesamt Brutto :","193,05 €"] ]}
+ }
+}
\ No newline at end of file