Skip to content

Commit 6eb2c66

Browse files
committed
Merge pull request #204 from ivanlanin/pdf-writer
Basic PDF Writer. It will be better if we can detect DomPDF installed by composer. Please help. Thanks.
2 parents d54d47d + 413f5e8 commit 6eb2c66

File tree

9 files changed

+474
-28
lines changed

9 files changed

+474
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
44

55
## 0.10.0 - Not yet released
66

7-
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML support is enabled.
7+
This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML and PDF writing support is enabled.
88

99
### Features
1010

@@ -33,6 +33,7 @@ This release marked heavy refactorings on internal code structure with the creat
3333
- ODT Writer: Basic table writing support - @ivanlanin
3434
- Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194
3535
- HTML Writer: Basic HTML writer initiated - @ivanlanin GH-203 GH-67 GH-147
36+
- PDF Writer: Basic PDF writer initiated using DomPDF - @ivanlanin GH-68
3637

3738
### Bugfixes
3839

samples/Sample_Header.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@
1111
require_once '../src/PhpWord/Autoloader.php';
1212
\PhpOffice\PhpWord\Autoloader::register();
1313

14+
// Set writers
15+
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html', 'PDF' => 'pdf');
16+
17+
// Set PDF renderer
18+
$rendererName = \PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF;
19+
$rendererLibraryPath = ''; // DomPDF library path
20+
21+
if (!\PhpOffice\PhpWord\Settings::setPdfRenderer($rendererName, $rendererLibraryPath)) {
22+
$writers['PDF'] = null;
23+
}
24+
1425
// Return to the caller script when runs by CLI
1526
if (CLI) {
1627
return;
@@ -22,9 +33,6 @@
2233
$pageTitle .= 'PHPWord';
2334
$pageHeading = IS_INDEX ? '' : "<h1>{$pageHeading}</h1>";
2435

25-
// Set writers
26-
$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html');
27-
2836
// Populate samples
2937
$files = '';
3038
if ($handle = opendir('.')) {
@@ -51,10 +59,15 @@ function write($phpWord, $filename, $writers)
5159

5260
// Write
5361
foreach ($writers as $writer => $extension) {
54-
$result .= date('H:i:s') . " Write to {$writer} format" . EOL;
55-
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
56-
$xmlWriter->save("{$filename}.{$extension}");
57-
rename("{$filename}.{$extension}", "results/{$filename}.{$extension}");
62+
$result .= date('H:i:s') . " Write to {$writer} format";
63+
if (!is_null($extension)) {
64+
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer);
65+
$xmlWriter->save("{$filename}.{$extension}");
66+
rename("{$filename}.{$extension}", "results/{$filename}.{$extension}");
67+
} else {
68+
$result .= ' ... NOT DONE!';
69+
}
70+
$result .= EOL;
5871
}
5972

6073
// Do not show execution time for index

src/PhpWord/IOFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ abstract class IOFactory
2828
*/
2929
public static function createWriter(PhpWord $phpWord, $name = 'Word2007')
3030
{
31-
if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) {
31+
if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML', 'PDF'))) {
3232
throw new Exception("\"{$name}\" is not a valid writer.");
3333
}
3434

src/PhpWord/Settings.php

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@
1414
*/
1515
class Settings
1616
{
17-
/** Available Zip library classes */
17+
/** Available Zip library classes */
1818
const PCLZIP = 'PhpOffice\\PhpWord\\Shared\\ZipArchive';
1919
const ZIPARCHIVE = 'ZipArchive';
2020

21+
/** Optional PDF Rendering libraries */
22+
const PDF_RENDERER_DOMPDF = 'DomPDF';
23+
2124
/**
2225
* Compatibility option for XMLWriter
2326
*
@@ -27,13 +30,32 @@ class Settings
2730

2831
/**
2932
* Name of the class used for Zip file management
30-
* e.g.
31-
* ZipArchive
3233
*
3334
* @var string
3435
*/
3536
private static $zipClass = self::ZIPARCHIVE;
3637

38+
/**
39+
* Name of the classes used for PDF renderer
40+
*
41+
* @var array
42+
*/
43+
private static $pdfRenderers = array(self::PDF_RENDERER_DOMPDF);
44+
45+
/**
46+
* Name of the external Library used for rendering PDF files
47+
*
48+
* @var string
49+
*/
50+
private static $pdfRendererName = null;
51+
52+
/**
53+
* Directory Path to the external Library used for rendering PDF files
54+
*
55+
* @var string
56+
*/
57+
private static $pdfRendererPath = null;
58+
3759
/**
3860
* Set the compatibility option used by the XMLWriter
3961
*
@@ -74,7 +96,7 @@ public static function setZipClass($zipClass)
7496
return true;
7597
}
7698
return false;
77-
} // function setZipClass()
99+
}
78100

79101
/**
80102
* Return the name of the Zip handler Class that PHPWord is configured to use (PCLZip or ZipArchive)
@@ -87,5 +109,71 @@ public static function setZipClass($zipClass)
87109
public static function getZipClass()
88110
{
89111
return self::$zipClass;
90-
} // function getZipClass()
112+
}
113+
114+
/**
115+
* Set details of the external library for rendering PDF files
116+
*
117+
* @param string $libraryName
118+
* @param string $libraryBaseDir
119+
* @return boolean Success or failure
120+
*/
121+
public static function setPdfRenderer($libraryName, $libraryBaseDir)
122+
{
123+
if (!self::setPdfRendererName($libraryName)) {
124+
return false;
125+
}
126+
127+
return self::setPdfRendererPath($libraryBaseDir);
128+
}
129+
130+
/**
131+
* Return the PDF Rendering Library
132+
*/
133+
public static function getPdfRendererName()
134+
{
135+
return self::$pdfRendererName;
136+
}
137+
138+
/**
139+
* Identify the external library to use for rendering PDF files
140+
*
141+
* @param string $libraryName
142+
* @return boolean Success or failure
143+
*/
144+
public static function setPdfRendererName($libraryName)
145+
{
146+
if (!in_array($libraryName, self::$pdfRenderers)) {
147+
return false;
148+
}
149+
150+
self::$pdfRendererName = $libraryName;
151+
152+
return true;
153+
}
154+
155+
156+
/**
157+
* Return the directory path to the PDF Rendering Library
158+
*/
159+
public static function getPdfRendererPath()
160+
{
161+
return self::$pdfRendererPath;
162+
}
163+
164+
/**
165+
* Location of external library to use for rendering PDF files
166+
*
167+
* @param string $libraryBaseDir Directory path to the library's base folder
168+
* @return boolean Success or failure
169+
*/
170+
public static function setPdfRendererPath($libraryBaseDir)
171+
{
172+
if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) {
173+
return false;
174+
}
175+
self::$pdfRendererPath = $libraryBaseDir;
176+
177+
return true;
178+
}
91179
}

src/PhpWord/Writer/HTML.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PhpOffice\PhpWord\Element\ListItem;
1717
use PhpOffice\PhpWord\Element\Object;
1818
use PhpOffice\PhpWord\Element\PageBreak;
19+
use PhpOffice\PhpWord\Element\PreserveText;
1920
use PhpOffice\PhpWord\Element\Table;
2021
use PhpOffice\PhpWord\Element\Text;
2122
use PhpOffice\PhpWord\Element\TextBreak;
@@ -65,7 +66,7 @@ public function save($filename = null)
6566
*
6667
* @return string
6768
*/
68-
private function writeDocument()
69+
public function writeDocument()
6970
{
7071
$html = '';
7172
$html .= '<!DOCTYPE html>' . PHP_EOL;
@@ -87,7 +88,7 @@ private function writeDocument()
8788
*
8889
* @return string
8990
*/
90-
public function writeHTMLHead()
91+
private function writeHTMLHead()
9192
{
9293
$properties = $this->getPhpWord()->getDocumentProperties();
9394
$propertiesMapping = array(
@@ -124,7 +125,7 @@ public function writeHTMLHead()
124125
*
125126
* @return string
126127
*/
127-
public function writeHTMLBody()
128+
private function writeHTMLBody()
128129
{
129130
$phpWord = $this->getPhpWord();
130131
$html = '';
@@ -136,8 +137,8 @@ public function writeHTMLBody()
136137
if ($countSections > 0) {
137138
foreach ($sections as $section) {
138139
$pSection++;
139-
$cellContents = $section->getElements();
140-
foreach ($cellContents as $element) {
140+
$contents = $section->getElements();
141+
foreach ($contents as $element) {
141142
if ($element instanceof Text) {
142143
$html .= $this->writeText($element);
143144
} elseif ($element instanceof TextRun) {
@@ -161,9 +162,9 @@ public function writeHTMLBody()
161162
} elseif ($element instanceof Object) {
162163
$html .= $this->writeObject($element);
163164
} elseif ($element instanceof Footnote) {
164-
$html .= $this->writeFootnote($element, true);
165+
$html .= $this->writeFootnote($element);
165166
} elseif ($element instanceof Endnote) {
166-
$html .= $this->writeEndnote($element, true);
167+
$html .= $this->writeEndnote($element);
167168
}
168169
}
169170
}
@@ -248,9 +249,9 @@ private function writeTextRun($textrun)
248249
} elseif ($element instanceof Image) {
249250
$html .= $this->writeImage($element, true);
250251
} elseif ($element instanceof Footnote) {
251-
$html .= $this->writeFootnote($element, true);
252+
$html .= $this->writeFootnote($element);
252253
} elseif ($element instanceof Endnote) {
253-
$html .= $this->writeEndnote($element, true);
254+
$html .= $this->writeEndnote($element);
254255
}
255256
}
256257
$html .= '</p>' . PHP_EOL;
@@ -263,6 +264,7 @@ private function writeTextRun($textrun)
263264
* Write link
264265
*
265266
* @param Link $element
267+
* @param boolean $withoutP
266268
* @return string
267269
*/
268270
private function writeLink($element, $withoutP = false)
@@ -300,6 +302,7 @@ private function writeTitle($element)
300302
* Write preserve text
301303
*
302304
* @param PreserveText $element
305+
* @param boolean $withoutP
303306
* @return string
304307
*/
305308
private function writePreserveText($element, $withoutP = false)
@@ -350,7 +353,7 @@ private function writeListItem($element)
350353
/**
351354
* Write table
352355
*
353-
* @param Title $element
356+
* @param Table $element
354357
* @return string
355358
*/
356359
private function writeTable($element)
@@ -361,7 +364,7 @@ private function writeTable($element)
361364
if ($cRows > 0) {
362365
$html .= "<table>" . PHP_EOL;
363366
foreach ($rows as $row) {
364-
$height = $row->getHeight();
367+
// $height = $row->getHeight();
365368
$rowStyle = $row->getStyle();
366369
$tblHeader = $rowStyle->getTblHeader();
367370
$html .= "<tr>" . PHP_EOL;
@@ -388,13 +391,13 @@ private function writeTable($element)
388391
} elseif ($content instanceof Object) {
389392
$html .= $this->writeObject($content);
390393
} elseif ($element instanceof Footnote) {
391-
$html .= $this->writeFootnote($element, true);
394+
$html .= $this->writeFootnote($element);
392395
} elseif ($element instanceof Endnote) {
393-
$html .= $this->writeEndnote($element, true);
396+
$html .= $this->writeEndnote($element);
394397
}
395398
}
396399
} else {
397-
$this->writeTextBreak($content);
400+
$html .= $this->writeTextBreak(new TextBreak());
398401
}
399402
$html .= "</td>" . PHP_EOL;
400403
}
@@ -410,6 +413,7 @@ private function writeTable($element)
410413
* Write image
411414
*
412415
* @param Image $element
416+
* @param boolean $withoutP
413417
* @return string
414418
*/
415419
private function writeImage($element, $withoutP = false)
@@ -421,6 +425,7 @@ private function writeImage($element, $withoutP = false)
421425
* Write object
422426
*
423427
* @param Object $element
428+
* @param boolean $withoutP
424429
* @return string
425430
*/
426431
private function writeObject($element, $withoutP = false)
@@ -478,11 +483,14 @@ private function writeUnsupportedElement($element, $withoutP = false)
478483
*/
479484
private function writeStyles()
480485
{
486+
$bodyCss = array();
481487
$css = '<style>' . PHP_EOL;
488+
482489
// Default styles
483490
$bodyCss['font-family'] = "'" . $this->getPhpWord()->getDefaultFontName() . "'";
484491
$bodyCss['font-size'] = $this->getPhpWord()->getDefaultFontSize() . 'pt';
485492
$css .= '* ' . $this->assembleCss($bodyCss, true) . PHP_EOL;
493+
486494
// Custom styles
487495
$styles = Style::getStyles();
488496
if (is_array($styles)) {

0 commit comments

Comments
 (0)