This topic is locked

How to use PHPRunner and PHPWord for previews of docx files

8/11/2024 8:35:08 AM
PHPRunner Tips and Tricks
C
cristi author

In this tutorial I'll show a method to have previews (without download and open in ms word) of docx files.
For this I will use the open source PHPWord library.
Now, PHPWord can't be directly downloaded and referenced in our scripts so we need an workaround for using it without the Composer.
I uploaded an archive with PHPWord that can be used without Composer here
You need to download that archive, decompress it and upload the files and folder in the root directory of your solution.
Create a table - or use an existing one - for the sake of this example I will create a table "Office":


CREATE TABLE `office` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`document` mediumtext DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci

This table has a primary key id and a field for uploading files called "document".
In visual designer make the document field of type 'File' in view as and 'File/Image' in edit as. Also in 'edit as' name a folder where the uploaded documents will be stored, check "delete file when associeted record is deleted" and linit the number of files to store at 1.

img alt

img alt

Be carefull to create that folder on the server with the necessary rights! - PHPRunner will not create it for you.

Now in the table 'After table initialized' event include this code:

require_once 'bootstrap.php'; //this assumes that you uploaded the content of the PHPWord archive in the root directory of your webfolder and it creates the references for PHPWord library and functions without the Composer

In The visual Designer of List page add a column next to your existing ones and insert a custom button - let's call it "preview_docs"

img alt

Comment everything in the 'client before' - we will work only with 'server' and 'client after' events.

In the server event insert this code:


$record = $button->getCurrentRecord(); //get the contents of the record

$filesArray = array();

$files = my_json_decode($record["document"]);
//if you do a var_dump of this array you will notice a lot of usefull info like "usrName", "name", "type" attributes for the uploaded file

foreach($files as $file){
$filesArray[] = $file;
}

foreach($filesArray as $doc)

$ext = pathinfo($doc["name"], PATHINFO_EXTENSION);
if($ext!='docx') //check if uploaded file is docx, if not show an warning message.
//you can also use $mimeType = $doc["type"];
//if($mimeType == 'application/vnd.google-apps.document' || $mimeType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || $mimeType == 'application/msword'){

{
$result["txt"]='<!DOCTYPE html><html><head><title>Warning</title></head><body>You can only preview docx files.

</body></html>'; //The head part is only usefull if you want to display an iframe directly on the page instead of a popup like in this example

}
else
{
if (!file_exists($doc["name"].'.html')) //we don't want to create and rewrite a new html file over the existing one everytime somebody opens a preview
{

$phpWord = \PhpOffice\PhpWord\IOFactory::load($doc["name"]);
$htmlWriter = new \PhpOffice\PhpWord\Writer\HTML($phpWord);
$htmlWriter->save($doc["name"].'.html');

}
$result["txt"]='<iframe src="'.$doc["name"].'.html" width="700" height="500"></iframe>';
}

In the client after:

var message = result["txt"];
Swal.fire({
title: 'Preview',
html:message,
icon: 'info',
showCancelButton: false,
showCloseButton: true,
showConfirmButton: false,
width: '800px'
})

img alt

And that's it - as you can see not a lot of code and not complicated at all to obtain your own preview platform for office docx format documents.
As a note old doc format is not supported because PHPWord dooes not support this.
You can obtain a similar functionality for excel files with PHPSpreedsheet but as the warning in the documentation says if you have formatted cells, rtext, images, charts, etc it will look ""ugly" - misaligned text, etc.