Read and replace contents in .docx (Word) file
Asked Answered
L

5

15

I need to replace content in some word documents based on User input. I am trying to read a template file (e.g. "template.docx"), and replace First name {fname}, Address {address} etc.

template.docx:

To,
The Office,
{officeaddress}
Sub:  Authorization Letter
Sir / Madam,

I/We hereby authorize  to  {Ename}  whose signature is attested here below, to submit application and collect Residential permit for {name}  
Kindly allow him to support our International assignee

{name}                                          {Ename}  

Is there a way to do the same in Laravel 5.3?

I am trying to do with phpword, but I can only see code to write new word files - but not read and replace existing ones. Also, when I simply read and write, the formatting is messed up.

Code:

$file = public_path('template.docx');
$phpWord = \PhpOffice\PhpWord\IOFactory::load($file);

$phpWord->save('b.docx');

b.docx

To,
The Office,
{officeaddress}

Sub: 
 Authorization Letter
Sir / Madam,


I/We hereby authorize 
 to

{Ename}


whose signature is attested here below, to submit a
pplication and collect Residential permit
 for 
{name}

Kindly allow him to support our International assignee


{name}













{
E
name}
Lorettelorgnette answered 23/12, 2016 at 6:24 Comment(3)
This package can do it: github.com/guiguidoc/laravel-phpword github.com/PHPOffice/PHPWordKisumu
here is the example for the reading from a .docx file: github.com/PHPOffice/PHPWord/blob/develop/samples/…Hendeca
Thanks guys - I'll give them a try.Lorettelorgnette
L
13

This is the working version to @addweb-solution-pvt-ltd 's answer.

//This is the main document in  Template.docx file.
$file = public_path('template.docx');

$phpword = new \PhpOffice\PhpWord\TemplateProcessor($file);

$phpword->setValue('{name}','Santosh');
$phpword->setValue('{lastname}','Achari');
$phpword->setValue('{officeAddress}','Yahoo');

$phpword->saveAs('edited.docx');

However, not all of the {name} fields are changing. Not sure why.


Alternatively:

// Creating the new document...
$zip = new \PhpOffice\PhpWord\Shared\ZipArchive();

//This is the main document in a .docx file.
$fileToModify = 'word/document.xml';

$file = public_path('template.docx');
$temp_file = storage_path('/app/'.date('Ymdhis').'.docx');
copy($template,$temp_file);

if ($zip->open($temp_file) === TRUE) {
    //Read contents into memory
    $oldContents = $zip->getFromName($fileToModify);

    echo $oldContents;

    //Modify contents:
    $newContents = str_replace('{officeaddqress}', 'Yahoo \n World', $oldContents);
    $newContents = str_replace('{name}', 'Santosh Achari', $newContents);

    //Delete the old...
    $zip->deleteName($fileToModify);
    //Write the new...
    $zip->addFromString($fileToModify, $newContents);
    //And write back to the filesystem.
    $return =$zip->close();
    If ($return==TRUE){
        echo "Success!";
    }
} else {
    echo 'failed';
}

Works well. Still trying to figure how to save it as a new file and force a download.

Lorettelorgnette answered 23/12, 2016 at 9:27 Comment(3)
See my UPDATE for your solutionMeza
NOT working, showing ERROR.... Fatal error: Uncaught Error: Call to undefined function public_path()Mobley
May be check the version of Laravel. This was built on an older version of Laravel.Lorettelorgnette
I
4

If you find simple solution you can use this library

Example: This code will replace $search to $replace in $pathToDocx file

$docx = new IRebega\DocxReplacer($pathToDocx);

$docx->replaceText($search, $replace);
Incunabulum answered 20/2, 2018 at 18:42 Comment(2)
Extension is no longer supported.Galbraith
Rebega, your solution is the perfect in case of just replacing text to text and text to image in the docx file. I am very thankful to you, have used your library in my 2 projects. My new project needs replace text to formatted text. could you please update your library to make the best? Happy to used your solution :) :)Mobley
H
3

I have same task to edit .doc or .docx file in php, i have use this code for it.

Reference : http://www.onlinecode.org/update-docx-file-using-php/

    $full_path = 'template.docx';
    //Copy the Template file to the Result Directory
    copy($template_file_name, $full_path);

    // add calss Zip Archive
    $zip_val = new ZipArchive;

    //Docx file is nothing but a zip file. Open this Zip File
    if($zip_val->open($full_path) == true)
    {
        // In the Open XML Wordprocessing format content is stored.
        // In the document.xml file located in the word directory.

        $key_file_name = 'word/document.xml';
        $message = $zip_val->getFromName($key_file_name);               

        $timestamp = date('d-M-Y H:i:s');

        // this data Replace the placeholders with actual values
        $message = str_replace("{officeaddress}", "onlinecode org", $message);
        $message = str_replace("{Ename}", "[email protected]", $message); 
        $message = str_replace("{name}", "www.onlinecode.org", $message);   

        //Replace the content with the new content created above.
        $zip_val->addFromString($key_file_name, $message);
        $zip_val->close();
    }
Hopscotch answered 6/11, 2017 at 5:41 Comment(0)
M
3

Library phpoffice/phpword working is ok.

For correct working you must use the right symbols in your Word document, like that:

${name}
${lastname}
${officeAddress}

and for method "setValue" you need to use only names, like:

'name'
'lastname'
'officeAddress'

Very good working within Laravel, Lumen, and other frameworks

Example:

//This is the main document in  Template.docx file.
$file = public_path('template.docx');

$phpword = new \PhpOffice\PhpWord\TemplateProcessor($file);

$phpword->setValue('name','Santosh');
$phpword->setValue('lastname','Achari');
$phpword->setValue('officeAddress','Yahoo');

$phpword->saveAs('edited.docx');
Medico answered 5/9, 2022 at 15:13 Comment(1)
How can we bold the text? $phpword->setValue('name','<b>Santosh</b>'); solution does not work. Any suggestion??Mobley
M
2

To read and replace content from Doc file, you can use PHPWord package and download this package using composer command:

composer require phpoffice/phpword 

As per version v0.12.1, you need to require the PHP Word Autoloader.php from src/PHPWord folder and register it

require_once 'src/PhpWord/Autoloader.php';
\PhpOffice\PhpWord\Autoloader::register();

1) Open document

$template = new \PhpOffice\PhpWord\TemplateProcessor('YOURDOCPATH');

2) Replace string variables for single

$template->setValue('variableName', 'MyVariableValue');

3) Replace string variables for multi occurrence
- Clone your array placeholder to the count of your array

$template->cloneRow('arrayName', count($array));  

- Replace variable value

for($number = 0; $number < count($array); $number++) {
    $template->setValue('arrayName#'.($number+1), htmlspecialchars($array[$number], ENT_COMPAT, 'UTF-8'));
}

4) Save the changed document

$template->saveAs('PATHTOUPDATED.docx');

UPDATE
You can pass limit as third parameter into $template->setValue($search, $replace, $limit) to specifies how many matches should take place.

Meza answered 23/12, 2016 at 7:7 Comment(4)
setValue(), is not always working. Does formatting make a difference? Also the documentation mentions variables as in the macros.Lorettelorgnette
the solution of AddWeb is not working at all. There is not error but the template is saved as a new document with no change at all. Instead I used @SantoshAchari solution with str_replace. Nevertheless there are still some placeholders not replaced. still checking why.Colunga
@Colunga it seems it is highly dependent on the version of Microsoft Word. In my case it worked off the sample word documents in PHPWord which seems to be word 2003.Lorettelorgnette
Solution NOT workingMobley

© 2022 - 2024 — McMap. All rights reserved.