i have this simple code that generate a new .docx file from a sample with some "token" to modify
this code work in a local MAMP webserver
$template_file_name = 'template2.docx';
$rand_no = rand(111111, 999999);
$fileName = "results_" . $rand_no . ".docx";
$folder = "results";
$full_path = $folder . '/' . $fileName;
echo $full_path;
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("token1", "text to replace", $message);
//Replace the content with the new content created above.
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
}
echo "<script type='text/javascript'>alert('file creato');</script>";
}
catch (Exception $exc)
{
$error_message = "Error creating the Word Document";
var_dump($exc);
}
in online webserver despite the file and folder are 777 privileges ,the file was created but without my text to replace
in codeigniter i get this error:
$message = $zip_val->getFromName($key_file_name);
$zip_val->addFromString($key_file_name, $message);
$zip_val->close();
anyone can help me ?
the stranger thigs are that in webserver in local work without problem, on webserver online doesnt work
i hope in your answer
thanks a lot
Related
I have a folder in my web server were I put zip files that I need to then unzip. I want to do that with php and this is what I have tried but it does not work:
<?php
$file = $_GET["file"];
$zip = new ZipArchive;
$res = $zip->open($file+'.zip');
$zip->extractTo('./');
$zip->close();
?>
The zip files are in the same folder as the php file, but when I go to the php page it does nothing.
By doing some testing I have found out that the script dies on the $zip = new ZipArchive; line
How can I manage this to work?
<?php
$fileName = $_GET['file']; // get file name in the URL param "file"
if (isset($fileName)) { // if $fileName php variable is set than
$zip = new ZipArchive; // create object
$res = $zip->open($fileName); // open archive
if ($res === TRUE) {
$zip->extractTo('./'); // extract contents to destination directory
$zip->close(); //close the archieve
echo 'Extracted file "'.$fileName.'"';
} else {
echo 'Cannot find the file name "'.$fileName.'" (the file name should include extension (.zip, ...))';
}
}
else {
echo 'Please set file name in the "file" param';
}
?>
Note:- For More Details Please refer https://www.php.net/manual/en/class.ziparchive.php
I have found the problem.
The code is fine, but the hosting service is not, and they do not have the ZIP extension available right now
Try this code. Also change $zip->open($file+".zip"); to $zip->open($file);.
+ (plus sign) is not concatenation operator in php
<?php
// $_GET["file"] is set to `a.zip`
$file = $_GET["file"];
$zip = new ZipArchive;
$res = $zip->open($file);
$zip->extractTo('./');
$zip->close();
?>
I'm trying to follow this link: https://learn.microsoft.com/en-us/rest/api/storageservices/copy-file
with examples from this repo: https://github.com/Azure/azure-storage-php/blob/master/samples/FileSamples.php#L235
The file is indeed copied to the azure server but the content aren't readable, to say the least, it takes a size but it's empty. This is only a text file as well, and what I plan to achieve after fixing this is to copy excel files generated via PHP to an azure file storage server.
Also, we are using file.core not blob.core
<?php
require_once "vendor/autoload.php";
use MicrosoftAzure\Storage\File\FileRestProxy;
use MicrosoftAzure\Storage\Common\Models\Range;
$accountName = "test";
$accountKey = "test";
$shareName = 'test';
$connectionString = "DefaultEndpointsProtocol=https;AccountName=$accountName;AccountKey=$accountKey";
$fileClient = FileRestProxy::createFileService($connectionString);
$dstfileName = 'demo-4.txt';
$srcfileName = 'demo-4.txt';
$sourcePath = sprintf(
'%s%s/%s',
(string)$fileClient->getPsrPrimaryUri(),
$shareName,
$srcfileName
);
try {
// Create destination file.
$fileClient->createFile($shareName, $dstfileName, 1024);
// Copy file.
return $fileClient->copyFile($shareName, $dstfileName, $sourcePath);
} catch (ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code . ": " . $error_message . PHP_EOL;
}
Update using file_get_contents
$srcfileName = 'demo-4.txt';
$content = file_get_contents('demo-4.txt');
$range = new Range(0, filesize('demo-4.txt') - 1);
$sourcePath = sprintf(
'%s%s/%s',
(string)$fileClient->getPsrPrimaryUri(),
$shareName,
$srcfileName
);
try {
// Create source file.
$fileClient->createFile($shareName, $srcfileName, 1024);
$fileClient->putFileRange($shareName, $srcfileName, $content, $range);
} catch (ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code . ": " . $error_message . PHP_EOL;
}
This is able to create the file with the content from the source file, but the problem is that the range is incorrect since I don't know how to correctly get that value.
The created file is presented by the image attached, it has multiple nulls in it because I'm guessing my range exceeds the actual length of the source file contents.
createFile method simply creates an empty file of size specified in the method call. It essentially maps to Create File REST API operation.
You should use createFileFromContent convenience method to create a file with content. It basically first creates an empty file and then writes the contents to that file.
Other option would be to call putFileRange method to write the contents to the file after you have created it using createFile method.
I have zip files with only one file inside it, but it has new name every time. I need to extract file and save it with specific file name, not extracted one.
$zip = new ZipArchive;
$res = $zip->open($tmp_name);
if ($res === TRUE) {
$path = _PATH."/files/";
$zip->extractTo($path);
$zip->close();
echo 'Unzip!';
}
Abowe code works, but I need to have specific filename. For example anyfile located under zip (eg. pricelist025.xml should be named temp.xml
Rename your specific file before you extract it.
$zip = new ZipArchive;
$res = $zip->open($tmp_name);
if ($res === TRUE) {
$zip->renameName('pricelist025.xml','temp.xml');
$path = _PATH."/files/";
$zip->extractTo($path);
$zip->close();
echo 'Unzip!';
} else {
echo 'failed, code:' . $res;
}
I hope this works.
UPDATE 1
There is two options if you want to change the file names.
1. change the file names before extracting -This way zip files will be modified
2. change the file names after extracting -Zip files will remain as they were before
Changing file names before extracting
We have to define a pattern for filenames. Here, Files will be in this patter : myfile0.xml, myfile1.html, adn so on..
Note: extension will be preserved.
$zip = new ZipArchive;
$res = $zip->open('hello.zip');
$newfilename = 'myfile';
for($i=0;$i<$zip->count();$i++)
{
$extension = pathinfo($zip->getNameIndex($i))['extension'];
$zip->renameName($zip->getNameIndex($i), $newfilename.$i.'.'.$extension);
}
Chaning file names after extracting
File names will in the same pattern as above.
$directory = 'hello/'; //your extracted directory
$newfilename = 'myfile';
foreach (glob($directory."*.*") as $index=>$filename) {
$basename = pathinfo($filename)['basename'];
if(!preg_match('/myfile\d\./', $basename)) {
$extension = pathinfo($filename)['extension'];
rename($filename,$newfilename.$index.'.'.$extension);
}
}
What we are here scanning the all the files from the extracted directory for which doesn't have a filename in the patter myfile[num]. and then we are changing it's name.
UPDATE 2
I just noticed you have updated your question.
As you have just one file and you want to extract it every time with different name. You should rename it every time you extract.
$zip = new ZipArchive;
$newfilename = "myfile".rand(1,999); //you can define any safe pattern here that suites you
if($zip->open('help.zip')===TRUE)
{
$path = '/your/path/to/directory';
$filename = $zip->getNameIndex(0);
if($zip->extractTo($path))
{
echo "Extracted";
}else{
echo "Extraction Failed";
exit();
}
$extension = pathinfo($filename)['extension'];
rename($path."/$filename",$path."/$newfilename".'.'.$extension);
echo "Extracted with different name successfully!";
} else {
echo "Failed";
}
I have this code to read a file for preview, but the downside is I have to download the file first from cloud and read from it, but it's a waste of space so I want to delete it after viewing a certain file. Is there an automatic way of doing this? Or do I have to integrate it to a close button?
// Get the container we want to use
$container = $conn->get_container('mailtemplate');
//$filename = 'template1.zip';
// upload file to Rackspace
$object = $container->get_object($filename);
//var_dump($object);
//echo '<pre>' . print_r($object,true) . '</pre>';
$localfile = $dir.$filename;
//echo $localfile;
$object->save_to_filename($localfile);
if($_GET['preview'] == "true")
{
$dir = "../mailtemplates/";
$file1 = $_GET['tfilename'];
$file = $dir.$file1;
$file2 = "index.html";
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']);
$path = $file_name.'/'.$file2;
$zip = new ZipArchive();
$zip->open($file);
$fp = $zip->getStream($path);
if(!$fp)
{
exit("faileds\n");
$zip->close();
unlink($dir.$filename);
}
else
{
$stuff = stream_get_contents($fp);
echo $stuff;
$zip->close();
if($stuff != null)
{
unlink($dir.$filename);
}
}
}
else
{
unlink($dir.$filename);
}
You didn't google this did ya?
Try Unlink
Edit:
Taking a look at this code, $zip->open($file); <-- is where you open the file. The file variable is set by:
"../mailtemplates/" . basename($_GET['tfilename'], '.' . $info['extension']) . '/' . "index.html"
So you're grabbing a relative directory and grabbing a filename as a folder, and going to that folder /index.html. Here's an example:
if you're in c:\ testing and you go to ../mailtemplates/ you'll be in c:\mailtemplates and then you're looking at file test.php but you're removing the file extension, so you'll be opening the location c:\mailtemplates\test\index.html so you open up that html file and read it. Then, you're trying to delete c:\mailtemplates\test.php
can you explain how any of that makes sense to you? 'cause that seems very odd to me.
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);