A pure PHP library for reading and writing word processing documents

Describe the Bug

When using setComplexValue to replace a template macro with a TextRun with Link, the document is corrupt, but recoverable, and the links do not link to the given target.

Steps to Reproduce

Please provide a code sample that reproduces the issue.

require __DIR__ . '/vendor/autoload.php';

/* some SQL => $projects */

$phpWord = new \PhpOffice\PhpWord\PhpWord();
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('template.docx');

$templateProcessor->setValue('date', date_format($_date, 'F j, Y'));
$templateProcessor->setValue('doc_num', htmlspecialchars($doc_num));

$templateProcessor->cloneBlock('PROJECT', count($projects));

foreach ($projects as $project) {
  $templateProcessor->setValue('project_title', htmlspecialchars($project_title), 1);
  $templateProcessor->setValue('project_start_date', htmlspecialchars($project_start_date), 1);
  $templateProcessor->setValue('project_manager', htmlspecialchars($project_manager), 1);
  $project_address = new PhpOffice\PhpWord\Element\TextRun();
  $address_lines = explode('\n', $main_office_address);
  foreach ($address_lines as $address line) {
  if (!empty($main_office_tel)) {
    $project_address->addText(htmlspecialchars($main_office_tel)) . ' ';
  if (!empty($main_office_fax)) {
    $project_address->addText(htmlspecialchars($main_office_fax)) . ' ';
  if (!empty($main_office_email)) {
    $project_address->addLink($main_office_email, htmlspecialchars($main_office_fax));
  $templateProcessor->setComplexValue('project_address', $project_address, 1);

$tempfile = tempnam(sys_get_temp_dir(), 'project_report_');
header("Content-disposition: attachment; filename=" . basename($tempfile) . ".docx; charset=iso-8859-1");
echo file_get_contents($tempfile);

Expected Behavior

The document should be well formed, the link text should link to the target as given in addLink.

Current Behavior

The document triggers an error in Word, "Word found unreadable content in [filename].docx. Do you want to recover the contents of this document?"
Recovering displays the document more-or-less correctly. The link text is present and seems to be a hyperlink, but no link target is set when exiting the link.
Have tried e-mail addresses and web addresses, with and without mailto: and https://, different character encodings. As soon as I comment out the addLink, I no longer get the "unreadable content" warning.


Please fill in your environment information:

  • PHP Version: 5.5 and 5.6 (legacy system)
  • PHPWord Version: 0.17

php version 7.4

$word = IOFactory::load('test.doc', 'MsDoc');

Notice: Trying to access array offset on value of type null
phpoffice/phpword/src/PhpWord/Reader/MsDoc.php on line 2319
phpoffice/phpword/src/PhpWord/Reader/MsDoc.php on line 2354
phpoffice/phpword/src/PhpWord/Reader/MsDoc.php on line 2346

.... more line

Describe the Bug

A software I use generates Word files (.docx). I can open them in MS Word without problem.
If I try to read them with PHPWord, it appears to be empty. But if I open the file in MS Word and save it, the file is readable by PHPWord.

There are some differences before and after saving the file:

Before After
Filesize 14Ko 50 Ko
Root Dir structure 2023-03-19_17h43_01 2023-03-19_17h44_02
word Dir structure 2023-03-19_17h46_22 2023-03-19_17h47_24

Steps to Reproduce

Please provide a code sample that reproduces the issue.

require __DIR__ . '/vendor/autoload.php';

$phpWord  = IOFactory::load('document.docx');
$sections = $phpWord->getSections();

// Here, $sections is an empty array. 
// If I open, save the file, and test it again, I got a lot of sections


  • PHP Version: 8.1
  • PHPWord Version: 1.0.0

Understand that OMML and MathML specs are quite complex, but if we use third party tool to author MathML, the PHPWord library just open an API to load the MathML and convert the MathML using Office's own mathml2ooml.xls, during exporting phase, it directly insert into the final document.xml. In this case, the implementation effort should be much less. Anyone can verify whether the idea is achievable? And which files I should look into?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

How can be read Mathtype from docx file using PhpWord?
I have searched lots of tickets and blogs. But did not get any solution.
Please help me

use PhpOffice\PhpWord\Element\Field;
use PhpOffice\PhpWord\Element\Table;
use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\SimpleType\TblWidth;

include_once 'Sample_Header.php';

// Template processor instance creation
echo date('H:i:s'), ' Creating new TemplateProcessor instance...', EOL;
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('resources/Sample_40_TemplateSetComplexValue.docx');

$title = new TextRun();
$title->addText('This title has been set ', array('bold' => true, 'italic' => true, 'color' => 'blue'));
$title->addText('dynamically', array('bold' => true, 'italic' => true, 'color' => 'red', 'underline' => 'single'));
$templateProcessor->setComplexBlock('title', $title);

$inline = new TextRun();
$inline->addText('by a red italic text', array('italic' => true, 'color' => 'red'));
$templateProcessor->setComplexValue('inline', $inline);

$table = new Table(array('borderSize' => 12, 'borderColor' => 'green', 'width' => 6000, 'unit' => TblWidth::TWIP));
$table->addCell(150)->addText('Cell A1');
$table->addCell(150)->addText('Cell A2');
$table->addCell(150)->addText('Cell A3');
$table->addCell(150)->addText('Cell B1');
$table->addCell(150)->addText('Cell B2');
$table->addCell(null)->addImage('./resources/_earth.jpg', array('width' => 250, 'height' => 250, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER));

$templateProcessor->setComplexBlock('table', $table); // this create black photo

$field = new Field('DATE', array('dateformat' => 'dddd d MMMM yyyy H:mm:ss'), array('PreserveFormat'));
$templateProcessor->setComplexValue('field', $field);

// $link = new Link('https://github.com/PHPOffice/PHPWord');
// $templateProcessor->setComplexValue('link', $link);

echo date('H:i:s'), ' Saving the result document...', EOL;

echo getEndingNotes(array('Word2007' => 'docx'), 'results/Sample_40_TemplateSetComplexValue.docx');
if (!CLI) {
include_once 'Sample_Footer.php';
according to sample i put some code to add image to my table but the result blank image.

I cannot find any tutorial on this. I'd like to add an array to a template as a list. cloneRow seems to only work for tables. So doing something like this does not work:

$templateProcessor->cloneRow('listOptions', count($listOptions));
for($i = 0; $i < count($listOptions); $i++){
    $templateProcessor->setValue('listOptions#'.($i+1), htmlspecialchars($listOptions[$i], ENT_COMPAT, 'UTF-8'));

Any ideas?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Is your feature request related to a problem? Please describe.

I want to make dynamic form input base on all the variables exist in docx template.

Describe the solution you'd like

I think it's better if there is a function that can return all variables inside the docx

Additional context

If it feature already exist feel free to tell me

Describe the Bug

我尝试将富文本转换为wrod文档。如果HTML代码中有任何标签的width属性值为auto就会引发一个异常:Unsupported operand types: string / int

<table style="width: auto;">
        <td colspan="1" rowspan="1" width="auto">td</td>

我通过跟踪源代码发现是 PhpOffice\PhpWord\Shared\Html::parseInlineStyle();方法中对于width的处理没有考虑到值为auto的情况

我创建了一个 PhpOffice\PhpWord\Shared\Html的子类,希望重写parseInlineStyle方法,但是因为方法内的静态调用(就像self::)和固定了命名空间的函数调用(就像call_user_func_array(array('PhpOffice\PhpWord\Shared\Html', $method), array_values($arguments));),使我不得不在子类里重写了所有调用了parseInlineStyle的方法,也包括addHtml方法。这些方法几乎没有任何改动,仅仅是为了让代码在执行中能正确的调用我修复过的parseInlineStyle方法。

因此我有一个建议:是否可以在 PhpOffice\PhpWord\Shared\Html类中使用static::代替self::,同时call_user_func_array(array('PhpOffice\PhpWord\Shared\Html', $method), array_values($arguments));这样的代码可以替换成call_user_func_array(array(static::class, $method), array_values($arguments));

Steps to Reproduce

require __DIR__ . '/vendor/autoload.php';

<table style="width: auto;">
        <td colspan="1" rowspan="1" width="auto">td</td>
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
PhpOffice\PhpWord\Shared\Html::addHtml($section, $html);

Expected Behavior


Current Behavior


Unsupported operand types: string / int at /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Converter.php:151)
#0 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(122): PhpOffice\\PhpWord\\Shared\\Converter::pixelToTwip()
#1 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(469): PhpOffice\\PhpWord\\Shared\\Html::parseInlineStyle()
#2 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(416): PhpOffice\\PhpWord\\Shared\\Html::recursiveParseStylesInHierarchy()
#3 [internal function]: PhpOffice\\PhpWord\\Shared\\Html::parseCell()
#4 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(215): call_user_func_array()
#5 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(247): PhpOffice\\PhpWord\\Shared\\Html::parseNode()
#6 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(229): PhpOffice\\PhpWord\\Shared\\Html::parseChildNodes()
#7 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(247): PhpOffice\\PhpWord\\Shared\\Html::parseNode()
#8 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(229): PhpOffice\\PhpWord\\Shared\\Html::parseChildNodes()
#9 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(247): PhpOffice\\PhpWord\\Shared\\Html::parseNode()
#10 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(229): PhpOffice\\PhpWord\\Shared\\Html::parseChildNodes()
#11 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(247): PhpOffice\\PhpWord\\Shared\\Html::parseNode()
#12 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(229): PhpOffice\\PhpWord\\Shared\\Html::parseChildNodes()
#13 /home/vagrant/code/proposition/vendor/phpoffice/phpword/src/PhpWord/Shared/Html.php(84): PhpOffice\\PhpWord\\Shared\\Html::parseNode()
#14 /home/vagrant/code/proposition/app/Http/Controllers/WordController.php(32): PhpOffice\\PhpWord\\Shared\\Html::addHtml()


  • PHP Version: PHP 8.2.3 (cli) (built: Feb 14 2023 16:57:50) (NTS)
  • PHPWord Version:0.18.3

Hi, i need convert DOCX to HTML. Here is my code example:

$phpWord = \PhpOffice\PhpWord\IOFactory::load($fileTmp);
$htmlWriter = new \PhpOffice\PhpWord\Writer\HTML($phpWord);

Output html no correct
Space in one sentence replaced on few new lines
in DOCX "Hello my world"
Output Html:

How fix this ?

Describe the Bug

The following test file when saved is building a file that could not be opened back in Word.

Steps to Reproduce

Just trying to open/save the file with the Template Processor.
Please use this sample file : absence.docx

require __DIR__ . '/vendor/autoload.php';

$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor("absence.docx");

Expected Behavior

The saved file should open properly in Word.

Current Behavior

The file does not open in Word.


Please fill in your environment information:

  • PHP Version: tested with 7.31 and 8.1.11
  • PHPWord Version: 0.18.3

what is the return value of $template_processor->saveAs() ? , i tried to catch the return value to determine whether the process is successfully executed

I'm trying to read .doc file in php(I'm using laravel v6). For reading .doc I'm using phpword library. It works fine with .doc file in english. But I'm from slovakia a we have in our alphabet characters like á,é,í,č,ň,ô. And whit those characters i have problem.

My code:

protected static function doc_to_text( $filename )
        $objReader = IOFactory::createReader('MsDoc');
        $phpWord = $objReader->load($filename); // instance of \PhpOffice\PhpWord\PhpWord

        $text = '';

        foreach ($phpWord->getSections() as $section) {
            foreach ($section->getElements() as $element) {
                if ($element instanceof Text) {
                    $text .= $element->getText();
        return $text;

This is output of function with slovak .doc:

"}\x01IVOTOPIS Titul, menoKontaktné údaje:Ulica, stoTelefón: 0xx/ xxx xxx Mobil: 09xx xxx xxx e-mail: \x13 HYPERLINK "mailto:info@firma.sk" \x14info@firma.sk\x15 Dosiahnuté vzdelanie: Vysokoa\x01kolské/stredoa\x01kolskéVzdelanie: 2000-2006 Fakulta/ univerzita1995-2000 stredná aDoplH\x01ujúce informácie o vzdelaní: 1998-2000 kurzy 1996-1997 a\x01tudijné pobytyPracovné skúsenosti: 2000-2004 zamestnávate>\x01, pozícia 2004-2006 zamestnávate> pozícia Jazykové znalosti: Anglický jazyk - aktívne 8:|<U+0094><U+009E>¶ÔÖþ\x16\vB\vZ\v<U+0086>\v
<U+008A>\v®\vä\v\x10B\x10´\x10Ö\x10\x1E\x11F\x11H\x11J\x11üøòøìøüøäøäÞäøìüøìøüøüøìøüøüøìøüøüøìøÜìøìøìøØ\x06\x16h\e\t_\x03U\x08\x01\x16hÌeh0J\x11\x0F\x03j\x16hÌehU\x08\x01\x16hÌeh0J\x10\x16hO\x1FÝ0J\x10\x06\x16hÌeh\x06\x16hO\x1FÝ-\x08\x16\x08.\x08P\x08<U+0082>\x08°\x08Ú\x08R\t¶\tÎ\t:<U+0080>¢Ö&\vF\x04\x13¤d\x14¤d[$\x01\$\x01gdÌeh\x0F&\vF\x03\x13¤d\x14¤d[$\x01\$\x01gdÌeh\x0F&\vF\x02\x13¤d\x14¤d[$\x01\$\x01gdÌeh\x0F&\vF\x01\x13¤d\x14¤d[$\x01\$\x01gdÌeh\x04\x0FgdÌeh\x04\x03gdÌeh\x13PoPHP, C++ XHTML, CSS Microsoft Excel Microsoft Word Vodi preukaz: sk. C (najazdených cca 600 000km) Vlastnosti a záujmy: "

This is output of function with english .doc:
"Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac faucibus odio. Vestibulum neque massa, scelerisque sit amet ligula eu, congue molestie mi. Praesent ut varius sem. Nullam at porttitor arcu, nec lacinia nisi. Ut ac dolor vitae odio interdum condimentum. Vivamus dapibus sodales ex, vitae malesuada ipsum cursus convallis. Maecenas sed egestas nulla, ac condimentum orci. Mauris diam felis, vulputate ac suscipit et, iaculis non est. Curabitur semper arcu ac ligula semper, nec luctus nisl blandit. Integer lacinia ante ac libero lobortis imperdiet. Nullam mollis convallis ipsum, ac accumsan nunc vehicula vitae. Nulla eget justo in felis tristique fringilla. Morbi sit amet tortor quis risus auctor condimentum. Morbi in ullamcorper elit. Nulla iaculis tellus sit amet mauris tempus fringilla.Maecenas mauris lectus, lobortis et purus mattis, blandit dictum tellus.Maecenas non lorem quis tellus placerat varius. Nulla facilisi. Aenean congue fringilla justo ut aliquam. In non mauris justo. Duis vehicula mi vel mi pretium, a viverra erat efficitur. Cras aliquam est ac eros varius, id iaculis dui auctor. Duis pretium neque ligula, et pulvinar mi placerat et. "

I have tried google and ask my friends. Also i try https://github.com/neitanod/forceutf8. I need some ideas what should be problem or how to solve it.

When I try to save file of document, I get this error:
Warning: ZipArchive::close(): Failure to create temporary file: Permission denied in vendor/phpoffice/phpword/src/PhpWord/Shared/ZipArchive.php on line 163
My code is this:

require 'vendor/autoload.php';
$html = file_get_contents('template.html');
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
\PhpOffice\PhpWord\Shared\Html::addHtml($section, $html, false, false);
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');

I'm running in Ubuntu 18.04 x64 PHP 7.2 and this project is inside apache's folder (/var/www/html/myproject).
I already tried to change entire folder permissions to 0755 and owner to www-data:www-data and myuser:www-data and I got same error

I am storing html data in database from ckeditor , but when i try to wrtite in file , addHtml causing an error ,
here is the code :
$wordTable3 = new \PhpOffice\PhpWord\Element\Table();
$cell3 = $wordTable3->addCell();

    $templateProcessor->setComplexBlock('session_content', $wordTable3);

here is the issue :
"Call to a member function addNumberingStyle() on null", exception: "Error",…}
exception: "Error"
file: "E:\xampp\htdocs\mis\vendor\phpoffice\phpword\src\PhpWord\Shared\Html.php"
line: 521
message: "Call to a member function addNumberingStyle() on null"
trace: [{function: "parseList", class: "PhpOffice\PhpWord\Shared\Html", type:

Hello, thank you for the great work.

I have a docx file with a table in it. I am trying to load it using IOFactory, but the following errror appear:
InvalidArgumentException: Invalid style value: lrTb Options:btLr,tbRl in PhpOffice\PhpWord\Style\AbstractStyle->setEnumVal()
Line 307 of /vendor/phpoffice/phpword/src/PhpWord/Style/AbstractStyle.php

  • PHP Version: 8.1
  • PHPWord Version: 1.0

This is:

  • a bug report
  • a feature request

Expected Behavior

My word export generates a Table of Contents, with clickable links which point to the correct title. However, the page numbers are not displayed in the table of contents.


Update field setting is set, and after applying this word will query for missing links. Still, no numbers are shown. This works for OSX and office for mac, so it appears to be a program/os related issue.

Update 8-06: The protected mode of a word document seems to cause this issue. If a word document is protected, and you need to switch it manually to edit mode the table of contents numbers are not updated.


  • PHP version:5.3.18
  • PHPWord version: 0.14

Describe the Bug

$depth If the maximum value exceeds 3, word2007 becomes invalid

Steps to Reproduce


require __DIR__ . '/vendor/autoload.php';

$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();

$this->section->addTitle('x1', 1); 
$this->section->addTitle('x2', 2); 
$this->section->addTitle('x3', 3); 
$this->section->addTitle('x4', 4); 
$this->section->addTitle('x5', 5); 

Here are the results :

Expected Behavior

I want to know what the maximum value of $depth is

Current Behavior

What is the current behavior?


Please fill in your environment information:

  • PHP Version: 8.1
  • PHPWord Version: 1.0.0 or 0.18

Hello Team,

I am generating docx using template. I am dynamically updating few tables in template. So on each scenario table content may be short or long so total page numbers will differ on each document that gets created.

And list of headings(TOC items) remain always same, but their content will vary dynamically.

Now what is happening is when click one heading in TOC, it takes me to right position. But the page number in TOC is not matching with actual page number of that.

Note: addTOC function helps to add new TOC item. I am looking something like updateTOC to update the existing TOC items in TEMPLATE based on dynamic content i write.

So i am looking for help to "Update the page numbers" at just before end of document created.


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Link :

Format :

Validator :

Samples :

ToDo :

  • Implement basic features (text, tables, images)
  • Validate locally
  • Unit Tests
  • Validate files with Travis-CI
  • Documentation (Differences with others format, Specifications for the Daisy Format)

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.