Forum


Replies: 6   Views: 278
Replacing multiple images
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by fiwoyax200  · 24-04-2024 - 23:06

Hi,

Is it possible to replace/add multiple images to a specific location in a document?

I have tried using replacePlaceholderImage, however, I have to add placeholder image for each image I would like to replace and the problem is each time I create a document the number of images to replace can vary therefore the placeholder image in the template becomes an issue.

 

Posted by admin  · 25-04-2024 - 06:41

Hello,

You can add images using addImage:

$options = array(
    'src' => 'image.png',
);

$docx->addImage($options);

or embedHTML:

$html = '<img src="image.png">';

$docx->embedHTML($html);

By default, these methods add the contents at the end of the document. If you need to add the images into specific positions of the document or replace existing elements you can use insertWordFragment or replaceWordContent from DOCXPath. For example, to add an image after the second paragraph:

$content = new WordFragment($docx, 'document');
$content->addImage(['src' => 'image.png']);

$referenceNode = [
    'type' => 'paragraph',
    'occurrence' => 2,
];

$docx->insertWordFragment($content, $referenceNode, 'after');

or to replace the second paragraph with an image:

$content = new WordFragment($docx, 'document');
$content->addImage(['src' => 'image.png']);

$referenceNode = [
    'type' => 'paragraph',
    'occurrence' => 2,
];

$docx->replaceWordContent($content, $referenceNode, 'after');

The WordFragment can be generated with addImage, embedHTML or any other phpdocx content method (even multiple contents).

In addition to replacePlaceholderImage, you can use replaceVariableByWordFragment to add images (for example replacing text placeholders by a WordFragment that contains an image); maybe this is the easiest approach to accomplish your task. For example:

$imageFragment = new WordFragment($docx, 'document');
$imageFragment->addImage(['src' => 'image.png']);

$docx->replaceVariableByWordFragment(['VAR_IMAGE' => $imageFragment], ['type' => 'block']);

The WordFragment can be generated with addImage, embedHTML or any other phpdocx content method (even multiple contents).
As other template methods, replacePlaceholderImage and replaceVariableByWordFragment replace all placeholders with the same name unless you set the firstMatch option as true.

Regards.

Posted by fiwoyax200  · 25-04-2024 - 10:37

Thanks for the response.

I have a Word document with a text placeholder of $IMAGE$. How would I be able to use replaceVariableByWordFragment to replace and add multiple images.

I have tried a work around using cloning blocks to create more than one placeholder, however, it just results in the first image being replaced by them all.

$BLOCK_FIRST$
$IMAGE$
$BLOCK_FIRST$
$docx->cloneBlock('FIRST');
$imageFragment = new WordFragment($docx, 'document');
$imageFragment->addImage(['src' => 'reports/Img/237/662834ac2885f.png'], $ImageProperties);
$docx->replaceVariableByWordFragment(['IMAGE' => $imageFragment], ['type' => 'block']);


$docx->cloneBlock('FIRST');
$imageFragment = new WordFragment($docx, 'document');
$imageFragment->addImage(['src' => 'reports/Img/237/662976a4c1b05.jpg']);
$docx->replaceVariableByWordFragment(['IMAGE' => $imageFragment], ['type' => 'block']);
$docx->cloneBlock('FIRST');
$docx->clearBlocks();

 

Posted by admin  · 25-04-2024 - 11:20

Hello,

You can add as many contents as needed in the WordFragment, including new placeholders to be replaced. For example:

$contentFragmentA = new WordFragment($docx, 'document');
$contentFragmentA->addImage(['src' => 'image.png']);
$contentFragmentA->addText('$NEWVAR$');

$docx->replaceVariableByWordFragment(['VAR' => $contentFragmentA], ['type' => 'block']);

$contentFragmentB = new WordFragment($docx, 'document');
$contentFragmentB->addImage(['src' => 'image2.png']);
$contentFragmentB->addText('More content');

$docx->replaceVariableByWordFragment(['NEWVAR' => $contentFragmentB], ['type' => 'block']);

Regarding the block question, we recommend you read the documentation available on Clone blocks replacing placeholders, that details how to clone blocks replacing contents. As exaplined on this page you can add the contents to be added or use the firstMatch option.

Regards.

Posted by fiwoyax200  · 25-04-2024 - 12:22

Thanks for the update.

The number of images can vary depending on the user (i.e. there could be 1 image or 3 images), however, if there were 3 images I was hoping to add them all in the same place in the document which I currently have a placeholder as $IMAGE$.

The code you previously provided would require me to have multiple placeholders 'VAR' and ' NEWVAR', however as I don't always know the number of images for each time the script is executed.

Is there away I could replace $IMAGE$ with multiple images?

Posted by admin  · 25-04-2024 - 12:54

Hello,

Yes, as explained in our previous reply, you can add as many contents as needed in the same WordFragment. For example, three images added as block contents (each image in its own pararagraph):

$contentFragment = new WordFragment($docx, 'document');
$contentFragment->addImage(['src' => 'image1.png']);
$contentFragment->addImage(['src' => 'image2.png']);
$contentFragment->addImage(['src' => 'image3.png']);

$docx->replaceVariableByWordFragment(['VAR_IMAGE' => $contentFragment], ['type' => 'block']);

Or three images added as inline images (in the same paragraph):

$contentFragment1 = new WordFragment($docx, 'document');
$contentFragment1->addImage(['src' => 'image1.png']);
$contentFragment2 = new WordFragment($docx, 'document');
$contentFragment2->addImage(['src' => 'image2.png']);
$contentFragment3 = new WordFragment($docx, 'document');
$contentFragment3->addImage(['src' => 'image3.png']);

$content = array();
$content[] = $contentFragment1;
$content[] = $contentFragment2;
$content[] = $contentFragment3;

$contentFragment = new WordFragment($docx);
$contentFragment->addText($content);

$docx->replaceVariableByWordFragment(['VAR_IMAGE' => $contentFragment], ['type' => 'block']);

replaceVariableByWordFragment supports doing block or inline type replacements.

We recommend you read the following documentation pages, that explains how to work with WordFragments (including samples):

Regards.

Posted by fiwoyax200  · 25-04-2024 - 16:06

Excellent. The first section of the code is exactly what I was after. Thank you very much for your support.