PHP: creating .docx document using .xml - php

I'm working on a project where I need to create a .docx document. I was using PHPWord, loading a template and then saving the file. This document has a lot of nested tables and PHPWord is breaking the tables after some replaces in the template.
So I decided to save the document as Word XML document (.xml) and do the replaces myself. I will load the text into a variable, do the replaces and then save as a new word document. My problem is that I don't know how to create a .docx document using a .xml.
Would you have some code snippets I could use?
Thanks for any help
I have come to the piece of code below. It saves the file but when I try to open using word it gives me invalid document
$xmlString = simplexml_load_file($this->config->application->fileTemplateFolder.'coi.xml')->asXML();
$xmlString = str_replace('${coi_number}', $coi['application_number'], $xmlString);
$path = $this->config->application->fileTemplateFolder.'test.docx';
$zip = new ZipArchive();
$zip->open($path, ZipArchive::CREATE);
$zip->addFromString("word/document.xml", $xmlString);
$zip->close();

Here is how I solved the issue:
private function CreateWordDocument($xmlString) {
$templateFolder = $this->config->fileTemplateFolder;
if(!endsWith($templateFolder, '/'))
$templateFolder = $templateFolder.'/';
$temp_file = tempnam(sys_get_temp_dir(), 'coi_').'.docx';
copy($templateFolder. 'coi.docx', $temp_file);
$zip = new ZipArchive();
if($zip->open($temp_file)===TRUE) {
$zip->deleteName('word/document.xml');
$zip->addFromString("word/document.xml", $xmlString);
$zip->close();
return $temp_file;
}
else {
return null;
}
}

Related

PHP - Editing a file in zip archive and saving as another archive name before close

I have a Microsoft Word file that I am using as a template. (testingsample.docx) The plan is to use form input values to create a lease agreement. The code I found below works very well for opening up the .docx file and finding and replacing the required strings. The problem is it only works once. The first time it is ran, it overwrites my template. I am trying to find a way to open testingsample.docx, make the required string changes, and save the archive as testingsamplecopy.docx without altering testingsample.docx.
Thanks in advance for any help!
// Create the Object.
$zip = new ZipArchive();
$inputFilename = 'testingsample.docx';
// Open the Microsoft Word .docx file as if it were a zip file... because it is.
if ($zip->open($inputFilename, ZipArchive::CREATE)!==TRUE) {
echo "Cannot open $inputFilename :( "; die;
}
// Fetch the document.xml file from the word subdirectory in the archive.
$xml = $zip->getFromName('word/document.xml');
// Replace the strings
$xml = str_replace("1111","Tenant Name Here",$xml);
$xml = str_replace("2222","Address Here",$xml);
// Write back to the document and close the object
if ($zip->addFromString('word/document.xml', $xml)) { echo 'File written!'; }
else { echo 'File not written. Go back and add write permissions to this folder!l'; }
$zip->close();
header("Location: testingsample.docx");
?>
Just copy from the template file to the target file, then open the target file and not the template.
Also, I changed the code at the header line to use the variable of the name of the file and not a static one.
<?php
// Create the Object.
$zip = new ZipArchive();
$templateFilename = 'testingsample.docx';
$inputFilename = 'testingsamplecopy.docx';
if(!copy($templateFilename, $inputFilename)) {
die("Could not copy '$templateFilename' to '$inputFilename');
}
// Open the Microsoft Word .docx file as if it were a zip file... because it is.
if ($zip->open($inputFilename, ZipArchive::CREATE)!==TRUE) {
echo "Cannot open $inputFilename :( "; die;
}
// Fetch the document.xml file from the word subdirectory in the archive.
$xml = $zip->getFromName('word/document.xml');
// Replace the strings
$xml = str_replace("1111","Tenant Name Here",$xml);
$xml = str_replace("2222","Address Here",$xml);
// Write back to the document and close the object
if ($zip->addFromString('word/document.xml', $xml)) { echo 'File written!'; }
else { echo 'File not written. Go back and add write permissions to this folder!l'; }
$zip->close();
// I also chaned this to use your variable instead of a static value.
header("Location: $inputFilename");
?>

Trying to Use PHP's Zip Archive - Extract To Doesn't Seem to be Working

Would appreciate some help on this. I've been trying to write a PHP script that Unzips a zip file that has been created using PHP's in-built Zip Archive extension.
The zipping-up process has been very straight forward but now I'm trying to unzip this to a particular folder and it doesn't seem to be working. The only thing it does is create the folder I've asked it to extract to. No files appear in that folder.
I've had no error messages.
Thanks in Advance. Here's my code:
<?php
$root = str_replace('public_html', '', $_SERVER["DOCUMENT_ROOT"]);
$path = $root.'scripts.zip';
$zip = new ZipArchive;
$zipped = $zip->open($path, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE);
$folder = $root.'public_html/scripts/';
if ($zipped) {
$extract = $zip->extractTo($folder);
if ($extract){
echo 'Zip File Extracted';
}
$zip->close();
}
?>
I would modify your code to look like the one below.
What you were doing was creating a new zip file, not extracting the old one. ZIPARCHIVE::CREATE instructs the code to create a zip, ZIPARCHIVE::OVERWRITE tells it to overwrite existing files in the zip.
So you are not extracting anything from the zip. This code below should work
<?php
$root = str_replace('public_html', '', $_SERVER["DOCUMENT_ROOT"]);
$path = $root.'scripts.zip';
$zip = new ZipArchive;
$zipped = $zip->open($path); /*I have removed the ::CREATE & ::OVERWRITE methods*/
$folder = $root.'public_html/scripts/';
if ($zipped) {
$extract = $zip->extractTo($folder);
if ($extract){
echo 'Zip File Extracted';
}
$zip->close();
}
?>
Hope that helps

Get content of docx file which saved in mysql dabase as blob type in php

I am saving docx file as BLOB type in mysql dadabase. after the saveing i am trying to see the content of the file through fetching the content of filed but it is showing some unreadable content.This this is working well for file having extention .doc but i don't know why it is not working for the .docx file.If any answer please help with proper explanation.
Make a query to select the data, then put the result in a variable.
Use file_put_content to get the docx file. Just be carefull with header.
To read it, the process is different from a doc. You have to "unzip" the docx and read the xml file inside it. You can use this function:
<?php
/*Name of the document file*/
$document = 'filename.docx';
/**Function to extract text*/
function extracttext($filename) {
//Check for extension
$ext = end(explode('.', $filename));
//if its docx file
if($ext == 'docx')
$dataFile = "word/document.xml";
//else it must be odt file
else
$dataFile = "content.xml";
//Create a new ZIP archive object
$zip = new ZipArchive;
// Open the archive file
if (true === $zip->open($filename)) {
// If successful, search for the data file in the archive
if (($index = $zip->locateName($dataFile)) !== false) {
// Index found! Now read it to a string
$text = $zip->getFromIndex($index);
// Load XML from a string
// Ignore errors and warnings
$xml = DOMDocument::loadXML($text, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
// Remove XML formatting tags and return the text
return strip_tags($xml->saveXML());
}
//Close the archive file
$zip->close();
}
// In case of failure return a message
return "File not found";
}
echo extracttext($document);
?>
(source of the code: http://www.botskool.com/geeks/how-extract-text-docx-or-odt-files-using-php)
Docx is a zipped file type See Tag Wiki
That's why you can't get the content of the document from the raw content.
I found this solution :
"update blob_table set blob_col='LOAD_FILE('$tmp_name')";
where $tmp_name is the file you upload, and this is the answer for this 6 years old question, using LOAD_FILE function. may be this is a newly added function to mysql.

PHP Word File line counter

I need to make a PHP function that will count the number of lines in a Word File (.doc, docx)
This code does not seem to work correctly for me :
$name = 'test.doc';
$line_count = count(file($name));
echo $line_count
My guess is that this script does not work well with .doc or .docx but works good in .txt files. Are there any alternatives available out there? Tnx!
Only .docx can be opened with simple PHP as it is a zip file:
$zip = new ZipArchive;
if ($zip->open('test.docx') === TRUE) {
$xml = $zip->getFromName('docProps/app.xml');
$zip->close();
} else {
$xml = false;
}
if($xml){
$xml = simplexml_load_string($xml);
echo $xml->Lines;
}

Edit .doc or .docx file using php

I have to modify the uploaded .doc or .docx file in php. I googled but i only found how to read that. I want the word file as it is and put text at the bottom of that MS Word file at run time. How is this possible anyone know please reply or give me example script.
Thanks,
I'm the developer of PHPWord. You can use the PHPWord_Template Class to open an existing DOCX File and then replace some text marks with your individual text.
Alternatively you can open the DOCX file with the ZipArchive extension and then read/write every xml File (document.xml, header.xml, footer.xml, ...) you want. This method is nothing else than the PHPWord_Template class. ;)
You can use PHPWord.
I have same requirement for Edit .doc or .docx file using php and i have find solution for it.
And i have write post on It :: http://www.onlinecode.org/update-docx-file-using-php/
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("client_full_name", "onlinecode org", $message);
$message = str_replace("client_email_address", "ingo#onlinecode.org", $message);
$message = str_replace("date_today", $timestamp, $message);
$message = str_replace("client_website", "www.onlinecode.org", $message);
$message = str_replace("client_mobile_number", "+1999999999", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
You only replace the predefined variables.
In the following code
https://github.com/PHPOffice/PHPWord
I also did this problem in phpword using the following code
if(!file_exists('file/word.docx')){
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('demo.docx');
$templateProcessor->setValue('name', 'Akbarali');
$templateProcessor->setValue('time','13.02.2021');
$templateProcessor->setValue('month', 'January');
$templateProcessor->setValue('state','Uzbekistan');
$templateProcessor->saveAs('file/word.docx');
}
This will change the words in the demo.docx file. The new file is then saved in the word.docx file folder.
you can define variables in the form of ${name} in the demo word file.
that is, ${name}, ${time}, ${month} and ${state}
In this post we will show you How to update docx file using php, hear for How to update docx file using php we will give you demo and example for implement.
Hear we will show you how to Edit .doc or .docx file using php. Hear we use “client_full_name”, “client_email_address”, “date_today”, “client_website”, “client_mobile_number” in .doc or .docx files
$template_file_name = 'template.docx';
$rand_no = rand(111111, 999999);
$fileName = "results_" . $rand_no . ".docx";
$folder = "results_";
$full_path = $folder . '/' . $fileName;
try
{
if (!file_exists($folder))
{
mkdir($folder);
}
//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("client_full_name", "onlinecode org", $message);
$message = str_replace("client_email_address", "ingo#onlinecode", $message);
$message = str_replace("date_today", $timestamp, $message);
$message = str_replace("client_website", "www.onlinecode", $message);
$message = str_replace("client_mobile_number", "+1999999999", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
}
catch (Exception $exc)
{
$error_message = "Error creating the Word Document";
var_dump($exc);
}
Try having a look at http://www.tinybutstrong.com/ as it can create and edit Word documents, we use it in a mail merge style for generating invoices in doc and pdf.
Some of these answers dont contain the full steps so here is what ive done:
Create your word document. With in this document anything you want to replace with PHPWORD mark it like this -> ${variable_name} so for example ${value1}
$file = "docs/input/word/source.docx";
$output_file = "docs/input/word/modified.docx";
$PHPWord = new \PhpOffice\PhpWord\PhpWord();
$document = $PHPWord->loadTemplate($file);
$document->setValue('value1', 'Enter Your Text Here');
$document->saveAs($output_file);

Categories