This commit is contained in:
wangjinlei
2024-07-17 09:23:45 +08:00
parent edf9deeb1a
commit 881ac3e056
1001 changed files with 41032 additions and 5452 deletions

View File

@@ -347,17 +347,8 @@ abstract class AbstractWriter implements WriterInterface
// Retrive GD image content or get local media
if (isset($element['isMemImage']) && $element['isMemImage']) {
$image = call_user_func($element['createFunction'], $element['source']);
if ($element['imageType'] === 'image/png') {
// PNG images need to preserve alpha channel information
imagesavealpha($image, true);
}
ob_start();
call_user_func($element['imageFunction'], $image);
$imageContents = ob_get_contents();
ob_end_clean();
$imageContents = $element['imageString'];
$zip->addFromString($target, $imageContents);
imagedestroy($image);
} else {
$this->addFileToPackage($zip, $element['source'], $target);
}

View File

@@ -18,6 +18,9 @@
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\Validate;
use PhpOffice\PhpWord\Style\Font;
/**
* HTML writer.
@@ -42,6 +45,27 @@ class HTML extends AbstractWriter implements WriterInterface
*/
protected $notes = [];
/**
* Callback for editing generated html.
*
* @var null|callable
*/
private $editCallback;
/**
* Default generic name for default font for html.
*
* @var string
*/
private $defaultGenericFont = '';
/**
* Default white space style for html.
*
* @var string
*/
private $defaultWhiteSpace = '';
/**
* Create new instance.
*/
@@ -63,10 +87,8 @@ class HTML extends AbstractWriter implements WriterInterface
/**
* Save PhpWord to file.
*
* @param string $filename
*/
public function save($filename = null): void
public function save(string $filename): void
{
$this->writeFile($this->openFile($filename), $this->getContent());
}
@@ -84,14 +106,56 @@ class HTML extends AbstractWriter implements WriterInterface
$content .= '<!DOCTYPE html>' . PHP_EOL;
$content .= '<!-- Generated by PHPWord -->' . PHP_EOL;
$content .= '<html>' . PHP_EOL;
$langtext = '';
$phpWord = $this->getPhpWord();
$lang = $phpWord->getSettings()->getThemeFontLang();
if (!empty($lang)) {
$lang2 = $lang->getLatin();
if (!$lang2) {
$lang2 = $lang->getEastAsia();
}
if (!$lang2) {
$lang2 = $lang->getBidirectional();
}
if ($lang2) {
$langtext = " lang='" . $lang2 . "'";
}
}
$content .= "<html$langtext>" . PHP_EOL;
$content .= $this->getWriterPart('Head')->write();
$content .= $this->getWriterPart('Body')->write();
$content .= '</html>' . PHP_EOL;
// Trigger a callback for editing the entire HTML
$callback = $this->editCallback;
if ($callback !== null) {
$content = $callback($content);
}
return $content;
}
/**
* Return the callback to edit the entire HTML.
*/
public function getEditCallback(): ?callable
{
return $this->editCallback;
}
/**
* Set a callback to edit the entire HTML.
*
* The callback must accept the HTML as string as first parameter,
* and it must return the edited HTML as string.
*/
public function setEditCallback(?callable $callback): self
{
$this->editCallback = $callback;
return $this;
}
/**
* Get is PDF.
*
@@ -122,4 +186,52 @@ class HTML extends AbstractWriter implements WriterInterface
{
$this->notes[$noteId] = $noteMark;
}
/**
* Get generic name for default font for html.
*/
public function getDefaultGenericFont(): string
{
return $this->defaultGenericFont;
}
/**
* Set generic name for default font for html.
*/
public function setDefaultGenericFont(string $value): self
{
$this->defaultGenericFont = Validate::validateCSSGenericFont($value);
return $this;
}
/**
* Get default white space style for html.
*/
public function getDefaultWhiteSpace(): string
{
return $this->defaultWhiteSpace;
}
/**
* Set default white space style for html.
*/
public function setDefaultWhiteSpace(string $value): self
{
$this->defaultWhiteSpace = Validate::validateCSSWhiteSpace($value);
return $this;
}
/**
* Escape string or not depending on setting.
*/
public function escapeHTML(string $txt): string
{
if (Settings::isOutputEscapingEnabled()) {
return htmlspecialchars($txt, ENT_QUOTES | (defined('ENT_SUBSTITUTE') ? ENT_SUBSTITUTE : 0), 'UTF-8');
}
return $txt;
}
}

View File

@@ -17,9 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use Laminas\Escaper\Escaper;
use PhpOffice\PhpWord\Element\AbstractElement as Element;
use PhpOffice\PhpWord\Writer\AbstractWriter;
use PhpOffice\PhpWord\Writer\HTML;
/**
* Abstract HTML element writer.
@@ -31,7 +30,7 @@ abstract class AbstractElement
/**
* Parent writer.
*
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
* @var HTML
*/
protected $parentWriter;
@@ -49,11 +48,6 @@ abstract class AbstractElement
*/
protected $withoutP = false;
/**
* @var \Laminas\Escaper\Escaper|\PhpOffice\PhpWord\Escaper\AbstractEscaper
*/
protected $escaper;
/**
* Write element.
*/
@@ -64,12 +58,11 @@ abstract class AbstractElement
*
* @param bool $withoutP
*/
public function __construct(AbstractWriter $parentWriter, Element $element, $withoutP = false)
public function __construct(HTML $parentWriter, Element $element, $withoutP = false)
{
$this->parentWriter = $parentWriter;
$this->element = $element;
$this->withoutP = $withoutP;
$this->escaper = new Escaper();
}
/**

View File

@@ -17,7 +17,7 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\HTML;
/**
* Link element HTML writer.
@@ -39,11 +39,11 @@ class Link extends Text
$prefix = $this->element->isInternal() ? '#' : '';
$content = $this->writeOpening();
if (Settings::isOutputEscapingEnabled()) {
$content .= "<a href=\"{$prefix}{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>";
} else {
$content .= "<a href=\"{$prefix}{$this->element->getSource()}\">{$this->element->getText()}</a>";
}
$content .= "<a href=\"{$prefix}"
. $this->parentWriter->escapeHTML($this->element->getSource())
. '">'
. $this->parentWriter->escapeHTML($this->element->getText())
. '</a>';
$content .= $this->writeClosing();
return $content;

View File

@@ -17,7 +17,7 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\HTML;
/**
* ListItem element HTML writer.
@@ -37,11 +37,7 @@ class ListItem extends AbstractElement
return '';
}
if (Settings::isOutputEscapingEnabled()) {
$content = '<p>' . $this->escaper->escapeHtml($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
} else {
$content = '<p>' . $this->element->getTextObject()->getText() . '</p>' . PHP_EOL;
}
$content = '<p>' . $this->parentWriter->escapeHTML($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
return $content;
}

View File

@@ -17,6 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
/**
* PageBreak element HTML writer.
*
@@ -35,10 +37,13 @@ class PageBreak extends TextBreak
{
/** @var \PhpOffice\PhpWord\Writer\HTML $parentWriter Type hint */
$parentWriter = $this->parentWriter;
if ($parentWriter instanceof TCPDF) {
return '<br pagebreak="true"/>';
}
if ($parentWriter->isPdf()) {
return '<pagebreak style="page-break-before: always;" pagebreak="true"></pagebreak>';
}
return '';
return '<div style="page-break-before: always; height: 0; margin: 0; padding: 0; overflow: hidden;">&#160;</div>' . PHP_EOL;
}
}

View File

@@ -17,6 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Writer\HTML\Style\Table as TableStyleWriter;
/**
* Table element HTML writer.
*
@@ -39,7 +41,7 @@ class Table extends AbstractElement
$rows = $this->element->getRows();
$rowCount = count($rows);
if ($rowCount > 0) {
$content .= '<table' . self::getTableStyle($this->element->getStyle()) . '>' . PHP_EOL;
$content .= '<table' . $this->getTableStyle($this->element->getStyle()) . '>' . PHP_EOL;
for ($i = 0; $i < $rowCount; ++$i) {
/** @var \PhpOffice\PhpWord\Element\Row $row Type hint */
@@ -51,10 +53,10 @@ class Table extends AbstractElement
$rowCellCount = count($rowCells);
for ($j = 0; $j < $rowCellCount; ++$j) {
$cellStyle = $rowCells[$j]->getStyle();
$cellStyleCss = $this->getTableStyle($cellStyle);
$cellBgColor = $cellStyle->getBgColor();
$cellBgColor === 'auto' && $cellBgColor = null; // auto cannot be parsed to hexadecimal number
$cellFgColor = null;
if ($cellBgColor) {
if ($cellBgColor && $cellBgColor !== 'auto') {
$red = hexdec(substr($cellBgColor, 0, 2));
$green = hexdec(substr($cellBgColor, 2, 2));
$blue = hexdec(substr($cellBgColor, 4, 2));
@@ -67,12 +69,8 @@ class Table extends AbstractElement
if ($cellVMerge === 'restart') {
for ($k = $i + 1; $k < $rowCount; ++$k) {
$kRowCells = $rows[$k]->getCells();
if (isset($kRowCells[$j])) {
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
++$cellRowSpan;
} else {
break;
}
if (isset($kRowCells[$j]) && $kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
++$cellRowSpan;
} else {
break;
}
@@ -83,22 +81,18 @@ class Table extends AbstractElement
$cellTag = $tblHeader ? 'th' : 'td';
$cellColSpanAttr = (is_numeric($cellColSpan) && ($cellColSpan > 1) ? " colspan=\"{$cellColSpan}\"" : '');
$cellRowSpanAttr = ($cellRowSpan > 1 ? " rowspan=\"{$cellRowSpan}\"" : '');
$cellBgColorAttr = (null === $cellBgColor ? '' : " bgcolor=\"#{$cellBgColor}\"");
$cellFgColorAttr = (null === $cellFgColor ? '' : " color=\"#{$cellFgColor}\"");
$content .= "<{$cellTag}{$cellColSpanAttr}{$cellRowSpanAttr}{$cellBgColorAttr}{$cellFgColorAttr}>" . PHP_EOL;
$cellBgColorAttr = (empty($cellBgColor) ? '' : " bgcolor=\"#{$cellBgColor}\"");
$cellFgColorAttr = (empty($cellFgColor) ? '' : " color=\"#{$cellFgColor}\"");
$content .= "<{$cellTag}{$cellStyleCss}{$cellColSpanAttr}{$cellRowSpanAttr}{$cellBgColorAttr}{$cellFgColorAttr}>" . PHP_EOL;
$writer = new Container($this->parentWriter, $rowCells[$j]);
$content .= $writer->write();
if ($cellRowSpan > 1) {
// There shouldn't be any content in the subsequent merged cells, but lets check anyway
for ($k = $i + 1; $k < $rowCount; ++$k) {
$kRowCells = $rows[$k]->getCells();
if (isset($kRowCells[$j])) {
if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
$writer = new Container($this->parentWriter, $kRowCells[$j]);
$content .= $writer->write();
} else {
break;
}
if (isset($kRowCells[$j]) && $kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
$writer = new Container($this->parentWriter, $kRowCells[$j]);
$content .= $writer->write();
} else {
break;
}
@@ -118,26 +112,25 @@ class Table extends AbstractElement
/**
* Translates Table style in CSS equivalent.
*
* @param null|\PhpOffice\PhpWord\Style\Table|string $tableStyle
*
* @return string
* @param null|\PhpOffice\PhpWord\Style\Cell|\PhpOffice\PhpWord\Style\Table|string $tableStyle
*/
private function getTableStyle($tableStyle = null)
private function getTableStyle($tableStyle = null): string
{
if ($tableStyle == null) {
return '';
}
if (is_string($tableStyle)) {
$style = ' class="' . $tableStyle;
} else {
$style = ' style="';
if ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED) {
$style .= 'table-layout: fixed;';
} elseif ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_AUTO) {
$style .= 'table-layout: auto;';
}
return $style . '"';
}
return $style . '"';
$styleWriter = new TableStyleWriter($tableStyle);
$style = $styleWriter->write();
if ($style === '') {
return '';
}
return ' style="' . $style . '"';
}
}

View File

@@ -18,9 +18,10 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Element\TrackChange;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Writer\HTML;
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter;
@@ -66,19 +67,21 @@ class Text extends AbstractElement
*/
public function write()
{
$this->processFontStyle();
/** @var \PhpOffice\PhpWord\Element\Text $element Type hint */
$element = $this->element;
$this->getFontStyle();
$text = $this->parentWriter->escapeHTML($element->getText());
if (!$this->withoutP && !trim($text)) {
$text = '&nbsp;';
}
$content = '';
$content .= $this->writeOpening();
$content .= $this->openingText;
$content .= $this->openingTags;
if (Settings::isOutputEscapingEnabled()) {
$content .= $this->escaper->escapeHtml($element->getText());
} else {
$content .= $element->getText();
}
$content .= $text;
$content .= $this->closingTags;
$content .= $this->closingText;
$content .= $this->writeClosing();
@@ -115,10 +118,7 @@ class Text extends AbstractElement
{
$content = '';
if (!$this->withoutP) {
$style = '';
if (method_exists($this->element, 'getParagraphStyle')) {
$style = $this->getParagraphStyle();
}
$style = $this->getParagraphStyle();
$content .= "<p{$style}>";
}
@@ -141,12 +141,7 @@ class Text extends AbstractElement
$content .= $this->writeTrackChangeClosing();
if (!$this->withoutP) {
if (Settings::isOutputEscapingEnabled()) {
$content .= $this->escaper->escapeHtml($this->closingText);
} else {
$content .= $this->closingText;
}
$content .= $this->parentWriter->escapeHTML($this->closingText);
$content .= '</p>' . PHP_EOL;
}
@@ -228,6 +223,7 @@ class Text extends AbstractElement
$pStyleIsObject = ($paragraphStyle instanceof Paragraph);
if ($pStyleIsObject) {
$styleWriter = new ParagraphStyleWriter($paragraphStyle);
$styleWriter->setParentWriter($this->parentWriter);
$style = $styleWriter->write();
} elseif (is_string($paragraphStyle)) {
$style = $paragraphStyle;
@@ -243,22 +239,50 @@ class Text extends AbstractElement
/**
* Get font style.
*/
private function getFontStyle(): void
private function processFontStyle(): void
{
/** @var \PhpOffice\PhpWord\Element\Text $element Type hint */
$element = $this->element;
$style = '';
$attributeStyle = $attributeLang = '';
$lang = null;
$fontStyle = $element->getFontStyle();
$fStyleIsObject = ($fontStyle instanceof Font);
if ($fStyleIsObject) {
if ($fontStyle instanceof Font) {
// Attribute style
$styleWriter = new FontStyleWriter($fontStyle);
$style = $styleWriter->write();
} elseif (is_string($fontStyle)) {
$style = $fontStyle;
$fontCSS = $styleWriter->write();
if ($fontCSS) {
$attributeStyle = ' style="' . $fontCSS . '"';
}
// Attribute Lang
$lang = $fontStyle->getLang();
} elseif (!empty($fontStyle)) {
// Attribute class
$attributeStyle = ' class="' . $fontStyle . '"';
// Attribute Lang
/** @var Font $cssClassStyle */
$cssClassStyle = Style::getStyle($fontStyle);
if ($cssClassStyle !== null && method_exists($cssClassStyle, 'getLang')) {
$lang = $cssClassStyle->getLang();
}
}
if ($style) {
$attribute = $fStyleIsObject ? 'style' : 'class';
$this->openingTags = "<span {$attribute}=\"{$style}\">";
if ($lang) {
$attributeLang = $lang->getLatin();
if (!$attributeLang) {
$attributeLang = $lang->getEastAsia();
}
if (!$attributeLang) {
$attributeLang = $lang->getBidirectional();
}
if ($attributeLang) {
$attributeLang = " lang='$attributeLang'";
}
}
if ($attributeStyle || $attributeLang) {
$this->openingTags = "<span$attributeLang$attributeStyle>";
$this->closingTags = '</span>';
}
}

View File

@@ -17,7 +17,7 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\HTML;
/**
* TextRun element HTML writer.
@@ -41,10 +41,8 @@ class Title extends AbstractElement
$text = $this->element->getText();
if (is_string($text)) {
if (Settings::isOutputEscapingEnabled()) {
$text = $this->escaper->escapeHtml($text);
}
} elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
$text = $this->parentWriter->escapeHTML($text);
} else {
$writer = new Container($this->parentWriter, $text);
$text = $writer->write();
}

View File

@@ -17,9 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Part;
use Laminas\Escaper\Escaper;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Writer\AbstractWriter;
use PhpOffice\PhpWord\Writer\HTML;
/**
* @since 0.11.0
@@ -27,35 +26,22 @@ use PhpOffice\PhpWord\Writer\AbstractWriter;
abstract class AbstractPart
{
/**
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
* @var ?HTML
*/
private $parentWriter;
/**
* @var \Laminas\Escaper\Escaper
*/
protected $escaper;
public function __construct()
{
$this->escaper = new Escaper();
}
/**
* @return string
*/
abstract public function write();
/**
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
*/
public function setParentWriter(?AbstractWriter $writer = null): void
public function setParentWriter(?HTML $writer = null): void
{
$this->parentWriter = $writer;
}
/**
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
* @return HTML
*/
public function getParentWriter()
{

View File

@@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\HTML\Part;
use PhpOffice\PhpWord\Writer\HTML\Element\Container;
use PhpOffice\PhpWord\Writer\HTML\Element\TextRun as TextRunWriter;
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
/**
* RTF body part writer.
@@ -40,9 +41,18 @@ class Body extends AbstractPart
$content .= '<body>' . PHP_EOL;
$sections = $phpWord->getSections();
$secno = 0;
$isTCPDFWriter = $this->getParentWriter() instanceof TCPDF;
foreach ($sections as $section) {
++$secno;
if ($isTCPDFWriter && $secno > 1) {
$content .= "<div style=\"page: page$secno; page-break-before:always;\">" . PHP_EOL;
} else {
$content .= "<div style='page: page$secno'>" . PHP_EOL;
}
$writer = new Container($this->getParentWriter(), $section);
$content .= $writer->write();
$content .= '</div>' . PHP_EOL;
}
$content .= $this->writeNotes();

View File

@@ -18,12 +18,15 @@
namespace PhpOffice\PhpWord\Writer\HTML\Part;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Style\Table;
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Generic as GenericStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter;
use PhpOffice\PhpWord\Writer\HTML\Style\Table as TableStyleWriter;
/**
* RTF head part writer.
@@ -63,8 +66,10 @@ class Head extends AbstractPart
$method = 'get' . $key;
if ($docProps->$method() != '') {
$content .= '<meta name="' . $value . '"'
. ' content="' . (Settings::isOutputEscapingEnabled() ? $this->escaper->escapeHtmlAttr($docProps->$method()) : $docProps->$method()) . '"'
. ' />' . PHP_EOL;
. ' content="'
. $this->getParentWriter()->escapeHTML($docProps->$method())
. '"'
. ' />' . PHP_EOL;
}
}
$content .= $this->writeStyles();
@@ -75,19 +80,27 @@ class Head extends AbstractPart
/**
* Get styles.
*
* @return string
*/
private function writeStyles()
private function writeStyles(): string
{
$css = '<style>' . PHP_EOL;
// Default styles
$defaultStyles = [
'*' => [
'font-family' => Settings::getDefaultFontName(),
'font-size' => Settings::getDefaultFontSize() . 'pt',
],
$astarray = [
'font-family' => $this->getFontFamily(Settings::getDefaultFontName(), $this->getParentWriter()->getDefaultGenericFont()),
'font-size' => Settings::getDefaultFontSize() . 'pt',
];
// Mpdf sometimes needs separate tag for body; doesn't harm others.
$bodyarray = $astarray;
$defaultWhiteSpace = $this->getParentWriter()->getDefaultWhiteSpace();
if ($defaultWhiteSpace) {
$astarray['white-space'] = $defaultWhiteSpace;
}
foreach ([
'body' => $bodyarray,
'*' => $astarray,
'a.NoteRef' => [
'text-decoration' => 'none',
],
@@ -106,8 +119,7 @@ class Head extends AbstractPart
'td' => [
'border' => '1px solid black',
],
];
foreach ($defaultStyles as $selector => $style) {
] as $selector => $style) {
$styleWriter = new GenericStyleWriter($style);
$css .= $selector . ' {' . $styleWriter->write() . '}' . PHP_EOL;
}
@@ -116,23 +128,81 @@ class Head extends AbstractPart
$customStyles = Style::getStyles();
if (is_array($customStyles)) {
foreach ($customStyles as $name => $style) {
$styleParagraph = null;
if ($style instanceof Font) {
$styleWriter = new FontStyleWriter($style);
if ($style->getStyleType() == 'title') {
$name = str_replace('Heading_', 'h', $name);
$styleParagraph = $style->getParagraph();
$style = $styleParagraph;
} else {
$name = '.' . $name;
}
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
} elseif ($style instanceof Paragraph) {
}
if ($style instanceof Paragraph) {
$styleWriter = new ParagraphStyleWriter($style);
$name = '.' . $name;
$styleWriter->setParentWriter($this->getParentWriter());
if (!$styleParagraph) {
$name = '.' . $name;
}
if ($name === '.Normal') {
$name = "p, $name";
}
$css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
}
if ($style instanceof Table) {
$styleWriter = new TableStyleWriter($style);
$css .= ".{$name} {" . $styleWriter->write() . '}' . PHP_EOL;
}
}
}
$css .= 'body > div + div {page-break-before: always;}' . PHP_EOL;
$css .= 'div > *:first-child {page-break-before: auto;}' . PHP_EOL;
$sectionNum = 0;
foreach ($this->getParentWriter()->getPhpWord()->getSections() as $section) {
++$sectionNum;
$css .= "@page page$sectionNum {";
$paperSize = $section->getStyle()->getPaperSize();
$orientation = $section->getStyle()->getOrientation();
if ($this->getParentWriter()->isPdf()) {
if ($orientation === 'landscape') {
$paperSize .= '-L';
}
$css .= "sheet-size: $paperSize; ";
} else {
$css .= "size: $paperSize $orientation; ";
}
$css .= 'margin-right: ' . (string) ($section->getStyle()->getMarginRight() / Converter::INCH_TO_TWIP) . 'in; ';
$css .= 'margin-left: ' . (string) ($section->getStyle()->getMarginLeft() / Converter::INCH_TO_TWIP) . 'in; ';
$css .= 'margin-top: ' . (string) ($section->getStyle()->getMarginTop() / Converter::INCH_TO_TWIP) . 'in; ';
$css .= 'margin-bottom: ' . (string) ($section->getStyle()->getMarginBottom() / Converter::INCH_TO_TWIP) . 'in; ';
$css .= '}' . PHP_EOL;
}
$css .= '</style>' . PHP_EOL;
return $css;
}
/**
* Set font and alternates for css font-family.
*/
private function getFontFamily(string $font, string $genericFont): string
{
if (empty($font)) {
return '';
}
$fontfamily = "'" . htmlspecialchars($font, ENT_QUOTES, 'UTF-8') . "'";
if (!empty($genericFont)) {
$fontfamily .= ", $genericFont";
}
return $fontfamily;
}
}

View File

@@ -17,7 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Style;
use PhpOffice\PhpWord\Style\AbstractStyle as Style;
use PhpOffice\PhpWord\Style\AbstractStyle as StyleAbstract;
use PhpOffice\PhpWord\Writer\HTML;
/**
* Style writer.
@@ -29,26 +30,28 @@ abstract class AbstractStyle
/**
* Parent writer.
*
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
* @var HTML
*/
private $parentWriter;
/**
* Style.
*
* @var array|\PhpOffice\PhpWord\Style\AbstractStyle
* @var null|array|StyleAbstract
*/
private $style;
/**
* Write style.
*
* @return mixed
*/
abstract public function write();
/**
* Create new instance.
*
* @param array|\PhpOffice\PhpWord\Style\AbstractStyle $style
* @param array|StyleAbstract $style
*/
public function __construct($style = null)
{
@@ -58,7 +61,7 @@ abstract class AbstractStyle
/**
* Set parent writer.
*
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
* @param HTML $writer
*/
public function setParentWriter($writer): void
{
@@ -68,7 +71,7 @@ abstract class AbstractStyle
/**
* Get parent writer.
*
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
* @return HTML
*/
public function getParentWriter()
{
@@ -78,11 +81,11 @@ abstract class AbstractStyle
/**
* Get style.
*
* @return array|\PhpOffice\PhpWord\Style\AbstractStyle $style
* @return null|array|string|StyleAbstract
*/
public function getStyle()
{
if (!$this->style instanceof Style && !is_array($this->style)) {
if (!$this->style instanceof StyleAbstract && !is_array($this->style)) {
return '';
}

View File

@@ -39,14 +39,14 @@ class Font extends AbstractStyle
}
$css = [];
$font = $style->getName();
$font = $this->getFontFamily($style->getName(), $style->getFallbackFont());
$size = $style->getSize();
$color = $style->getColor();
$fgColor = $style->getFgColor();
$underline = $style->getUnderline() != FontStyle::UNDERLINE_NONE;
$lineThrough = $style->isStrikethrough() || $style->isDoubleStrikethrough();
$css['font-family'] = $this->getValueIf($font !== null, "'{$font}'");
$css['font-family'] = $this->getValueIf(!empty($font), $font);
$css['font-size'] = $this->getValueIf($size !== null, "{$size}pt");
$css['color'] = $this->getValueIf($color !== null, "#{$color}");
$css['background'] = $this->getValueIf($fgColor != '', $fgColor);
@@ -61,10 +61,35 @@ class Font extends AbstractStyle
$css['text-transform'] = $this->getValueIf($style->isAllCaps(), 'uppercase');
$css['font-variant'] = $this->getValueIf($style->isSmallCaps(), 'small-caps');
$css['display'] = $this->getValueIf($style->isHidden(), 'none');
$whitespace = $style->getWhiteSpace();
if ($whitespace) {
$css['white-space'] = $whitespace;
}
$spacing = $style->getSpacing();
$css['letter-spacing'] = $this->getValueIf(null !== $spacing, ($spacing / 20) . 'pt');
if ($style->isRTL()) {
$css['direction'] = 'rtl';
} elseif ($style->isRTL() === false) {
$css['direction'] = 'ltr';
}
return $this->assembleCss($css);
}
/**
* Set font and alternates for css font-family.
*/
private function getFontFamily(?string $font, string $genericFont): string
{
if (empty($font)) {
return '';
}
$fontfamily = "'" . htmlspecialchars($font, ENT_QUOTES, 'UTF-8') . "'";
if (!empty($genericFont)) {
$fontfamily .= ", $genericFont";
}
return $fontfamily;
}
}

View File

@@ -17,7 +17,9 @@
namespace PhpOffice\PhpWord\Writer\HTML\Style;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\Writer\PDF\TCPDF;
/**
* Paragraph style HTML writer.
@@ -49,6 +51,9 @@ class Paragraph extends AbstractStyle
break;
case Jc::END:
$textAlign = $style->isBidi() ? 'left' : 'right';
break;
case Jc::MEDIUM_KASHIDA:
case Jc::HIGH_KASHIDA:
case Jc::LOW_KASHIDA:
@@ -63,9 +68,13 @@ class Paragraph extends AbstractStyle
$textAlign = 'justify';
break;
default: //all others, align left
case Jc::LEFT:
$textAlign = 'left';
break;
default: //all others, including Jc::START
$textAlign = $style->isBidi() ? 'right' : 'left';
break;
}
@@ -79,9 +88,32 @@ class Paragraph extends AbstractStyle
$after = $spacing->getAfter();
$css['margin-top'] = $this->getValueIf(null !== $before, ($before / 20) . 'pt');
$css['margin-bottom'] = $this->getValueIf(null !== $after, ($after / 20) . 'pt');
} else {
$css['margin-top'] = '0';
$css['margin-bottom'] = '0';
}
// Line Height
$lineHeight = $style->getLineHeight();
if (!empty($lineHeight)) {
$css['line-height'] = $lineHeight;
}
// Indentation (Margin)
$indentation = $style->getIndentation();
if ($indentation) {
$inches = $indentation->getLeft() * 1.0 / Converter::INCH_TO_TWIP;
$css[$this->getParentWriter() instanceof TCPDF ? 'text-indent' : 'margin-left'] = ((string) $inches) . 'in';
$inches = $indentation->getRight() * 1.0 / Converter::INCH_TO_TWIP;
$css['margin-right'] = ((string) $inches) . 'in';
}
// Page Break Before
if ($style->hasPageBreakBefore()) {
$css['page-break-before'] = 'always';
}
// Bidirectional
if ($style->isBidi()) {
$css['direction'] = 'rtl';
}
return $this->assembleCss($css);

View File

@@ -0,0 +1,82 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
declare(strict_types=1);
namespace PhpOffice\PhpWord\Writer\HTML\Style;
use PhpOffice\PhpWord\Style\Cell as StyleCell;
use PhpOffice\PhpWord\Style\Table as StyleTable;
class Table extends AbstractStyle
{
/**
* @return string
*/
public function write()
{
$style = $this->getStyle();
if (!$style instanceof StyleTable && !$style instanceof StyleCell) {
return '';
}
$css = [];
if (is_object($style) && method_exists($style, 'getLayout')) {
if ($style->getLayout() == StyleTable::LAYOUT_FIXED) {
$css['table-layout'] = 'fixed';
} elseif ($style->getLayout() == StyleTable::LAYOUT_AUTO) {
$css['table-layout'] = 'auto';
}
}
if (is_object($style) && method_exists($style, 'isBidiVisual')) {
if ($style->isBidiVisual()) {
$css['direction'] = 'rtl';
}
}
foreach (['Top', 'Left', 'Bottom', 'Right'] as $direction) {
$method = 'getBorder' . $direction . 'Style';
if (method_exists($style, $method)) {
$outval = $style->{$method}();
if ($outval === 'single') {
$outval = 'solid';
}
if (is_string($outval) && 1 == preg_match('/^[a-z]+$/', $outval)) {
$css['border-' . lcfirst($direction) . '-style'] = $outval;
}
}
$method = 'getBorder' . $direction . 'Color';
if (method_exists($style, $method)) {
$outval = $style->{$method}();
if (is_string($outval) && 1 == preg_match('/^[a-z]+$/', $outval)) {
$css['border-' . lcfirst($direction) . '-color'] = $outval;
}
}
$method = 'getBorder' . $direction . 'Size';
if (method_exists($style, $method)) {
$outval = $style->{$method}();
if (is_numeric($outval)) {
// size is in twips - divide by 20 to get points
$css['border-' . lcfirst($direction) . '-width'] = ((string) ($outval / 20)) . 'pt';
}
}
}
return $this->assembleCss($css);
}
}

View File

@@ -17,8 +17,12 @@
namespace PhpOffice\PhpWord\Writer;
use PhpOffice\Math\Writer\MathML;
use PhpOffice\PhpWord\Element\AbstractElement;
use PhpOffice\PhpWord\Element\Formula;
use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\ODText\Part\AbstractPart;
/**
* ODText writer.
@@ -27,10 +31,13 @@ use PhpOffice\PhpWord\PhpWord;
*/
class ODText extends AbstractWriter implements WriterInterface
{
/**
* @var AbstractElement[]
*/
protected $objects = [];
/**
* Create new ODText writer.
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*/
public function __construct(?PhpWord $phpWord = null)
{
@@ -61,10 +68,8 @@ class ODText extends AbstractWriter implements WriterInterface
/**
* Save PhpWord to file.
*
* @param string $filename
*/
public function save($filename = null): void
public function save(string $filename): void
{
$filename = $this->getTempFile($filename);
$zip = $this->getZipArchive($filename);
@@ -77,8 +82,28 @@ class ODText extends AbstractWriter implements WriterInterface
// Write parts
foreach ($this->parts as $partName => $fileName) {
if ($fileName != '') {
$zip->addFromString($fileName, $this->getWriterPart($partName)->write());
if ($fileName === '') {
continue;
}
$part = $this->getWriterPart($partName);
if (!$part instanceof AbstractPart) {
continue;
}
$part->setObjects($this->objects);
$zip->addFromString($fileName, $part->write());
$this->objects = $part->getObjects();
}
// Write objects charts
if (!empty($this->objects)) {
$writer = new MathML();
foreach ($this->objects as $idxObject => $object) {
if ($object instanceof Formula) {
$zip->addFromString('Formula' . $idxObject . '/content.xml', $writer->write($object->getMath()));
}
}
}

View File

@@ -15,7 +15,7 @@
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
// Not fully implemented
// - supports only PAGE and NUMPAGES
// - supports only PAGE, NUMPAGES, DATE and FILENAME
// - supports only default formats and options
// - supports style only if specified by name
// - spaces before and after field may be dropped
@@ -44,6 +44,7 @@ class Field extends Text
case 'date':
case 'page':
case 'numpages':
case 'filename':
$this->writeDefault($element, $type);
break;
@@ -78,6 +79,18 @@ class Field extends Text
$xmlWriter->startElement('text:page-count');
$xmlWriter->endElement();
break;
case 'filename':
$xmlWriter->startElement('text:file-name');
$xmlWriter->writeAttribute('text:fixed', 'false');
$options = $element->getOptions();
if ($options != null && in_array('Path', $options)) {
$xmlWriter->writeAttribute('text:display', 'full');
} else {
$xmlWriter->writeAttribute('text:display', 'name');
}
$xmlWriter->endElement();
break;
}
$xmlWriter->endElement(); // text:span

View File

@@ -0,0 +1,74 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Writer\ODText\Element;
use PhpOffice\PhpWord\Element\Formula as ElementFormula;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\Writer\ODText\Part\AbstractPart;
/**
* Formula element writer.
*
* @since 0.10.0
*/
class Formula extends AbstractElement
{
/**
* Write element.
*/
public function write(): void
{
$xmlWriter = $this->getXmlWriter();
$element = $this->getElement();
if (!$element instanceof ElementFormula) {
return;
}
$part = $this->getPart();
if (!$part instanceof AbstractPart) {
return;
}
$objectIdx = $part->addObject($element);
//$style = $element->getStyle();
//$width = Converter::pixelToCm($style->getWidth());
//$height = Converter::pixelToCm($style->getHeight());
$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'OB' . $objectIdx);
$xmlWriter->startElement('draw:frame');
$xmlWriter->writeAttribute('draw:name', $element->getElementId());
$xmlWriter->writeAttribute('text:anchor-type', 'as-char');
//$xmlWriter->writeAttribute('svg:width', $width . 'cm');
//$xmlWriter->writeAttribute('svg:height', $height . 'cm');
//$xmlWriter->writeAttribute('draw:z-index', $mediaIndex);
$xmlWriter->startElement('draw:object');
$xmlWriter->writeAttribute('xlink:href', 'Formula' . $objectIdx);
$xmlWriter->writeAttribute('xlink:type', 'simple');
$xmlWriter->writeAttribute('xlink:show', 'embed');
$xmlWriter->writeAttribute('xlink:actuate', 'onLoad');
$xmlWriter->endElement(); // draw:object
$xmlWriter->endElement(); // draw:frame
$xmlWriter->endElement(); // text:p
}
}

View File

@@ -44,7 +44,7 @@ class Table extends AbstractElement
if ($rowCount > 0) {
$xmlWriter->startElement('table:table');
$xmlWriter->writeAttribute('table:name', $element->getElementId());
$xmlWriter->writeAttribute('table:style', $element->getElementId());
$xmlWriter->writeAttribute('table:style-name', $element->getElementId());
// Write columns
$this->writeColumns($xmlWriter, $element);

View File

@@ -55,7 +55,8 @@ class Title extends AbstractElement
$text = $element->getText();
if (is_string($text)) {
$this->writeText($text);
} elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
}
if ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
$containerWriter = new Container($xmlWriter, $text);
$containerWriter->write();
}

View File

@@ -17,6 +17,7 @@
namespace PhpOffice\PhpWord\Writer\ODText\Part;
use PhpOffice\PhpWord\Element\AbstractElement;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Style;
@@ -28,6 +29,11 @@ use PhpOffice\PhpWord\Writer\Word2007\Part\AbstractPart as Word2007AbstractPart;
*/
abstract class AbstractPart extends Word2007AbstractPart
{
/**
* @var AbstractElement[]
*/
protected $objects = [];
/**
* @var string Date format
*/
@@ -102,4 +108,29 @@ abstract class AbstractPart extends Word2007AbstractPart
}
$xmlWriter->endElement();
}
public function addObject(AbstractElement $object): int
{
$this->objects[] = $object;
return count($this->objects) - 1;
}
/**
* @param AbstractElement[] $objects
*/
public function setObjects(array $objects): self
{
$this->objects = $objects;
return $this;
}
/**
* @return AbstractElement[]
*/
public function getObjects(): array
{
return $this->objects;
}
}

View File

@@ -135,8 +135,11 @@ class Content extends AbstractPart
$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'SB' . $section->getSectionId());
$xmlWriter->endElement();
$containerWriter = new Container($xmlWriter, $section);
$containerWriter->setPart($this);
$containerWriter->write();
$xmlWriter->endElement(); // text:section
}
@@ -198,7 +201,7 @@ class Content extends AbstractPart
}
foreach ($styles as $style) {
$sty = $style->getStyleName();
$sty = (string) $style->getStyleName();
if (substr($sty, 0, 8) === 'Heading_') {
$style = new Paragraph();
$style->setStyleName('HD' . substr($sty, 8));
@@ -280,7 +283,6 @@ class Content extends AbstractPart
$sty->setAlignment($style->getAlignment());
$this->imageParagraphStyles[] = $sty;
} elseif ($element instanceof Table) {
/** @var \PhpOffice\PhpWord\Style\Table $style */
$style = $element->getStyle();
if (is_string($style)) {
$style = Style::getStyle($style);

View File

@@ -17,7 +17,9 @@
namespace PhpOffice\PhpWord\Writer\ODText\Part;
use PhpOffice\PhpWord\Element\Formula;
use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\Writer\ODText;
/**
* ODText manifest part writer: META-INF/manifest.xml.
@@ -31,7 +33,6 @@ class Manifest extends AbstractPart
*/
public function write()
{
$parts = ['content.xml', 'meta.xml', 'styles.xml'];
$xmlWriter = $this->getXmlWriter();
$xmlWriter->startDocument('1.0', 'UTF-8');
@@ -46,7 +47,7 @@ class Manifest extends AbstractPart
$xmlWriter->endElement();
// Parts
foreach ($parts as $part) {
foreach (['content.xml', 'meta.xml', 'styles.xml'] as $part) {
$xmlWriter->startElement('manifest:file-entry');
$xmlWriter->writeAttribute('manifest:media-type', 'text/xml');
$xmlWriter->writeAttribute('manifest:full-path', $part);
@@ -64,6 +65,20 @@ class Manifest extends AbstractPart
}
}
foreach ($this->getObjects() as $idxObject => $object) {
if ($object instanceof Formula) {
$xmlWriter->startElement('manifest:file-entry');
$xmlWriter->writeAttribute('manifest:full-path', 'Formula' . $idxObject . '/content.xml');
$xmlWriter->writeAttribute('manifest:media-type', 'text/xml');
$xmlWriter->endElement();
$xmlWriter->startElement('manifest:file-entry');
$xmlWriter->writeAttribute('manifest:full-path', 'Formula' . $idxObject . '/');
$xmlWriter->writeAttribute('manifest:version', '1.2');
$xmlWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.formula');
$xmlWriter->endElement();
}
}
$xmlWriter->endElement(); // manifest:manifest
return $xmlWriter->getData();

View File

@@ -17,7 +17,10 @@
namespace PhpOffice\PhpWord\Writer\ODText\Style;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\Style;
/**
* Font style writer.
@@ -26,6 +29,16 @@ use PhpOffice\PhpWord\Shared\Converter;
*/
class Paragraph extends AbstractStyle
{
private const BIDI_MAP = [
Jc::END => Jc::LEFT,
Jc::START => Jc::RIGHT,
];
private const NON_BIDI_MAP = [
Jc::START => Jc::LEFT,
Jc::END => Jc::RIGHT,
];
/**
* Write style.
*/
@@ -42,7 +55,7 @@ class Paragraph extends AbstractStyle
$xmlWriter->startElement('style:style');
$styleName = $style->getStyleName();
$styleName = (string) $style->getStyleName();
$styleAuto = false;
$mpm = '';
$psm = '';
@@ -111,8 +124,18 @@ class Paragraph extends AbstractStyle
$xmlWriter->writeAttributeIf($marginTop !== null, 'fo:margin-top', ($marginTop / $twipToPoint) . 'pt');
$xmlWriter->writeAttributeIf($marginBottom !== null, 'fo:margin-bottom', ($marginBottom / $twipToPoint) . 'pt');
}
$temp = $style->getAlignment();
$xmlWriter->writeAttributeIf($temp !== '', 'fo:text-align', $temp);
$alignment = $style->getAlignment();
$bidi = $style->isBidi();
$defaultRtl = Settings::isDefaultRtl();
if ($alignment === '' && $bidi !== null) {
$alignment = Jc::START;
}
if ($bidi) {
$alignment = self::BIDI_MAP[$alignment] ?? $alignment;
} elseif ($defaultRtl !== null) {
$alignment = self::NON_BIDI_MAP[$alignment] ?? $alignment;
}
$xmlWriter->writeAttributeIf($alignment !== '', 'fo:text-align', $alignment);
$temp = $style->getLineHeight();
$xmlWriter->writeAttributeIf($temp !== null, 'fo:line-height', ((string) ($temp * 100) . '%'));
$xmlWriter->writeAttributeIf($style->hasPageBreakBefore() === true, 'fo:break-before', 'page');

View File

@@ -20,6 +20,7 @@ namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Writer\PDF\AbstractRenderer;
/**
* PDF Writer.
@@ -71,6 +72,16 @@ class PDF
// throw new Exception("PDF Rendering library has not been defined.");
// }
return call_user_func_array([$this->renderer, $name], $arguments);
return call_user_func_array([$this->getRenderer(), $name], $arguments);
}
public function save(string $filename): void
{
$this->getRenderer()->save($filename);
}
public function getRenderer(): AbstractRenderer
{
return $this->renderer;
}
}

View File

@@ -81,6 +81,7 @@ abstract class AbstractRenderer extends HTML
public function __construct(PhpWord $phpWord)
{
parent::__construct($phpWord);
$this->isPdf = true;
if ($this->includeFile != null) {
$includeFile = Settings::getPdfRendererPath() . '/' . $this->includeFile;
if (file_exists($includeFile)) {
@@ -93,6 +94,12 @@ abstract class AbstractRenderer extends HTML
// @codeCoverageIgnoreEnd
}
}
// Configuration
$options = Settings::getPdfRendererOptions();
if (!empty($options['font'])) {
$this->setFont($options['font']);
}
}
/**
@@ -187,7 +194,6 @@ abstract class AbstractRenderer extends HTML
throw new Exception("Could not open file $filename for writing.");
}
// @codeCoverageIgnoreEnd
$this->isPdf = true;
return $fileHandle;
}

View File

@@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Writer\PDF;
use Dompdf\Dompdf as DompdfLib;
use Dompdf\Options;
use PhpOffice\PhpWord\Writer\WriterInterface;
/**
@@ -42,15 +43,18 @@ class DomPDF extends AbstractRenderer implements WriterInterface
*/
protected function createExternalWriterInstance()
{
return new DompdfLib();
$options = new Options();
if ($this->getFont()) {
$options->set('defaultFont', $this->getFont());
}
return new DompdfLib($options);
}
/**
* Save PhpWord to file.
*
* @param string $filename Name of the file to save as
*/
public function save($filename = null): void
public function save(string $filename): void
{
$fileHandle = parent::prepareForSave($filename);

View File

@@ -29,6 +29,9 @@ use PhpOffice\PhpWord\Writer\WriterInterface;
*/
class MPDF extends AbstractRenderer implements WriterInterface
{
public const SIMULATED_BODY_START = '<!-- simulated body start -->';
private const BODY_TAG = '<body>';
/**
* Overridden to set the correct includefile, only needed for MPDF 5.
*
@@ -46,21 +49,24 @@ class MPDF extends AbstractRenderer implements WriterInterface
/**
* Gets the implementation of external PDF library that should be used.
*
* @return Mpdf implementation
* @return \Mpdf\Mpdf implementation
*/
protected function createExternalWriterInstance()
{
$mPdfClass = $this->getMPdfClassName();
return new $mPdfClass();
$options = [];
if ($this->getFont()) {
$options['default_font'] = $this->getFont();
}
return new $mPdfClass($options);
}
/**
* Save PhpWord to file.
*
* @param string $filename Name of the file to save as
*/
public function save($filename = null): void
public function save(string $filename): void
{
$fileHandle = parent::prepareForSave($filename);
@@ -82,7 +88,24 @@ class MPDF extends AbstractRenderer implements WriterInterface
$pdf->setKeywords($docProps->getKeywords());
$pdf->setCreator($docProps->getCreator());
$pdf->writeHTML($this->getContent());
$html = $this->getContent();
$bodyLocation = strpos($html, self::SIMULATED_BODY_START);
if ($bodyLocation === false) {
$bodyLocation = strpos($html, self::BODY_TAG);
if ($bodyLocation !== false) {
$bodyLocation += strlen(self::BODY_TAG);
}
}
// Make sure first data presented to Mpdf includes body tag
// (and any htmlpageheader/htmlpagefooter tags)
// so that Mpdf doesn't parse it as content. Issue 2432.
if ($bodyLocation !== false) {
$pdf->WriteHTML(substr($html, 0, $bodyLocation));
$html = substr($html, $bodyLocation);
}
foreach (explode("\n", $html) as $line) {
$pdf->WriteHTML("$line\n");
}
// Write to file
fwrite($fileHandle, $pdf->output($filename, 'S'));

View File

@@ -17,7 +17,11 @@
namespace PhpOffice\PhpWord\Writer\PDF;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Writer\WriterInterface;
use TCPDF as TCPDFBase;
/**
* TCPDF writer.
@@ -42,24 +46,56 @@ class TCPDF extends AbstractRenderer implements WriterInterface
* @param string $unit Unit measure
* @param string $paperSize Paper size
*
* @return \TCPDF implementation
* @return TCPDFBase implementation
*/
protected function createExternalWriterInstance($orientation, $unit, $paperSize)
{
return new \TCPDF($orientation, $unit, $paperSize);
$instance = new TCPDFBase($orientation, $unit, $paperSize);
if ($this->getFont()) {
$instance->setFont($this->getFont(), $instance->getFontStyle(), $instance->getFontSizePt());
}
return $instance;
}
/**
* Overwriteable function to allow user to extend TCPDF.
* There should always be an AddPage call, preceded or followed
* by code to customize TCPDF configuration.
* The customization below sets vertical spacing
* between paragaraphs when the user has
* explicitly set those values to numeric in default style.
*/
protected function prepareToWrite(TCPDFBase $pdf): void
{
$pdf->AddPage();
$customStyles = Style::getStyles();
$normal = $customStyles['Normal'] ?? null;
if ($normal instanceof Style\Paragraph) {
$before = $normal->getSpaceBefore();
$after = $normal->getSpaceAfter();
if (is_numeric($before) && is_numeric($after)) {
$height = $normal->getLineHeight() ?? '';
$pdf->setHtmlVSpace([
'p' => [
['n' => $before, 'h' => $height],
['n' => $after, 'h' => $height],
],
]);
}
}
}
/**
* Save PhpWord to file.
*
* @param string $filename Name of the file to save as
*/
public function save($filename = null): void
public function save(string $filename): void
{
$fileHandle = parent::prepareForSave($filename);
// PDF settings
$paperSize = 'A4';
$paperSize = strtoupper(Settings::getDefaultPaper());
$orientation = 'P';
// Create PDF
@@ -67,8 +103,8 @@ class TCPDF extends AbstractRenderer implements WriterInterface
$pdf->setFontSubsetting(false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont($this->getFont());
$this->prepareToWrite($pdf);
$pdf->writeHTML($this->getContent());
// Write document properties

View File

@@ -35,8 +35,6 @@ class RTF extends AbstractWriter implements WriterInterface
/**
* Create new instance.
*
* @param \PhpOffice\PhpWord\PhpWord $phpWord
*/
public function __construct(?PhpWord $phpWord = null)
{
@@ -56,10 +54,8 @@ class RTF extends AbstractWriter implements WriterInterface
/**
* Save content to file.
*
* @param string $filename
*/
public function save($filename = null): void
public function save(string $filename): void
{
$this->writeFile($this->openFile($filename), $this->getContent());
}

View File

@@ -25,7 +25,6 @@ use PhpOffice\PhpWord\Style;
use PhpOffice\PhpWord\Style\Font as FontStyle;
use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle;
use PhpOffice\PhpWord\Writer\AbstractWriter;
use PhpOffice\PhpWord\Writer\HTML\Element\AbstractElement as HTMLAbstractElement;
use PhpOffice\PhpWord\Writer\RTF\Style\Font as FontStyleWriter;
use PhpOffice\PhpWord\Writer\RTF\Style\Paragraph as ParagraphStyleWriter;
@@ -34,8 +33,36 @@ use PhpOffice\PhpWord\Writer\RTF\Style\Paragraph as ParagraphStyleWriter;
*
* @since 0.11.0
*/
abstract class AbstractElement extends HTMLAbstractElement
abstract class AbstractElement
{
/**
* Parent writer.
*
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
*/
protected $parentWriter;
/**
* Element.
*
* @var \PhpOffice\PhpWord\Element\AbstractElement
*/
protected $element;
/**
* Without paragraph.
*
* @var bool
*/
protected $withoutP = false;
/**
* Write element.
*
* @return string
*/
abstract public function write();
/**
* Font style.
*
@@ -50,10 +77,16 @@ abstract class AbstractElement extends HTMLAbstractElement
*/
protected $paragraphStyle;
public function __construct(AbstractWriter $parentWriter, Element $element, $withoutP = false)
{
parent::__construct($parentWriter, $element, $withoutP);
/**
* @var \PhpOffice\PhpWord\Escaper\EscaperInterface
*/
protected $escaper;
public function __construct(AbstractWriter $parentWriter, Element $element, bool $withoutP = false)
{
$this->parentWriter = $parentWriter;
$this->element = $element;
$this->withoutP = $withoutP;
$this->escaper = new Rtf();
}

View File

@@ -17,14 +17,14 @@
namespace PhpOffice\PhpWord\Writer\RTF\Element;
use PhpOffice\PhpWord\Writer\HTML\Element\Container as HTMLContainer;
use PhpOffice\PhpWord\Element\AbstractContainer as ContainerElement;
/**
* Container element RTF writer.
*
* @since 0.11.0
*/
class Container extends HTMLContainer
class Container extends AbstractElement
{
/**
* Namespace; Can't use __NAMESPACE__ in inherited class (RTF).
@@ -32,4 +32,33 @@ class Container extends HTMLContainer
* @var string
*/
protected $namespace = 'PhpOffice\\PhpWord\\Writer\\RTF\\Element';
/**
* Write container.
*
* @return string
*/
public function write()
{
$container = $this->element;
if (!$container instanceof ContainerElement) {
return '';
}
$containerClass = substr(get_class($container), strrpos(get_class($container), '\\') + 1);
$withoutP = in_array($containerClass, ['TextRun', 'Footnote', 'Endnote']) ? true : false;
$content = '';
$elements = $container->getElements();
foreach ($elements as $element) {
$elementClass = get_class($element);
$writerClass = str_replace('PhpOffice\\PhpWord\\Element', $this->namespace, $elementClass);
if (class_exists($writerClass)) {
/** @var AbstractElement $writer Type hint */
$writer = new $writerClass($this->parentWriter, $element, $withoutP);
$content .= $writer->write();
}
}
return $content;
}
}

View File

@@ -17,10 +17,12 @@
namespace PhpOffice\PhpWord\Writer\RTF\Element;
use PhpOffice\PhpWord\Element\Field as ElementField;
/**
* Field element writer.
*
* Note: for now, only date, page and numpages fields are implemented for RTF.
* Note: for now, only date, page, numpages and filename fields are implemented for RTF.
*/
class Field extends Text
{
@@ -30,7 +32,7 @@ class Field extends Text
public function write()
{
$element = $this->element;
if (!$element instanceof \PhpOffice\PhpWord\Element\Field) {
if (!$element instanceof ElementField) {
return;
}
@@ -66,7 +68,18 @@ class Field extends Text
return 'NUMPAGES';
}
protected function writeDate(\PhpOffice\PhpWord\Element\Field $element)
protected function writeFilename(ElementField $element): string
{
$content = 'FILENAME';
$options = $element->getOptions();
if ($options != null && in_array('Path', $options)) {
$content .= ' \\\\p';
}
return $content;
}
protected function writeDate(ElementField $element)
{
$content = '';
$content .= 'DATE';

View File

@@ -20,6 +20,8 @@ namespace PhpOffice\PhpWord\Writer\RTF\Element;
use PhpOffice\PhpWord\Element\Cell as CellElement;
use PhpOffice\PhpWord\Element\Row as RowElement;
use PhpOffice\PhpWord\Element\Table as TableElement;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style;
/**
* Table element RTF writer.
@@ -45,6 +47,9 @@ class Table extends AbstractElement
}
$content = '';
$style = $this->element->getStyle();
$bidiStyle = (is_object($style) && method_exists($style, 'isBidiVisual')) ? $style->isBidiVisual() : Settings::isDefaultRtl();
$bidi = $bidiStyle ? '\rtlrow' : '';
$rows = $element->getRows();
$rowCount = count($rows);
@@ -52,7 +57,7 @@ class Table extends AbstractElement
$content .= '\pard' . PHP_EOL;
for ($i = 0; $i < $rowCount; ++$i) {
$content .= '\trowd ';
$content .= "\\trowd$bidi ";
$content .= $this->writeRowDef($rows[$i]);
$content .= PHP_EOL;
$content .= $this->writeRow($rows[$i]);

View File

@@ -71,7 +71,7 @@ class Title extends Text
$style = $element->getStyle();
if (is_string($style)) {
$style = str_replace('Heading', '', $style);
if (is_numeric($style)) {
if ("$style" !== '') {
$style = (int) $style - 1;
if ($style >= 0 && $style <= 8) {
$content .= '{\\outlinelevel' . $style;

View File

@@ -27,7 +27,7 @@ use PhpOffice\PhpWord\Writer\AbstractWriter;
abstract class AbstractPart
{
/**
* @var \PhpOffice\PhpWord\Writer\AbstractWriter
* @var \PhpOffice\PhpWord\Writer\RTF
*/
private $parentWriter;
@@ -47,7 +47,7 @@ abstract class AbstractPart
abstract public function write();
/**
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
* @param \PhpOffice\PhpWord\Writer\RTF $writer
*/
public function setParentWriter(?AbstractWriter $writer = null): void
{
@@ -55,7 +55,7 @@ abstract class AbstractPart
}
/**
* @return \PhpOffice\PhpWord\Writer\AbstractWriter
* @return \PhpOffice\PhpWord\Writer\RTF
*/
public function getParentWriter()
{

View File

@@ -148,7 +148,13 @@ class Document extends AbstractPart
$sections = $this->getParentWriter()->getPhpWord()->getSections();
$evenOdd = $this->getParentWriter()->getPhpWord()->getSettings()->hasEvenAndOddHeaders();
$sectOwed = false;
foreach ($sections as $section) {
if ($sectOwed) {
$content .= '\sect' . PHP_EOL;
} else {
$sectOwed = true;
}
$styleWriter = new SectionStyleWriter($section->getStyle());
$styleWriter->setParentWriter($this->getParentWriter());
$content .= $styleWriter->write();
@@ -197,8 +203,6 @@ class Document extends AbstractPart
$elementWriter = new Container($this->getParentWriter(), $section);
$content .= $elementWriter->write();
$content .= '\sect' . PHP_EOL;
}
return $content;

View File

@@ -17,13 +17,91 @@
namespace PhpOffice\PhpWord\Writer\RTF\Style;
use PhpOffice\PhpWord\Writer\HTML\Style\AbstractStyle as HTMLAbstractStyle;
use PhpOffice\PhpWord\Style\AbstractStyle as StyleAbstract;
use PhpOffice\PhpWord\Writer\RTF;
/**
* Abstract RTF style writer.
*
* @since 0.11.0
*/
abstract class AbstractStyle extends HTMLAbstractStyle
abstract class AbstractStyle
{
/**
* Parent writer.
*
* @var RTF
*/
private $parentWriter;
/**
* Style.
*
* @var null|array|StyleAbstract
*/
private $style;
/**
* Write style.
*
* @return mixed
*/
abstract public function write();
/**
* Create new instance.
*
* @param array|StyleAbstract $style
*/
public function __construct($style = null)
{
$this->style = $style;
}
/**
* Set parent writer.
*
* @param RTF $writer
*/
public function setParentWriter($writer): void
{
$this->parentWriter = $writer;
}
/**
* Get parent writer.
*
* @return RTF
*/
public function getParentWriter()
{
return $this->parentWriter;
}
/**
* Get style.
*
* @return null|array|string|StyleAbstract
*/
public function getStyle()
{
if (!$this->style instanceof StyleAbstract && !is_array($this->style)) {
return '';
}
return $this->style;
}
/**
* Get value if ...
*
* @param null|bool $condition
* @param string $value
*
* @return string
*/
protected function getValueIf($condition, $value)
{
return $condition == true ? $value : '';
}
}

View File

@@ -35,6 +35,10 @@ class Paragraph extends AbstractStyle
*/
private $nestedLevel = 0;
private const LEFT = Jc::LEFT;
private const RIGHT = Jc::RIGHT;
private const JUSTIFY = Jc::JUSTIFY;
/**
* Write style.
*
@@ -52,6 +56,18 @@ class Paragraph extends AbstractStyle
Jc::END => '\qr',
Jc::CENTER => '\qc',
Jc::BOTH => '\qj',
self::LEFT => '\ql',
self::RIGHT => '\qr',
self::JUSTIFY => '\qj',
];
$bidiAlignments = [
Jc::START => '\qr',
Jc::END => '\ql',
Jc::CENTER => '\qc',
Jc::BOTH => '\qj',
self::LEFT => '\ql',
self::RIGHT => '\qr',
self::JUSTIFY => '\qj',
];
$spaceAfter = $style->getSpaceAfter();
@@ -61,8 +77,13 @@ class Paragraph extends AbstractStyle
if ($this->nestedLevel == 0) {
$content .= '\pard\nowidctlpar ';
}
if (isset($alignments[$style->getAlignment()])) {
$content .= $alignments[$style->getAlignment()];
$alignment = $style->getAlignment();
$bidi = $style->isBidi();
if ($alignment === '' && $bidi !== null) {
$alignment = Jc::START;
}
if (isset($alignments[$alignment])) {
$content .= $bidi ? $bidiAlignments[$alignment] : $alignments[$alignment];
}
$content .= $this->writeIndentation($style->getIndentation());
$content .= $this->getValueIf($spaceBefore !== null, '\sb' . round($spaceBefore ?? 0));

View File

@@ -52,14 +52,15 @@ class Word2007 extends AbstractWriter implements WriterInterface
$this->setPhpWord($phpWord);
// Create parts
// The first four files need to be in this order for Mimetype detection to work
$this->parts = [
'ContentTypes' => '[Content_Types].xml',
'Rels' => '_rels/.rels',
'RelsDocument' => 'word/_rels/document.xml.rels',
'Document' => 'word/document.xml',
'DocPropsApp' => 'docProps/app.xml',
'DocPropsCore' => 'docProps/core.xml',
'DocPropsCustom' => 'docProps/custom.xml',
'RelsDocument' => 'word/_rels/document.xml.rels',
'Document' => 'word/document.xml',
'Comments' => 'word/comments.xml',
'Styles' => 'word/styles.xml',
'Numbering' => 'word/numbering.xml',
@@ -90,10 +91,8 @@ class Word2007 extends AbstractWriter implements WriterInterface
/**
* Save document by name.
*
* @param string $filename
*/
public function save($filename = null): void
public function save(string $filename): void
{
$filename = $this->getTempFile($filename);
$zip = $this->getZipArchive($filename);
@@ -120,7 +119,7 @@ class Word2007 extends AbstractWriter implements WriterInterface
$this->addHeaderFooterMedia($zip, 'footer');
// Add header/footer contents
$rId = Media::countElements('section') + 6; // @see Rels::writeDocRels for 6 first elements
$rId = Media::countElements('section') + 6; //@see Rels::writeDocRels for 6 first elements
$sections = $phpWord->getSections();
foreach ($sections as $section) {
$this->addHeaderFooterContent($section, $zip, 'header', $rId);

View File

@@ -21,6 +21,7 @@ use PhpOffice\PhpWord\Element\AbstractElement as Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Shared\Text as SharedText;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Writer\Word2007\Part\AbstractPart;
/**
* Abstract element writer.
@@ -50,6 +51,11 @@ abstract class AbstractElement
*/
protected $withoutP = false;
/**
* @var null|AbstractPart
*/
protected $part;
/**
* Write element.
*/
@@ -224,4 +230,16 @@ abstract class AbstractElement
return $this->getXmlWriter()->writeRaw($content);
}
public function setPart(?AbstractPart $part): self
{
$this->part = $part;
return $this;
}
public function getPart(): ?AbstractPart
{
return $this->part;
}
}

View File

@@ -83,6 +83,7 @@ class Container extends AbstractElement
if (class_exists($writerClass)) {
/** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */
$writer = new $writerClass($xmlWriter, $element, $withoutP);
$writer->setPart($this->getPart());
$writer->write();
}

View File

@@ -166,15 +166,15 @@ class Field extends Text
foreach ($properties as $propkey => $propval) {
switch ($propkey) {
case 'format':
$propertiesAndOptions .= '\* ' . $propval . ' ';
$propertiesAndOptions .= '\\* ' . $propval . ' ';
break;
case 'numformat':
$propertiesAndOptions .= '\# ' . $propval . ' ';
$propertiesAndOptions .= '\\# ' . $propval . ' ';
break;
case 'dateformat':
$propertiesAndOptions .= '\@ "' . $propval . '" ';
$propertiesAndOptions .= '\\@ "' . $propval . '" ';
break;
case 'macroname':
@@ -192,27 +192,31 @@ class Field extends Text
foreach ($options as $option) {
switch ($option) {
case 'PreserveFormat':
$propertiesAndOptions .= '\* MERGEFORMAT ';
$propertiesAndOptions .= '\\* MERGEFORMAT ';
break;
case 'LunarCalendar':
$propertiesAndOptions .= '\h ';
$propertiesAndOptions .= '\\h ';
break;
case 'SakaEraCalendar':
$propertiesAndOptions .= '\s ';
$propertiesAndOptions .= '\\s ';
break;
case 'LastUsedFormat':
$propertiesAndOptions .= '\l ';
$propertiesAndOptions .= '\\l ';
break;
case 'Bold':
$propertiesAndOptions .= '\b ';
$propertiesAndOptions .= '\\b ';
break;
case 'Italic':
$propertiesAndOptions .= '\i ';
$propertiesAndOptions .= '\\i ';
break;
case 'Path':
$propertiesAndOptions .= '\\p ';
break;
default:

View File

@@ -0,0 +1,50 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Writer\Word2007\Element;
use PhpOffice\Math\Writer\OfficeMathML;
use PhpOffice\PhpWord\Element\Formula as FormulaElement;
/**
* Formula element writer.
*/
class Formula extends AbstractElement
{
/**
* Write element.
*/
public function write(): void
{
$element = $this->getElement();
if (!$element instanceof FormulaElement) {
return;
}
$this->startElementP();
$xmlWriter = $this->getXmlWriter();
$xmlWriter->startElement('w:r');
$xmlWriter->writeElement('w:rPr');
$xmlWriter->endElement();
$xmlWriter->writeRaw((new OfficeMathML())->write($element->getMath()));
$this->endElementP();
}
}

View File

@@ -17,6 +17,7 @@
namespace PhpOffice\PhpWord\Writer\Word2007\Element;
use PhpOffice\PhpWord\Element\Title;
use PhpOffice\PhpWord\Element\TOC as TOCElement;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Style\Font;
@@ -63,17 +64,14 @@ class TOC extends AbstractElement
/**
* Write title.
*
* @param \PhpOffice\PhpWord\Element\Title $title
* @param bool $writeFieldMark
*/
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $writeFieldMark): void
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, Title $title, bool $writeFieldMark): void
{
$tocStyle = $element->getStyleTOC();
$fontStyle = $element->getStyleFont();
$isObject = ($fontStyle instanceof Font) ? true : false;
$rId = $title->getRelationId();
$indent = ($title->getDepth() - 1) * $tocStyle->getIndent();
$indent = (int) (($title->getDepth() - 1) * $tocStyle->getIndent());
$xmlWriter->startElement('w:p');
@@ -95,7 +93,10 @@ class TOC extends AbstractElement
$styleWriter->write();
}
$xmlWriter->startElement('w:t');
$this->writeText($title->getText());
$titleText = $title->getText();
$this->writeText(is_string($titleText) ? $titleText : '');
$xmlWriter->endElement(); // w:t
$xmlWriter->endElement(); // w:r
@@ -116,6 +117,20 @@ class TOC extends AbstractElement
$xmlWriter->endElement();
$xmlWriter->endElement();
if ($title->getPageNumber() !== null) {
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'separate');
$xmlWriter->endElement();
$xmlWriter->endElement();
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:t');
$xmlWriter->text((string) $title->getPageNumber());
$xmlWriter->endElement();
$xmlWriter->endElement();
}
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'end');
@@ -129,10 +144,8 @@ class TOC extends AbstractElement
/**
* Write style.
*
* @param int $indent
*/
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, $indent): void
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, int $indent): void
{
$tocStyle = $element->getStyleTOC();
$fontStyle = $element->getStyleFont();

View File

@@ -2,10 +2,8 @@
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
@@ -50,6 +48,10 @@ class TextBox extends Image
$xmlWriter->startElement('v:shape');
$xmlWriter->writeAttribute('type', '#_x0000_t0202');
if ($style->getBgColor()) {
$xmlWriter->writeAttribute('fillcolor', $style->getBgColor());
}
$styleWriter->write();
$styleWriter->writeBorder();

View File

@@ -67,7 +67,8 @@ class Title extends AbstractElement
$this->writeText($text);
$xmlWriter->endElement(); // w:t
$xmlWriter->endElement(); // w:r
} elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
}
if ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
$containerWriter = new Container($xmlWriter, $text);
$containerWriter->write();
}

View File

@@ -48,8 +48,6 @@ abstract class AbstractPart
/**
* Set parent writer.
*
* @param \PhpOffice\PhpWord\Writer\AbstractWriter $writer
*/
public function setParentWriter(?AbstractWriter $writer = null): void
{

View File

@@ -151,6 +151,7 @@ class Settings extends AbstractPart
$this->setOnOffValue('w:updateFields', $documentSettings->hasUpdateFields());
$this->setOnOffValue('w:autoHyphenation', $documentSettings->hasAutoHyphenation());
$this->setOnOffValue('w:doNotHyphenateCaps', $documentSettings->hasDoNotHyphenateCaps());
$this->setOnOffValue('w:bookFoldPrinting', $documentSettings->hasBookFoldPrinting());
$this->setThemeFontLang($documentSettings->getThemeFontLang());
$this->setRevisionView($documentSettings->getRevisionView());
@@ -217,8 +218,6 @@ class Settings extends AbstractPart
/**
* Set the Proof state.
*
* @param ProofState $proofState
*/
private function setProofState(?ProofState $proofState = null): void
{
@@ -234,8 +233,6 @@ class Settings extends AbstractPart
/**
* Set the Revision View.
*
* @param TrackChangesView $trackChangesView
*/
private function setRevisionView(?TrackChangesView $trackChangesView = null): void
{
@@ -253,8 +250,6 @@ class Settings extends AbstractPart
/**
* Sets the language.
*
* @param Language $language
*/
private function setThemeFontLang(?Language $language = null): void
{

View File

@@ -88,6 +88,7 @@ class Cell extends AbstractStyle
$vMerge = $style->getVMerge();
$xmlWriter->writeElementIf(null !== $gridSpan, 'w:gridSpan', 'w:val', $gridSpan);
$xmlWriter->writeElementIf(null !== $vMerge, 'w:vMerge', 'w:val', $vMerge);
$xmlWriter->writeElementIf($style->getNoWrap(), 'w:noWrap');
$xmlWriter->endElement(); // w:tcPr
}

View File

@@ -2,10 +2,8 @@
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.

View File

@@ -24,8 +24,6 @@ interface WriterInterface
{
/**
* Save PhpWord to file.
*
* @param string $filename
*/
public function save($filename = null);
public function save(string $filename): void;
}