Enable image in HTML writer
This commit is contained in:
parent
9c738f7eae
commit
2829fd8216
|
|
@ -32,8 +32,8 @@ This release marked heavy refactorings on internal code structure with the creat
|
|||
- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198
|
||||
- ODT Writer: Basic table writing support - @ivanlanin
|
||||
- Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194
|
||||
- HTML Writer: Basic HTML writer initiated - @ivanlanin GH-203 GH-67 GH-147
|
||||
- PDF Writer: Basic PDF writer initiated using DomPDF - @ivanlanin GH-68
|
||||
- HTML Writer: Basic HTML writer: text, textrun, link, title, textbreak, table, image (as Base64) - @ivanlanin GH-203 GH-67 GH-147
|
||||
- PDF Writer: Basic PDF writer using DomPDF: All HTML element except image - @ivanlanin GH-68
|
||||
|
||||
### Bugfixes
|
||||
|
||||
|
|
|
|||
114
docs/intro.rst
114
docs/intro.rst
|
|
@ -62,63 +62,63 @@ Below are the supported features for each file formats.
|
|||
Writers
|
||||
~~~~~~~
|
||||
|
||||
+-------------------------------------------------+--------+-------+-------+
|
||||
| Features | DOCX | ODT | RTF |
|
||||
+=========================+=======================+========+=======+=======+
|
||||
| **Document Properties** | Standard | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Extended | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | UserDefined | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+
|
||||
| **Element Type** | Text | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Text Run | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Title | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Link | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Preserve Text | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Text Break | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Page Break | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | List | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Table | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Image | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Object | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Watermark | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Table of Contents | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Header | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Footer | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Footnote | ✓ | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Endnote | ✓ | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+
|
||||
| **Graphs** | 2D basic graphs | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | 2D advanced graphs | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | 3D graphs | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+
|
||||
| **Math** | OMML support | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | MathML support | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+
|
||||
| **Bonus** | Encryption | | | |
|
||||
+ +-----------------------+--------+-------+-------+
|
||||
| | Protection | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+
|
||||
+-------------------------------------------------+--------+-------+-------+-------+-------+
|
||||
| Features | DOCX | ODT | RTF | HTML | PDF |
|
||||
+=========================+=======================+========+=======+=======+=======+=======+
|
||||
| **Document Properties** | Standard | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Extended | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | UserDefined | ✓ | | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
|
||||
| **Element Type** | Text | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Text Run | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Title | ✓ | | | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Link | ✓ | | | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Preserve Text | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Text Break | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Page Break | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | List | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Table | ✓ | ✓ | | ✓ | ✓ |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Image | ✓ | | | ✓ | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Object | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Watermark | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Table of Contents | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Header | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Footer | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Footnote | ✓ | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Endnote | ✓ | | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
|
||||
| **Graphs** | 2D basic graphs | | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | 2D advanced graphs | | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | 3D graphs | | | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
|
||||
| **Math** | OMML support | | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | MathML support | | | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
|
||||
| **Bonus** | Encryption | | | | | |
|
||||
+ +-----------------------+--------+-------+-------+-------+-------+
|
||||
| | Protection | | | | | |
|
||||
+-------------------------+-----------------------+--------+-------+-------+-------+-------+
|
||||
|
||||
|
||||
Readers
|
||||
|
|
|
|||
|
|
@ -126,6 +126,16 @@ class Image extends AbstractElement
|
|||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image source type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSourceType()
|
||||
{
|
||||
return $this->sourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image media ID
|
||||
*
|
||||
|
|
@ -324,6 +334,9 @@ class Image extends AbstractElement
|
|||
|
||||
/**
|
||||
* Set proportional width/height if one dimension not available
|
||||
*
|
||||
* @param integer $actualWidth
|
||||
* @param integer $actualHeight
|
||||
*/
|
||||
private function setProportionalSize($actualWidth, $actualHeight)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -164,11 +164,7 @@ abstract class AbstractWriter implements WriterInterface
|
|||
protected function getTempFile($filename)
|
||||
{
|
||||
// Temporary directory
|
||||
$tempDir = sys_get_temp_dir() . '/PHPWordMedia/';
|
||||
if (!is_dir($tempDir)) {
|
||||
mkdir($tempDir);
|
||||
}
|
||||
$this->tempDir = $tempDir;
|
||||
$this->setTempDir();
|
||||
|
||||
// Temporary file
|
||||
$this->originalFilename = $filename;
|
||||
|
|
@ -184,23 +180,30 @@ abstract class AbstractWriter implements WriterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Cleanup temporary file
|
||||
*
|
||||
* If a temporary file was used, copy it to the correct file stream
|
||||
* Get temporary directory
|
||||
*/
|
||||
protected function getTempDir()
|
||||
{
|
||||
return $this->tempDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set temporary directory
|
||||
*/
|
||||
protected function setTempDir()
|
||||
{
|
||||
$tempDir = sys_get_temp_dir() . '/PHPWordMedia/';
|
||||
if (!is_dir($tempDir)) {
|
||||
mkdir($tempDir);
|
||||
}
|
||||
$this->tempDir = $tempDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup temporary file
|
||||
*
|
||||
* If a temporary file was used, copy it to the correct file stream
|
||||
*/
|
||||
protected function cleanupTempFile()
|
||||
{
|
||||
// File
|
||||
if ($this->originalFilename != $this->tempFilename) {
|
||||
if (copy($this->tempFilename, $this->originalFilename) === false) {
|
||||
throw new Exception("Could not copy temporary zip file {$this->tempFilename} to {$this->originalFilename}.");
|
||||
|
|
@ -208,7 +211,14 @@ abstract class AbstractWriter implements WriterInterface
|
|||
@unlink($this->tempFilename);
|
||||
}
|
||||
|
||||
// Directory
|
||||
$this->clearTempDir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear temporary directory
|
||||
*/
|
||||
protected function clearTempDir()
|
||||
{
|
||||
if (is_dir($this->tempDir)) {
|
||||
$this->deleteDir($this->tempDir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ use PhpOffice\PhpWord\TOC;
|
|||
*/
|
||||
class HTML extends AbstractWriter implements WriterInterface
|
||||
{
|
||||
/**
|
||||
* Is the current writer creating PDF?
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isPdf = false;
|
||||
|
||||
/**
|
||||
* Create new instance
|
||||
*/
|
||||
|
|
@ -53,9 +60,11 @@ class HTML extends AbstractWriter implements WriterInterface
|
|||
public function save($filename = null)
|
||||
{
|
||||
if (!is_null($this->getPhpWord())) {
|
||||
$this->setTempDir();
|
||||
$hFile = fopen($filename, 'w') or die("can't open file");
|
||||
fwrite($hFile, $this->writeDocument());
|
||||
fclose($hFile);
|
||||
$this->clearTempDir();
|
||||
} else {
|
||||
throw new Exception("No PHPWord assigned.");
|
||||
}
|
||||
|
|
@ -421,7 +430,18 @@ class HTML extends AbstractWriter implements WriterInterface
|
|||
*/
|
||||
private function writeImage($element, $withoutP = false)
|
||||
{
|
||||
return $this->writeUnsupportedElement($element, $withoutP);
|
||||
$html = $this->writeUnsupportedElement($element, $withoutP);
|
||||
if (!$this->isPdf) {
|
||||
$imageData = $this->getBase64ImageData($element);
|
||||
if (!is_null($imageData)) {
|
||||
$html = '<img border="0" src="' . $imageData . '"/>';
|
||||
if (!$withoutP) {
|
||||
$html = '<p>' . $html . '</p>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -597,4 +617,42 @@ class HTML extends AbstractWriter implements WriterInterface
|
|||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Base64 image data
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function getBase64ImageData(Image $element)
|
||||
{
|
||||
$imageData = null;
|
||||
$source = $element->getSource();
|
||||
$imageType = $element->getImageType();
|
||||
|
||||
// Get actual source
|
||||
if ($element->getSourceType() == 'archive') {
|
||||
$source = substr($source, 6);
|
||||
list($zipFilename, $imageFilename) = explode('#', $source);
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($zipFilename) !== false) {
|
||||
if ($zip->locateName($imageFilename)) {
|
||||
$zip->extractTo($this->getTempDir(), $imageFilename);
|
||||
$actualSource = $this->getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
} else {
|
||||
$actualSource = $source;
|
||||
}
|
||||
|
||||
// Read image binary data and convert into Base64
|
||||
if ($fp = fopen($actualSource, "rb", 0)) {
|
||||
$image = fread($fp, filesize($actualSource));
|
||||
fclose($fp);
|
||||
$base64 = chunk_split(base64_encode($image));
|
||||
$imageData = 'data:' . $imageType . ';base64,' . $base64;
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
|
|||
public function __construct(PhpWord $phpWord)
|
||||
{
|
||||
parent::__construct($phpWord);
|
||||
$this->setTempDir(sys_get_temp_dir());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -141,36 +140,11 @@ abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get temporary storage directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTempDir()
|
||||
{
|
||||
return $this->tempDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set temporary storage directory
|
||||
*
|
||||
* @param string $pValue Temporary storage directory
|
||||
* @return self
|
||||
*/
|
||||
public function setTempDir($pValue = '')
|
||||
{
|
||||
if (is_dir($pValue)) {
|
||||
$this->tempDir = $pValue;
|
||||
} else {
|
||||
throw new Exception("Directory does not exist: $pValue");
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save PhpWord to PDF file, pre-save
|
||||
*
|
||||
* @param string $pFilename Name of the file to save as
|
||||
* @return resource
|
||||
*/
|
||||
protected function prepareForSave($pFilename = null)
|
||||
{
|
||||
|
|
@ -178,6 +152,8 @@ abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
|
|||
if ($fileHandle === false) {
|
||||
throw new Exception("Could not open file $pFilename for writing.");
|
||||
}
|
||||
$this->isPdf = true;
|
||||
|
||||
return $fileHandle;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ class Word2007 extends AbstractWriter implements WriterInterface
|
|||
/**
|
||||
* Add file to package
|
||||
*
|
||||
* Get the actual source from an archive image
|
||||
*
|
||||
* @param mixed $objZip
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class SettingsTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertFalse(Settings::setZipClass('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set/get PDF renderer
|
||||
*/
|
||||
public function testSetGetPdfRenderer()
|
||||
{
|
||||
$domPdfPath = realpath(PHPWORD_TESTS_BASE_DIR . '/../vendor/dompdf/dompdf');
|
||||
|
|
|
|||
Loading…
Reference in New Issue