mpdf table width to fit A4 paper size - html

I have been trying every possible solution to make table fill the width of the A4 paper. I am using mpdf to convert HTML to pdf. But table is never 100% width.
I tried giving width in 100%, 1000px, 180mm but none of them worked. Please Help.
I tried :
<table width="1000px"> //style="width:100%;" or width:180mm or width:100px
</table>
Nothing worked.

It may help to you, customize page from mpdf configuration:
Fullpage example:
include 'MPDF/mpdf.php';
$pdf = new mPDF();
$pdf->ignore_invalid_utf8 = true;
$header ="Header html file or code";
$footer ="Footer html file or code";
$content ="Body html or code";
$pdf->SetDisplayMode('fullpage');
$pdf->SetHTMLHeader($header);
$pdf->SetHTMLFooter($footer);
$pdf->WriteHTML($content); // write the HTML into the PDF
$pdf->Output("pdf/test.pdt", 'F'); // save to file because we can
or you can use custom margin:
include 'MPDF/mpdf.php';
$pdf = new mPDF();
$pdf->ignore_invalid_utf8 = true;
$header ="Header html file or code";
$footer ="Footer html file or code";
$content ="Body html or code";
$pdf->SetHTMLHeader($header);
$pdf->SetHTMLFooter($footer);
$pdf->AddPage('', // L - landscape, P - portrait
'', '', '', '',
15, // margin_left
15, // margin right
30, // margin top
30, // margin bottom
10, // margin header
10 // margin footer
);
$pdf->WriteHTML($content); // write the HTML into the PDF
$pdf->Output("pdf/test.pdt", 'F'); // save to file because we can

Related

Add div to existing pdf laravel [duplicate]

Laravel Package:
"setasign/fpdi": "^2.3",
"setasign/fpdf": "^1.8"
$pdf = new \setasign\Fpdi\Fpdi('L','mm','A4');
$pageCount = $pdf->setSourceFile(public_path().'/'.$url);
$pdf->setFont('Arial', 'B', 10);
for($i = 1; $i <= $pageCount; $i++){
$tplIdx = $pdf->importPage($i);
$pageDimensions = $pdf->getImportedPageSize($tplIdx);
$pdf->addPage($pageDimensions['orientation'], $pageDimensions);
$pdf->useTemplate($tplIdx);
}
If It Possible read the content of the last page and get after page content ordinate of the current position. then Write new content without add new page or whitespaces
If Pdf Generate using DomPdf so you can generate HTML file using
$pdf->getDomPDF()->outputHtml()
Generated html file using DomPDF add some element like this:
<div id="divId"></div>
Then whenever you need to edit this document, you need to read the HTML file line by line and
Edit document:
$url=public_path() .'/test.html';
$htmlFile='';
foreach(file($url) as $key => $line){
if(strpos($line, 'id="divId"') !== false){
$line='<div>Hello world</div>';
}
$htmlFile.=$line;
}
$pdf = PDF::loadHTML($htmlFile)->setPaper('a4', 'landscape');
$pdf->output();

mPDF image to cover page with crop and no distortion

I've tried every conceivable combination of getting something that seems so simple to work.
I need to place an image on a page, A4 (210mm (h) X 297mm (w)) and have that image 100% height, i.e. 297mm, then stretch the width proportionally to that and just crop the overflow (i.e. hidden in css overflow). I've tried every combination I can think of with $mpdf->Image(), or like I've done everywhere else in the PDF file, use pure HTML and CSS. E.g.
<img src="path(to/file.jpg" />
or
<div style="background: url("path(to/file.jpg") center center no-repeat;"></div>
again, with all possible CSS configurations I can think of.
Is it not possible to stretch and image to fit the entire pages height while maintaining the aspect ratio and crop the image on the sides?
I've seen background-image-resize on MPDF full page background, but again, nothing.
How can I get an image to be 100% of the page's height (I don't care if I have to define the height (i.e. 297mm) or if it's a percentage) have the image scale proportionally to that and crop any excess of the image on the sides.
I'm sure I've just missed something obvious here. I can't see what I'm doing wrong (I think I'm stuck in a loop in my head now).
An example of what shows up fine (as expected) if I do an echo and view in the browser
$html = '<div style="
background: url('.$imageSource.') center center no-repeat;
position: absolute;
overflow: hidden;
height: 297mm;
width: 100%;
background-size: cover;
top: 0;
left: 0;
"></div>';
However, doing the same with $pdf->WriteHTML( $html, 2 ) and then $pdf->Output() the image is 297mm in height, but the width is distorted (i.e. it doesn't stretch proportionally to the height).
Here is the resulting PDF (with a placeholder image)
This is what I'm trying to achieve
So the resulting PDF gets "squeezed". Instead of extending the width proportionally to the height (297mm).
PS. Sorry for the lack of actual tested code. But there are just so many different combinations I've tried that I can't reproduce all of them.
PPS. Using latest version of mPDF. Grabbed from GitHub three days ago.
Since I had a lot of problems getting the logic, CSS and math right I thought I'd share my final working solution here with anyone else struggling with this.
Start with the function
function image( $containerWidth, $containerHeight, $imageSource, $top, $left, $border ){
// Get image width
$imageWidth = getimagesize( $imageSource )[0];
// Get image height
$imageHeight = getimagesize( $imageSource )[1];
// Get image aspect ratio
$imageRatio = $imageWidth / $imageHeight;
// Get container aspect ratio
$containerRatio = $containerWidth / $containerHeight;
// Decide if image should increase in height or width
if( $imageRatio > $containerRatio ){
$width = ( ( $imageRatio / $containerRatio ) * 100 );
}else{
$width = ( ( $containerRatio / $imageRatio ) * 100 );
}
if( $border ){
// $border array: 0 = thicknes in points, 1 = type (solid, dotted etc), 2 = color
$border = 'border: '.$border[0].'pt '.$border[1].' '.$border[2].';';
}
return '<div style="position: absolute; top: '.$top.'mm; left: '.$left.'mm; width: '.$containerWidth.'mm; height: '.$containerHeight.'mm; overflow:hidden; margin:0;'.$border.'"><img src="'.$imageSource.'" style="width: '.$width.'%; margin: 0 -'.( ( $width - 100 ) / 2 ).'%;" /></div>';
}
Then for a centered full page image
$image1 = image( 210, 297, $imageSource[0], 0, 0, null );
Or two images on top of each other, one with a white border
$image2 = image( 105, 148, $imageSource[1], 15, 15, null );
$image3 = image( 105, 148, $imageSource[2], 133, 90, [ 10, 'solid', 'white' ] );
Output
// mPDF options array
$pdfOptions = array(
'mode' => 'utf-8',
'format' => 'A4',
'img_dpi' => 300,
'dpi' => 300,
);
// Declare $pdf and set options
$pdf = new \Mpdf\Mpdf( $pdfOptions );
// Stylesheets
$style = file_get_contents( __DIR__ . '/path/to/stylesheet.css');
$pdf->WriteHTML( $style, 1 );
$pdf->WriteHTML( $image1, 2 );
$pdf->AddPage();
$pdf->WriteHTML( $image2, 2 );
$pdf->WriteHTML( $image3, 2 );
$pdf->Output();

Set Page Size in Units with NReco (WkHtmlToPdf)

Is there a way to set print page size in millimeters, like you can with borders, in NReco - the html to pdf wrapper for wkhtmltopdf? Found a way to specify one of four page sizes in the docs, which isn't precise enough.
From reading the wkhtmltopdf docs themselves, it seems like it's also limited to predefined page sizes, rather than setting them manually in units of length.
Making this question in case I am, hopefully, wrong. Need to set page to something 15x10cm for example.
Edit: I am having trouble forcing the library to use the html page settings (as an alternative to not setting anything in the html, and setting height/width/margins in NReco, as shown in my partial answer below). This:
#page {
size: 4in 3in;
margin: 0mm 0mm 0mm 0mm;
}
actually works on print, but when I try to force NReco to use it with:
pdfConverter.CustomWkHtmlArgs = "--print-media-type";
it does nothing. Example is from front page of NReco's site too, which makes it funnier.
Looking at this snippet from the wkhtmltopdf documentation:
--page-height <unitreal> Page height
-s, --page-size <Size> Set paper size to: A4, Letter, etc.
(default A4)
--page-width <unitreal> Page width
I would say that using --page-height and --page-width would do the trick. Logic would say that these will set the page height and width in points, but in fact it is mm. If you need to convert, there are 25.4 mm in an inch, and 72 points in an inch.
Note: I will be editing this answer if I get somewhere, but for now, I guess something is better than nothing for whoever might read this.
Posting an answer that others might find helpful but that isn't the full solution to my problem:
HtmlToPdfConverter pdfConverter = new HtmlToPdfConverter();
//The page width and page height values are in mm
pdfConverter.PageWidth = 102;
pdfConverter.PageHeight = 77;
This should NOT be the accepted answer - for some reason it does NOT fully match simple html sizing. For example, if I create an html document with size ratios of 4x3 and then set these props appropriately, the resulting image on the page still does not take up the entire page (ends up smaller).
If I run the following html and set page sizes to 102 mm x 72mm I get the screenshot below, which is way off despite having the ratios right:
<html>
<head>
<style>
.reportBody {
padding: 0px;
border: 0px;
margin: 0px;
}
.reportTable{
padding: 0px;
border: 0px;
margin: 0px;
width: 102mm;
height: 77mm;
}
</style>
</head>
<body class = "reportBody">
<table class = "reportTable">
<tr>
<td style = "background-color:red">
Row 1 Column 1
</td>
<td style = "background-color:blue">
Row 1 Column 2
</td>
</tr>
<tr>
<td style = "background-color:green">
Row 2 Column 1
</td>
<td style = "background-color:yellow">
Row 2 Column 2
</td>
</tr>
</table>
</body>
</html>
Quick answer to your question is yes, the settings are in mm when you use the height and width properties, so what you are doing is correct with regard to the C# code, your sizing issue is the converter employing a 'smart' resizing technique, which is on by default. The ratio being correct but the dimensions reduced is exactly the same issue I had, which was resolved by the --disable-smart-shrinking option being included.
For a fuller picture:
I've just finished step one of getting prescription printing direct from a new Razor app done, the PDFs being generated via the NReco wrapper. I have to print to a fixed prescription sheet (215mm x 176mm) with a small margin around it. This is the code that I've got in the Controller, which returns the pdf as the fileResult variable.
public async Task<ActionResult> OutputScript(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var model = await GetViewModelForScript(id.Value);
if (model == null)
{
return HttpNotFound();
}
// create a string writer to receive the HTML code
StringWriter stringWriter = new StringWriter();
// get the view to render
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, "Script", null);
// create a context to render a view based on a model
ViewContext viewContext = new ViewContext(
ControllerContext,
viewResult.View,
new ViewDataDictionary(model),
new TempDataDictionary(),
stringWriter
);
// render the view to a HTML code
viewResult.View.Render(viewContext, stringWriter);
// return the HTML code
string htmlToConvert = stringWriter.ToString();
// instantiate the HTML to PDF converter
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();
htmlToPdfConverter.CustomWkHtmlArgs = " --print-media-type --title \"SMS Script " + model.ScriptID + "\" --dpi 300 --disable-smart-shrinking";
htmlToPdfConverter.PageHeight = 215;
htmlToPdfConverter.PageWidth = 176;
var margins = new PageMargins();
margins.Bottom = 4;
margins.Top = 4;
margins.Left = 5;
margins.Right = 5;
htmlToPdfConverter.Margins = margins;
htmlToPdfConverter.Orientation = PageOrientation.Landscape;
// render the HTML code as PDF in memory
byte[] pdfBuffer = htmlToPdfConverter.GeneratePdf(htmlToConvert);
// send the PDF file to browser
FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
fileResult.FileDownloadName = "Script.pdf";
return fileResult;
}
The way it is now all the#media print directives are obeyed, hiding the labels that show on the screen "preview" when the PDF is generated for printing.

HTML to PDF with mpdf table is not centered

I have used mpdf to output some html to a pdf. I am not sure why mpdf is not inserting a top or right margin on the PDF yet the left side seems to have one:
I want to just have the content in the horiztonal center as it is cutting off text on the right. I also want to have a top margin as top content is being cut off.
Here is the settings I have set right now:
$mpdf = new mPDF('win-1252', 'Letter', '', '', 10, '', '', '', '', '');
$mpdf->useOnlyCoreFonts = true;
$mpdf->SetDisplayMode('fullpage');
I switched my declaration to the following:
$mpdf = new mPDF('win-1252','Letter', 12, '', 10, 10, 10, 10);
This correctly set the margins.

chrome not displaying pdf right?

At first i thought TCPDF's GetStringWidth() was not working right, giving me the wrong width:
[----------------------------------------------------------------------------------------------------------------------]
I have some text like $txt = "hallo".
I've tried to get the strings width via the built in function GetStringWidth()
and then create a cell with the strings width.
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setFontSubsetting(true);
$pdf->AddPage();
$pdf->SetFont('times', '', 20);
$pdf->SetCellPadding(0);
$txt = "hey i'm santa clause";
$width = $pdf->GetStringWidth($txt);
$pdf->Cell($width, $h=0, $txt, $border=1, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M');
$pdf->Output('example_001.pdf', 'I');
?>
The created cell however is to short for it's content.
If I try the same with courier it works fine.
I think it's a measure of GetStringWidth not processing the font's width right, cause of Courier having the same width for each character, which works.
How can I get GetStringWidth() working
[----------------------------------------------------------------------------------------------------------------------]
Today I tried opening it with Firefox/Evince instead of chrome
Here's the result:
Firefox is on the left, chrome on the right.
The generated PDF file is v. 1.7
Used version of chrome:
google-chrome-beta (41.0.2272.53-1)
What could have gone wrong here? Is it really chromes fault? Or am I missing somethign here?
Thanks
You must try with replacing:
$pdf->Output("{$filename}.pdf", 'I');
with
$pdf->Output("{$filename}.pdf", 'D');