Skip to content

Commit 2829fd8

Browse files
committed
Enable image in HTML writer
1 parent 9c738f7 commit 2829fd8

File tree

8 files changed

+161
-99
lines changed

8 files changed

+161
-99
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ This release marked heavy refactorings on internal code structure with the creat
3232
- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198
3333
- ODT Writer: Basic table writing support - @ivanlanin
3434
- Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194
35-
- 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
35+
- HTML Writer: Basic HTML writer: text, textrun, link, title, textbreak, table, image (as Base64) - @ivanlanin GH-203 GH-67 GH-147
36+
- PDF Writer: Basic PDF writer using DomPDF: All HTML element except image - @ivanlanin GH-68
3737

3838
### Bugfixes
3939

docs/intro.rst

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -62,63 +62,63 @@ Below are the supported features for each file formats.
6262
Writers
6363
~~~~~~~
6464

65-
+-------------------------------------------------+--------+-------+-------+
66-
| Features | DOCX | ODT | RTF |
67-
+=========================+=======================+========+=======+=======+
68-
| **Document Properties** | Standard | | | |
69-
+ +-----------------------+--------+-------+-------+
70-
| | Extended | | | |
71-
+ +-----------------------+--------+-------+-------+
72-
| | UserDefined | | | |
73-
+-------------------------+-----------------------+--------+-------+-------+
74-
| **Element Type** | Text ||||
75-
+ +-----------------------+--------+-------+-------+
76-
| | Text Run ||||
77-
+ +-----------------------+--------+-------+-------+
78-
| | Title || | |
79-
+ +-----------------------+--------+-------+-------+
80-
| | Link || | |
81-
+ +-----------------------+--------+-------+-------+
82-
| | Preserve Text || | |
83-
+ +-----------------------+--------+-------+-------+
84-
| | Text Break ||||
85-
+ +-----------------------+--------+-------+-------+
86-
| | Page Break || | |
87-
+ +-----------------------+--------+-------+-------+
88-
| | List || | |
89-
+ +-----------------------+--------+-------+-------+
90-
| | Table || | |
91-
+ +-----------------------+--------+-------+-------+
92-
| | Image || | |
93-
+ +-----------------------+--------+-------+-------+
94-
| | Object || | |
95-
+ +-----------------------+--------+-------+-------+
96-
| | Watermark || | |
97-
+ +-----------------------+--------+-------+-------+
98-
| | Table of Contents || | |
99-
+ +-----------------------+--------+-------+-------+
100-
| | Header || | |
101-
+ +-----------------------+--------+-------+-------+
102-
| | Footer || | |
103-
+ +-----------------------+--------+-------+-------+
104-
| | Footnote || | |
105-
+ +-----------------------+--------+-------+-------+
106-
| | Endnote || | |
107-
+-------------------------+-----------------------+--------+-------+-------+
108-
| **Graphs** | 2D basic graphs | | | |
109-
+ +-----------------------+--------+-------+-------+
110-
| | 2D advanced graphs | | | |
111-
+ +-----------------------+--------+-------+-------+
112-
| | 3D graphs | | | |
113-
+-------------------------+-----------------------+--------+-------+-------+
114-
| **Math** | OMML support | | | |
115-
+ +-----------------------+--------+-------+-------+
116-
| | MathML support | | | |
117-
+-------------------------+-----------------------+--------+-------+-------+
118-
| **Bonus** | Encryption | | | |
119-
+ +-----------------------+--------+-------+-------+
120-
| | Protection | | | |
121-
+-------------------------+-----------------------+--------+-------+-------+
65+
+-------------------------------------------------+--------+-------+-------+-------+-------+
66+
| Features | DOCX | ODT | RTF | HTML | PDF |
67+
+=========================+=======================+========+=======+=======+=======+=======+
68+
| **Document Properties** | Standard | | | | | |
69+
+ +-----------------------+--------+-------+-------+-------+-------+
70+
| | Extended | | | | | |
71+
+ +-----------------------+--------+-------+-------+-------+-------+
72+
| | UserDefined | | | | | |
73+
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
74+
| **Element Type** | Text ||||||
75+
+ +-----------------------+--------+-------+-------+-------+-------+
76+
| | Text Run ||||||
77+
+ +-----------------------+--------+-------+-------+-------+-------+
78+
| | Title || | |||
79+
+ +-----------------------+--------+-------+-------+-------+-------+
80+
| | Link || | |||
81+
+ +-----------------------+--------+-------+-------+-------+-------+
82+
| | Preserve Text || | | | |
83+
+ +-----------------------+--------+-------+-------+-------+-------+
84+
| | Text Break ||||||
85+
+ +-----------------------+--------+-------+-------+-------+-------+
86+
| | Page Break || | | | |
87+
+ +-----------------------+--------+-------+-------+-------+-------+
88+
| | List || | | | |
89+
+ +-----------------------+--------+-------+-------+-------+-------+
90+
| | Table || | || |
91+
+ +-----------------------+--------+-------+-------+-------+-------+
92+
| | Image || | || |
93+
+ +-----------------------+--------+-------+-------+-------+-------+
94+
| | Object || | | | |
95+
+ +-----------------------+--------+-------+-------+-------+-------+
96+
| | Watermark || | | | |
97+
+ +-----------------------+--------+-------+-------+-------+-------+
98+
| | Table of Contents || | | | |
99+
+ +-----------------------+--------+-------+-------+-------+-------+
100+
| | Header || | | | |
101+
+ +-----------------------+--------+-------+-------+-------+-------+
102+
| | Footer || | | | |
103+
+ +-----------------------+--------+-------+-------+-------+-------+
104+
| | Footnote || | | | |
105+
+ +-----------------------+--------+-------+-------+-------+-------+
106+
| | Endnote || | | | |
107+
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
108+
| **Graphs** | 2D basic graphs | | | | | |
109+
+ +-----------------------+--------+-------+-------+-------+-------+
110+
| | 2D advanced graphs | | | | | |
111+
+ +-----------------------+--------+-------+-------+-------+-------+
112+
| | 3D graphs | | | | | |
113+
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
114+
| **Math** | OMML support | | | | | |
115+
+ +-----------------------+--------+-------+-------+-------+-------+
116+
| | MathML support | | | | | |
117+
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
118+
| **Bonus** | Encryption | | | | | |
119+
+ +-----------------------+--------+-------+-------+-------+-------+
120+
| | Protection | | | | | |
121+
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
122122

123123

124124
Readers

src/PhpWord/Element/Image.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ public function getSource()
126126
return $this->source;
127127
}
128128

129+
/**
130+
* Get image source type
131+
*
132+
* @return string
133+
*/
134+
public function getSourceType()
135+
{
136+
return $this->sourceType;
137+
}
138+
129139
/**
130140
* Get image media ID
131141
*
@@ -324,6 +334,9 @@ private function setFunctions()
324334

325335
/**
326336
* Set proportional width/height if one dimension not available
337+
*
338+
* @param integer $actualWidth
339+
* @param integer $actualHeight
327340
*/
328341
private function setProportionalSize($actualWidth, $actualHeight)
329342
{

src/PhpWord/Writer/AbstractWriter.php

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,7 @@ public function getDiskCachingDirectory()
164164
protected function getTempFile($filename)
165165
{
166166
// Temporary directory
167-
$tempDir = sys_get_temp_dir() . '/PHPWordMedia/';
168-
if (!is_dir($tempDir)) {
169-
mkdir($tempDir);
170-
}
171-
$this->tempDir = $tempDir;
167+
$this->setTempDir();
172168

173169
// Temporary file
174170
$this->originalFilename = $filename;
@@ -184,31 +180,45 @@ protected function getTempFile($filename)
184180
}
185181

186182
/**
187-
* Cleanup temporary file
188-
*
189-
* If a temporary file was used, copy it to the correct file stream
183+
* Get temporary directory
190184
*/
191185
protected function getTempDir()
192186
{
193187
return $this->tempDir;
194188
}
195189

190+
/**
191+
* Set temporary directory
192+
*/
193+
protected function setTempDir()
194+
{
195+
$tempDir = sys_get_temp_dir() . '/PHPWordMedia/';
196+
if (!is_dir($tempDir)) {
197+
mkdir($tempDir);
198+
}
199+
$this->tempDir = $tempDir;
200+
}
201+
196202
/**
197203
* Cleanup temporary file
198-
*
199-
* If a temporary file was used, copy it to the correct file stream
200204
*/
201205
protected function cleanupTempFile()
202206
{
203-
// File
204207
if ($this->originalFilename != $this->tempFilename) {
205208
if (copy($this->tempFilename, $this->originalFilename) === false) {
206209
throw new Exception("Could not copy temporary zip file {$this->tempFilename} to {$this->originalFilename}.");
207210
}
208211
@unlink($this->tempFilename);
209212
}
210213

211-
// Directory
214+
$this->clearTempDir();
215+
}
216+
217+
/**
218+
* Clear temporary directory
219+
*/
220+
protected function clearTempDir()
221+
{
212222
if (is_dir($this->tempDir)) {
213223
$this->deleteDir($this->tempDir);
214224
}

src/PhpWord/Writer/HTML.php

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@
3636
*/
3737
class HTML extends AbstractWriter implements WriterInterface
3838
{
39+
/**
40+
* Is the current writer creating PDF?
41+
*
42+
* @var boolean
43+
*/
44+
protected $isPdf = false;
45+
3946
/**
4047
* Create new instance
4148
*/
@@ -53,9 +60,11 @@ public function __construct(PhpWord $phpWord = null)
5360
public function save($filename = null)
5461
{
5562
if (!is_null($this->getPhpWord())) {
63+
$this->setTempDir();
5664
$hFile = fopen($filename, 'w') or die("can't open file");
5765
fwrite($hFile, $this->writeDocument());
5866
fclose($hFile);
67+
$this->clearTempDir();
5968
} else {
6069
throw new Exception("No PHPWord assigned.");
6170
}
@@ -421,7 +430,18 @@ private function writeTable($element)
421430
*/
422431
private function writeImage($element, $withoutP = false)
423432
{
424-
return $this->writeUnsupportedElement($element, $withoutP);
433+
$html = $this->writeUnsupportedElement($element, $withoutP);
434+
if (!$this->isPdf) {
435+
$imageData = $this->getBase64ImageData($element);
436+
if (!is_null($imageData)) {
437+
$html = '<img border="0" src="' . $imageData . '"/>';
438+
if (!$withoutP) {
439+
$html = '<p>' . $html . '</p>' . PHP_EOL;
440+
}
441+
}
442+
}
443+
444+
return $html;
425445
}
426446

427447
/**
@@ -597,4 +617,42 @@ private function assembleCss($css, $curlyBracket = false)
597617

598618
return $string;
599619
}
620+
621+
/**
622+
* Get Base64 image data
623+
*
624+
* @return string|null
625+
*/
626+
private function getBase64ImageData(Image $element)
627+
{
628+
$imageData = null;
629+
$source = $element->getSource();
630+
$imageType = $element->getImageType();
631+
632+
// Get actual source
633+
if ($element->getSourceType() == 'archive') {
634+
$source = substr($source, 6);
635+
list($zipFilename, $imageFilename) = explode('#', $source);
636+
$zip = new \ZipArchive();
637+
if ($zip->open($zipFilename) !== false) {
638+
if ($zip->locateName($imageFilename)) {
639+
$zip->extractTo($this->getTempDir(), $imageFilename);
640+
$actualSource = $this->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
641+
}
642+
}
643+
$zip->close();
644+
} else {
645+
$actualSource = $source;
646+
}
647+
648+
// Read image binary data and convert into Base64
649+
if ($fp = fopen($actualSource, "rb", 0)) {
650+
$image = fread($fp, filesize($actualSource));
651+
fclose($fp);
652+
$base64 = chunk_split(base64_encode($image));
653+
$imageData = 'data:' . $imageType . ';base64,' . $base64;
654+
}
655+
656+
return $imageData;
657+
}
600658
}

src/PhpWord/Writer/PDF/AbstractRenderer.php

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
6969
public function __construct(PhpWord $phpWord)
7070
{
7171
parent::__construct($phpWord);
72-
$this->setTempDir(sys_get_temp_dir());
7372
}
7473

7574
/**
@@ -141,43 +140,20 @@ public function setOrientation($pValue = 'default')
141140
return $this;
142141
}
143142

144-
/**
145-
* Get temporary storage directory
146-
*
147-
* @return string
148-
*/
149-
public function getTempDir()
150-
{
151-
return $this->tempDir;
152-
}
153-
154-
/**
155-
* Set temporary storage directory
156-
*
157-
* @param string $pValue Temporary storage directory
158-
* @return self
159-
*/
160-
public function setTempDir($pValue = '')
161-
{
162-
if (is_dir($pValue)) {
163-
$this->tempDir = $pValue;
164-
} else {
165-
throw new Exception("Directory does not exist: $pValue");
166-
}
167-
return $this;
168-
}
169-
170143
/**
171144
* Save PhpWord to PDF file, pre-save
172145
*
173146
* @param string $pFilename Name of the file to save as
147+
* @return resource
174148
*/
175149
protected function prepareForSave($pFilename = null)
176150
{
177151
$fileHandle = fopen($pFilename, 'w');
178152
if ($fileHandle === false) {
179153
throw new Exception("Could not open file $pFilename for writing.");
180154
}
155+
$this->isPdf = true;
156+
181157
return $fileHandle;
182158
}
183159

src/PhpWord/Writer/Word2007.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ private function addFilesToPackage($objZip, $elements)
181181
/**
182182
* Add file to package
183183
*
184+
* Get the actual source from an archive image
185+
*
184186
* @param mixed $objZip
185187
* @param string $source
186188
* @param string $target

tests/PhpWord/Tests/SettingsTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public function testSetGetZipClass()
3939
$this->assertFalse(Settings::setZipClass('foo'));
4040
}
4141

42+
/**
43+
* Test set/get PDF renderer
44+
*/
4245
public function testSetGetPdfRenderer()
4346
{
4447
$domPdfPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');

0 commit comments

Comments
 (0)