Skip to content

Instantly share code, notes, and snippets.

@marcus-at-localhost
Last active April 13, 2022 13:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcus-at-localhost/04bebc64832cd618a872e146a0e48b26 to your computer and use it in GitHub Desktop.
Save marcus-at-localhost/04bebc64832cd618a872e146a0e48b26 to your computer and use it in GitHub Desktop.
Encrypted PDF with DOMPDF and FPDI/FPDF
<html>
<head>
<style>
@page { margin: 27pt }
@font-face {
font-family: 'Open Sans Regular';
src: url('/assets/fonts/opensans-regular-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Open Sans Regular';
src: url('/assets/fonts/opensans-regular-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Open Sans Semi-Bold';
src: url('/assets/fonts/opensans-semibold-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
body{
font-family: 'Open Sans Regular', sans-serif;
font-size:11pt;
line-height:1;
}
h1 {
font-family: 'Open Sans Semi-Bold', sans-serif;
font-weight: bold;
color:#e20613;
font-size:30pt;
}
h1 small {
font-size: 20pt;
font-weight: normal;
}
h2 {
font-weight: 700;
}
small {
font-size:6pt;
}
footer {
}
footer p {
font-size:6pt;
}
footer p.meta {
color:#9D9D9C;
}
/* Tables */
table {
border-collapse: collapse;
width:100%;
margin-bottom: 1mm;
}
td {
border-top:dotted 1px #BBB4AD;
border-bottom:dotted 1px #BBB4AD;
padding:1mm 3pt 2mm;
text-align: center;
}
td:first-child{
text-align:left;
border-right:dotted 1px #BBB4AD;
}
td[colspan="2"]{
color:#e20613;
background-color: #ECE9E6;
text-align: left;
border-right:none 0;
}
.print-header {
text-align:right;
height:41pt;
}
.print-header-logo {
height: 41pt;
width: 170pt;
}
.main-img-container{
float:right;
width:60mm;
}
.main-img{
height:50mm;
}
.profil-img{
padding-left:4pt;
vertical-align: middle;
}
</style>
</head>
<body>
<html>
<div class="print-header">
<img class="print-header-logo" src="image/logo.svg">
</div>
<div class="col-md-8 col-md-offset-2">
<header>
<h1>Flachdichtung <br><small>ABCD-1234</small></h1>
</header>
<div class="main-img-container">
<img class="main-img" src="image/1300.jpg">
</div>
<p>
<span>FD10</span>
<img class="profil-img" width="100" src="image/FD10.png" alt="FD10">
</p>
<h2>Lorem Ipsum</h2>
<p>
Dapibus parturient cursus ridiculus sodales leo eu ligula proin a malesuada ullamcorper diam hac scelerisque a leo felis. Ut curabitur est bibendum lectus parturient lorem dolor velit primis quam vestibulum himenaeos a gravida parturient nulla a mollis suspendisse scelerisque montes id parturient ridiculus suspendisse adipiscing. Suspendisse facilisis adipiscing penatibus auctor dictum pharetra condimentum torquent maecenas ridiculus conubia praesent consectetur vestibulum praesent feugiat sagittis. Scelerisque penatibus inceptos cubilia dictum mus ultricies faucibus gravida nunc ipsum eros quis taciti viverra habitant vestibulum a litora a justo parturient vestibulum.
</p>
<table>
<tr>
<td colspan="2">FREIGABEN</td>
</tr>
<tr>
<td>Besonderheiten</td>
<td>VP 401, HTB</td>
</tr>
<tr>
<td>BAM* EO/PO [Ethylen-/Propylenoxid]</td>
<td></td>
</tr>
<tr>
<td>FDA</td>
<td></td>
</tr>
<tr>
<td>TA Luft 2002 [VDI 2440/2200]</td>
<td>&times;</td>
</tr>
<tr>
<td>DVGW [DIN 3535-6]</td>
<td></td>
</tr>
<tr>
<td>Germanischer Lloyd</td>
<td></td>
</tr>
<tr>
<td>KTW-Leitlinie</td>
<td></td>
</tr>
<tr>
<td>Ausblassicherheit</td>
<td></td>
</tr>
<tr>
<td>Fire Safe Test</td>
<td></td>
</tr>
<tr>
<td>BAM* Sauerstoff</td>
<td></td>
</tr>
<tr>
<td>EG 1935/2004</td>
<td></td>
</tr>
<tr>
<td>KTW-Leitlinie</td>
<td></td>
</tr>
<tr>
<td>Ausblassicherheit</td>
<td></td>
</tr>
<tr>
<td>Fire Safe Test</td>
<td></td>
</tr>
<tr>
<td>BAM* Sauerstoff</td>
<td></td>
</tr>
<tr>
<td>EG 1935/2004</td>
<td></td>
</tr>
</table>
<p>
<small><sup>3</sup> Footnote</small>
</p>
</div>
<footer>
<p class="meta">Dapibus parturient cursus ridiculus sodales leo eu ligula proin a malesuada ullamcorper diam hac scelerisque a leo felis. Ut curabitur est bibendum lectus parturient lorem dolor velit primis quam.</p>
</footer>
</html>
</body>
</html>

Encrypted PDF with DOMPDF and FPDI/FPDF

It's possible to encrypt PDF with dompdf alone, but not if you want to use custom fonts (see bug #698). PDFTK is no option when on shared hosting.

My solution is to convert the HTML to pdf with dompdf first and then encrypt it.

1. DomPDF

Download and setup dompdf

2. FPDI and FPDI Protection

FPDI is used to merge PDFs. It needs the FPDF library to work.

  1. Download latest version of FPDI
  2. Download FPDI_Protection
  3. Download FPDF

3. Setup

Make sure all paths are correct in pdf.php

Info

  • dompdf CSS Compatibility
  • In the process of encrypting, the PDF structure gets changed. Eg. hyperlinks won't work anymore.

Hope that works

<?php
/**
* DOMPDF/FPDI Example
* 1. create pdf with custom fonts in dompdf
* 2. encrypt pdf with fpdi
*/
use Dompdf\Adapter\CPDF;
use Dompdf\Dompdf;
use Dompdf\Exception;
function pdfEncrypt ($origFile, $destFile, $owner_password=null, $user_password=null){
require_once('vendor/fpdf181/fpdf.php');
require_once('vendor/FPDI-1.6.1/fpdi.php');
require_once('vendor/FPDI-1.6.1/FPDI_Protection.php');
$pdf = new FPDI_Protection();
$pagecount = $pdf->setSourceFile($origFile);
// copy all pages from the old unprotected pdf in the new one
for ($loop = 1; $loop <= $pagecount; $loop++) {
$tplidx = $pdf->importPage($loop);
$pdf->addPage();
$dim = $pdf->useTemplate($tplidx);
//var_dump($dim);exit;
}
// Allow for array('print', 'modify', 'copy', 'annot-forms');
$pdf->SetProtection(array('print'),$user_password, $owner_password);
$pdf->Output($destFile,'F'); // F write, D download
return $destFile;
}
require "vendor/dompdf/autoload.inc.php";
$file_to_save = 'content.pdf';
//password for the pdf file
$owner_password = "owner";
$user_password = null; // everybody can open the file!
//name of the destination file
$destFile =str_replace('.pdf','_protected.pdf',$file_to_save);
// html content from file
$html = file_get_contents('content.html');
// start with DOMPDF
$dompdf = new DOMPDF(); //if you use namespaces you may use new \DOMPDF()
// set options: https://github.com/dompdf/dompdf/blob/master/src%2FOptions.php
$dompdf->set_option('isRemoteEnabled',true);
$dompdf->set_option('isFontSubsettingEnabled',true);
$dompdf->set_option('tempDir','content/tmp');
$dompdf->set_paper('a4', 'portrait');
//generate
$dompdf->loadHtml($html);
$dompdf->render();
// embedded custom fonts won't be visible with encryption on
// $dompdf->get_canvas()->get_cpdf()->setEncryption('', 'ownerpass', array('print','copy'));
// $dompdf->stream("sample.pdf", array("Attachment"=>0));
//save the pdf file on the server
file_put_contents($file_to_save, $dompdf->output());
//encrypt the pdf and create the protected file
$file_to_save = pdfEncrypt($file_to_save, $destFile, $owner_password, $user_password );
//print the pdf file to the screen for saving
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="file.pdf"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file_to_save));
header('Accept-Ranges: bytes');
readfile($file_to_save);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment