Viewed   670 times

Ok, so I use the following snippet to get "views" of HTML with PHP variables loaded in as $data so that I can do things like fill in tr's of data from a database call or whatever.

function getView ($file, $data=NULL) {
    if (!empty($data)) extract($data);
    ob_start();
    if (is_file($file)) include($file);
    return ob_get_clean();
}

Gets used for something like, $htmlPDF = getView('receipt.php', array( 'orderNumber' => $orderNumber )); Where $orderNumber is then used in the HTML to fill in it's proper places. For instance something like:

<h1>You Order #<?= $orderNumber; ?></h1>


Ok, so point is, that's how I get my HTML. I then load it to my dompdf variable as:
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();

Which all works great. The problem is getting the inline php script to work to get PAge Numbers / Page Headers|Footers. I've followed the directions here best I can, but I can't seem to make the right blend. Thus far, not having any errors, except I get 0 Page Numbers anywhere!

And yes I've looked at pages like Header in PDF page using DOMPDF in PHP and dompdf page number, but still no forward progress, at all! I'm wondering if the inline php scripting has to do with how I'm getting the HTML as a string? Any pointers, ideas, advice?

 Answers

1

Update Regarding changes with version of dompdf >= 0.7.0
1. Because the dompdf_config.inc.php file has been removed from this release (and is no longer referenced) all dompdf options should be set at run time.
4. The FontMetrics class is now instantiated instead of static. To simplify migration of embedded scripts from earlier versions of dompdf we provide access to the instantiated FontMetrics class via the $fontMetrics variable. Please update your embedded scripts. For example, FontMetrics::get_font('helvetica') would now be $fontMetrics->getFont('helvetica').
~ Thanks to Dennis Ameling's answer for the updated information.

Found my answer by looking over the dompdf_config.inc.php file. As it turns out, DOMPDF_ENABLE_PHP is set to false thus causing the inline php script to be ignored. I simply edited dompdf_config.custom.inc.php to the following and all is fine and working with the later code in the view.

In dompdf/dompdf_config.custom.inc.php

<?php
    define("DOMPDF_ENABLE_PHP", true);

At Run Time

$dompdf->set_option("isPhpEnabled", true);

Then, in my html file

<body>
    <script type="text/php">
        if ( isset($pdf) ) {
            // OLD 
            // $font = Font_Metrics::get_font("helvetica", "bold");
            // $pdf->page_text(72, 18, "{PAGE_NUM} of {PAGE_COUNT}", $font, 6, array(255,0,0));
            // v.0.7.0 and greater
            $x = 72;
            $y = 18;
            $text = "{PAGE_NUM} of {PAGE_COUNT}";
            $font = $fontMetrics->get_font("helvetica", "bold");
            $size = 6;
            $color = array(255,0,0);
            $word_space = 0.0;  //  default
            $char_space = 0.0;  //  default
            $angle = 0.0;   //  default
            $pdf->page_text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
        }
    </script>
    <div

If you go this route, don't forget to restart Apache

Monday, November 28, 2022
1

I've tested your code and it works fine for me - sample.pdf file is being downloaded in browser. I've downloaded library from https://github.com/dompdf/dompdf/releases/tag/v0.6.1 url (not only the encoding branch(

Probably you haven't moved the whole project to selected directory or you haven't downloaded the whole library. I moved the whole downloaded directory content to APIs/dompdf-encoding directory and I have here files dompdf_config.inc.php and directories lib, include and www.

EDIT

As you edited you want to use only encoding branch, what you have to do is adding the following code at the beginning of your file:

use DompdfAdapterCPDF;
use DompdfDompdf;
use DompdfException;

EDIT2

The whole working code:

<?php
use DompdfAdapterCPDF;
use DompdfDompdf;
use DompdfException;



        require_once("APIs/dompdf-encoding/dompdf_config.inc.php");     
$cart_body='<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>New Order Placed</title></head><body><p>Test Printing...</p></body></html>';
        $dompdf = new Dompdf();
        $dompdf->load_html($cart_body);//body -> html content which needs to be converted as pdf..
        $dompdf->render();
        $dompdf->stream("sample.pdf"); //To popup pdf as download

I have also changed DOMPDF to Dompdf just in case (in Windows both are working)

Monday, November 7, 2022
 
2

I had the exact same problem, no images were displaying for me - background images and inline ones. I had to set DOMPDF_ENABLE_REMOTE to true in your config dompdf_config.inc.php

Just note the security risk if you have this enabled along with DOMPDF_ENABLE_PHP

Saturday, October 15, 2022
2

What do you mean by "difference"? A difference in the text of the PDF or some layout change (e.g. an embedded graphic was resized). The first is easy to detect, the second is almost impossible to get (PDF is an VERY complicated file format, that offers endless file formatting capabilities).

If you want to get the text diff, just run a pdf to text utility on the two PDFs and then use Python's built-in diff library to get the difference of the converted texts.

This question deals with pdf to text conversion in python: Python module for converting PDF to text.

The reliability of this method depends on the PDF Generators you are using. If you use e.g. Adobe Acrobat and some Ghostscript-based PDF-Creator to make two PDFs from the SAME word document, you might still get a diff although the source document was identical.

This is because there are dozens of ways to encode the information of the source document to a PDF and each converter uses a different approach. Often the pdf to text converter can't figure out the correct text flow, especially with complex layouts or tables.

Thursday, November 24, 2022
 
2

This feels like a duplicate to many questions&answers here on but most of the answers to those questions turn out to be not very helpful nowadays as they link to examples that cannot be found anymore, for example because of the move of the iText code base from sourceforge to github or because of redesigns of the itext web site. Furthermore, the OP indicates in a comment that he does know an approach, merely not how to apply it to his case.

Two Main Approaches

First of all, there are two main ways to add "Page x of y" headers or footers to the pages of a document you create using iText:

  • (one-pass approach) You can use page events (in particular the OnEndPage method) to add header/footer/margin material to each page right when this page is finished and before the next page is started.
  • (two-passes approach) Or you can in a first pass create the PDF without those headers or footers and then read that PDF and stamp the footer/header/matgin material in a second pass.

Usually one prefers page events for header and footer material because this way one does not need to temporarily store the PDF from the first pass but can instead already stream it to the target while still being in the process of creating it.

"Page x of y" footers/headers are special, though, because one does not know the final number of pages before all the content has been written. Thus, for the page event approach one has to use a trick and add a reference to a canvas to each page where the total page number shall appear. When all regular content has been added to the document, one finally writes the total page number into it. Unfortunately one does not know how much space exactly is necessary for that template, so the formatting in the resulting header / footer might look a bit awkward in the end. Thus, the two-pass approach may be preferred here.

How to add "Page x of y" headers in two passes to PDFs using iText 5.x is described in the example TwoPasses in chapter 6 of the book "iText in Action - 2nd Edition" written by Bruno Lowagie. The original Java examples have been ported to C# by kuujinbo. Here the pivotal code:

PdfReader reader = new PdfReader(firstPass);
using (MemoryStream ms2 = new MemoryStream()) {
    // Create a stamper
    using (PdfStamper stamper = new PdfStamper(reader, ms2)) {
        // Loop over the pages and add a header to each page
        int n = reader.NumberOfPages;
        for (int i = 1; i <= n; i++) {
            GetHeaderTable(i, n).WriteSelectedRows(0, -1, 34, 803, stamper.GetOverContent(i));
        }
    }
    // write content of ms2 somewhere, e.g. as ms2.ToArray()
}

public static PdfPTable GetHeaderTable(int x, int y) {
    PdfPTable table = new PdfPTable(2);
    table.TotalWidth = 527;
    table.LockedWidth = true;
    table.DefaultCell.FixedHeight = 20;
    table.DefaultCell.Border = Rectangle.BOTTOM_BORDER;
    table.AddCell("FOOBAR FILMFESTIVAL");
    table.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
    table.AddCell(string.Format("Page {0} of {1}", x, y));
    return table;
}    

(on github / on kuujinbo.info)

Application to Your Case

In a comment the OP writes

I have been facing difficulty understanding the two step method, where it starts, how to apply it in my case

Ok, you describe your case as going like this:

iTextSharp.text.Document doc = new iTextSharp.text.Document(PageSize.A4.Rotate(), 50f, 50f, 50f, 50f);
{
    try
    {
        //Main pdf publishing code follows 
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error! try again.", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        doc.Close();
    }
}

First of all I would propose you change it to this:

try
{
    using (iTextSharp.text.Document doc = new iTextSharp.text.Document(PageSize.A4.Rotate(), 50f, 50f, 50f, 50f))
    {
        //Main pdf publishing code follows
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Error! try again.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

because your original approach misses exceptions thrown during the closing of the document object! The using (Document doc = ...) {...} structure replaces a Document doc = ...; try {...} finally {doc.Close();} one.

Now your //Main pdf publishing code follows in particular includes a PdfWriter instantiation, something like

PdfWriter writer = PdfWriter.GetInstance(doc, SOME_STREAM);

For the two pass approach you must instead target your PdfWriter to a temporary stream. To the contents thereof you then apply the above quoted two-pass code. Only the result of that shall finally go to your SOME_STREAM.

All together:

try
{
    using (MemoryStream ms = new MemoryStream())
    {
        float leftRightMargin = 50f;
        using (iTextSharp.text.Document doc = new iTextSharp.text.Document(PageSize.A4.Rotate(), leftRightMargin, leftRightMargin, 50f, 50f))
        {
            PdfWriter writer = PdfWriter.GetInstance(doc, ms);
            //Main pdf publishing code (except PdfWriter instantiation) follows
        }

        using (PdfReader reader = new PdfReader(ms.ToArray()))
        using (PdfStamper stamper = new PdfStamper(reader, SOME_STREAM))
        {
            int n = reader.NumberOfPages;
            for (int i = 1; i <= n; i++)
            {
                Rectangle cropBox = reader.GetCropBox(i);
                for (int rotation = reader.GetPageRotation(i); rotation > 0; rotation -= 90)
                    cropBox = cropBox.Rotate();
                GetHeaderTable(i, n, cropBox.Width - 2 * leftRightMargin).WriteSelectedRows(0, -1, leftRightMargin, cropBox.GetTop(10), stamper.GetOverContent(i));
            }
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Error! try again.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

public static PdfPTable GetHeaderTable(int x, int y, float width)
{
    PdfPTable table = new PdfPTable(2);
    table.TotalWidth = width;
    table.LockedWidth = true;
    table.DefaultCell.FixedHeight = 20;
    table.DefaultCell.Border = Rectangle.BOTTOM_BORDER;
    table.AddCell("Header test");
    table.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
    table.AddCell(string.Format("Page {0} of {1}", x, y));
    return table;
}
Sunday, November 27, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :