2. Comment créer downloader dans CakePHP3
3. Comment créer downloader pour des fichiers de PDF dans CakePHP3
D'abord, nous avons besoin de installer libreoffice pour la conversion à PDF et lang-lack de libreoffice:
$ sudo yum install libreoffice libreoffice-langpack-fr
Et éditez la commande de sudo avec visudo et ajoutez "apache ALL=(ALL) NOPASSWD: /usr/bin/libreoffice" dans ce fichier:
$ sudo visudo
(Ajoutez "apache ALL=(ALL) NOPASSWD: /usr/bin/libreoffice" dans ce fichier)
(Ajoutez "apache ALL=(ALL) NOPASSWD: /usr/bin/libreoffice" dans ce fichier)
Redémarrer apache:
$ sudo service httpd restart
Ajoutez la fonction suivante dans l'index.ctp:
function downloadPdf(){
var files = getSelectedDocuments(true);
files_not_excel = files.files_notexcel;
files = files.checkeditems;
console.log(files);
if(files.length < 1 || files === undefined){
alert('Please select at least one Excel document.');
} else {
if(files_not_excel.length > 0 && files_not_excel !== undefined){
var r = confirm("The following files will not be converted to PDF because they are not excel files:\n"
+ files_not_excel.join(', '));
} else {
var r = true;
}
if(r === true){
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "pdfDownload")); ?>',
data: {'files' : files},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/' + data;
console.log(url);
download(url);
}
});
}
}
}
var files = getSelectedDocuments(true);
files_not_excel = files.files_notexcel;
files = files.checkeditems;
console.log(files);
if(files.length < 1 || files === undefined){
alert('Please select at least one Excel document.');
} else {
if(files_not_excel.length > 0 && files_not_excel !== undefined){
var r = confirm("The following files will not be converted to PDF because they are not excel files:\n"
+ files_not_excel.join(', '));
} else {
var r = true;
}
if(r === true){
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "pdfDownload")); ?>',
data: {'files' : files},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/' + data;
console.log(url);
download(url);
}
});
}
}
}
Et un bouton pour télécharger fichiers de PDF:
<p><a href="#" onclick="downloadPdf()">Download As PDF</a></p>
L'index.ctp dans l'ensemble:
<?php
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\Customer[]|\Cake\Collection\CollectionInterface $customers
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('New Customer'), ['action' => 'add']) ?></li>
</ul>
</nav>
<div class="customers index large-9 medium-8 columns content">
<h3><?= __('Customers') ?></h3>
<p><a href="#" onclick="downloadDocuments()">Download As Zip</a></p>
<p><a href="#" onclick="downloadPdf()">Download As PDF</a></p>
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th scope="col" class="text-center" style="vertical-align: middle;"><?= $this->Form->checkbox('check_all', ['id'=>'check_all']);?></th>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('name') ?></th>
<th scope="col"><?= $this->Paginator->sort('file_location', 'File') ?></th>
<th scope="col"><?= $this->Paginator->sort('created') ?></th>
<th scope="col"><?= $this->Paginator->sort('modified') ?></th>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($customers as $customer): ?>
<tr>
<?php $temp = explode('.', $customer->file_location); $extension = strtolower(end($temp)); ?>
<?php $file = ['file_location' => $customer->file_location, 'file_name'=>$customer->name, 'extension'=>$extension] ?>
<td class="text-center"><?= $this->Form->checkbox('checkbox',['name'=>'check_box', 'value'=>h(json_encode($file))]) ?></td>
<td><?= $this->Number->format($customer->id) ?></td>
<td><?= h($customer->name) ?></td>
<td><img src="/cake/uploads/customers/<?= $customer->file_location ?>" width="100" /></td>
<td><?= h($customer->created) ?></td>
<td><?= h($customer->modified) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $customer->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $customer->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $customer->id], ['confirm' => __('Are you sure you want to delete # {0}?', $customer->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$('#check_all').on('click', function() {
$('input:checkbox[name=check_box]').prop('checked', this.checked);
});
});
function getSelectedDocuments(pdfonly){
if (pdfonly === undefined) {
pdfonly = false;
}
var checkeditems = [];
var files_notexcel = [];
$("input[type=checkbox][name=check_box]").each(function(){
if (this.checked) {
var value = JSON.parse($(this).val());
if(pdfonly === true){
var extension = value.extension.toLowerCase();
if($.inArray(extension, ['xlsx','xlsm','xls']) !== -1){
checkeditems.push(value.file_location);
} else {
var name = value.file_location.split("/");
files_notexcel.push(name[name.length - 1]);
}
} else {
checkeditems.push(value.file_location);
}
}
});
var files = {"checkeditems" : checkeditems, "files_notexcel" : files_notexcel};
return files;
}
function download(url){
var link=document.createElement('a');
document.body.appendChild(link);
link.href=url;
link.download = 'download';
link.click();
link.parentNode.removeChild(link);
}
function downloadDocuments(){
var checkeditems = getSelectedDocuments();
checkeditems = checkeditems.checkeditems;
if(checkeditems.length < 1 || checkeditems === undefined){
alert('Please select at least one document.');
} else {
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "zipDownload")); ?>',
data: {'files' : checkeditems},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/'+data;
console.log(url);
download(url);
}
});
}
}
function downloadPdf(){
var files = getSelectedDocuments(true);
files_not_excel = files.files_notexcel;
files = files.checkeditems;
console.log(files);
if(files.length < 1 || files === undefined){
alert('Please select at least one Excel document.');
} else {
if(files_not_excel.length > 0 && files_not_excel !== undefined){
var r = confirm("The following files will not be converted to PDF because they are not excel files:\n"
+ files_not_excel.join(', '));
} else {
var r = true;
}
if(r === true){
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "pdfDownload")); ?>',
data: {'files' : files},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/' + data;
console.log(url);
download(url);
}
});
}
}
}
</script>
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\Customer[]|\Cake\Collection\CollectionInterface $customers
*/
?>
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('New Customer'), ['action' => 'add']) ?></li>
</ul>
</nav>
<div class="customers index large-9 medium-8 columns content">
<h3><?= __('Customers') ?></h3>
<p><a href="#" onclick="downloadDocuments()">Download As Zip</a></p>
<p><a href="#" onclick="downloadPdf()">Download As PDF</a></p>
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th scope="col" class="text-center" style="vertical-align: middle;"><?= $this->Form->checkbox('check_all', ['id'=>'check_all']);?></th>
<th scope="col"><?= $this->Paginator->sort('id') ?></th>
<th scope="col"><?= $this->Paginator->sort('name') ?></th>
<th scope="col"><?= $this->Paginator->sort('file_location', 'File') ?></th>
<th scope="col"><?= $this->Paginator->sort('created') ?></th>
<th scope="col"><?= $this->Paginator->sort('modified') ?></th>
<th scope="col" class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($customers as $customer): ?>
<tr>
<?php $temp = explode('.', $customer->file_location); $extension = strtolower(end($temp)); ?>
<?php $file = ['file_location' => $customer->file_location, 'file_name'=>$customer->name, 'extension'=>$extension] ?>
<td class="text-center"><?= $this->Form->checkbox('checkbox',['name'=>'check_box', 'value'=>h(json_encode($file))]) ?></td>
<td><?= $this->Number->format($customer->id) ?></td>
<td><?= h($customer->name) ?></td>
<td><img src="/cake/uploads/customers/<?= $customer->file_location ?>" width="100" /></td>
<td><?= h($customer->created) ?></td>
<td><?= h($customer->modified) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $customer->id]) ?>
<?= $this->Html->link(__('Edit'), ['action' => 'edit', $customer->id]) ?>
<?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $customer->id], ['confirm' => __('Are you sure you want to delete # {0}?', $customer->id)]) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="paginator">
<ul class="pagination">
<?= $this->Paginator->first('<< ' . __('first')) ?>
<?= $this->Paginator->prev('< ' . __('previous')) ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next(__('next') . ' >') ?>
<?= $this->Paginator->last(__('last') . ' >>') ?>
</ul>
<p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$('#check_all').on('click', function() {
$('input:checkbox[name=check_box]').prop('checked', this.checked);
});
});
function getSelectedDocuments(pdfonly){
if (pdfonly === undefined) {
pdfonly = false;
}
var checkeditems = [];
var files_notexcel = [];
$("input[type=checkbox][name=check_box]").each(function(){
if (this.checked) {
var value = JSON.parse($(this).val());
if(pdfonly === true){
var extension = value.extension.toLowerCase();
if($.inArray(extension, ['xlsx','xlsm','xls']) !== -1){
checkeditems.push(value.file_location);
} else {
var name = value.file_location.split("/");
files_notexcel.push(name[name.length - 1]);
}
} else {
checkeditems.push(value.file_location);
}
}
});
var files = {"checkeditems" : checkeditems, "files_notexcel" : files_notexcel};
return files;
}
function download(url){
var link=document.createElement('a');
document.body.appendChild(link);
link.href=url;
link.download = 'download';
link.click();
link.parentNode.removeChild(link);
}
function downloadDocuments(){
var checkeditems = getSelectedDocuments();
checkeditems = checkeditems.checkeditems;
if(checkeditems.length < 1 || checkeditems === undefined){
alert('Please select at least one document.');
} else {
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "zipDownload")); ?>',
data: {'files' : checkeditems},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/'+data;
console.log(url);
download(url);
}
});
}
}
function downloadPdf(){
var files = getSelectedDocuments(true);
files_not_excel = files.files_notexcel;
files = files.checkeditems;
console.log(files);
if(files.length < 1 || files === undefined){
alert('Please select at least one Excel document.');
} else {
if(files_not_excel.length > 0 && files_not_excel !== undefined){
var r = confirm("The following files will not be converted to PDF because they are not excel files:\n"
+ files_not_excel.join(', '));
} else {
var r = true;
}
if(r === true){
var csrfToken = $('[name=_csrfToken]').val();
$.ajax({
type: "POST",
url: '<?= $this->Url->build(array("controller" => "Customers", "action" => "pdfDownload")); ?>',
data: {'files' : files},
beforeSend: function(xhr){
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
},
success: function(data){
var url = '/cake/temp/zip/' + data;
console.log(url);
download(url);
}
});
}
}
}
</script>
Changez le controller de customers et ajoutez les fonctions suivantes comme ça:
function createZip($uploadToDir = null, $copyFromDir = null, $files = null, $containsYearmonth = false){
if(!file_exists($uploadToDir)){
if(!mkdir($uploadToDir, 0755, true)){
throw new BadRequestException('Can not mkdir.');
}
chmod($uploadToDir, 0755);
}
try {
$zip = new ZipArchive();
$zip_file_name = sha1(time() . rand()).".zip";
$zip_name = $uploadToDir.$zip_file_name; // Zip name
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($files as $file) {
$path = $copyFromDir.$file;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo "file does not exist";
}
}
$zip->close();
return $zip_file_name;
} catch (BadRequestException $e) {
throw $e;
}
}
public function pdfDownload(){
if ($this->request->is('ajax')) {
$files = $this->request->data['files'];
$layout = 'ajax';
$this->loadModel('Documents');
$this->autoRender = false;
try {
$filesPdf = [];
$uploadToDirPdf = WWW_ROOT.'temp/zip/';
$copyFromDirPdf = WWW_ROOT.'uploads/customers/';
$uploadToDirZip = WWW_ROOT.'temp/zip/';
$copyFromDirZip = WWW_ROOT;
foreach($files as $file){
$extension = $this->getExtension($file);
if(in_array($extension,array_map('strtolower',['xlsx','xlsm','xls']))){
$pathPdf = $this->excelToPdf($uploadToDirPdf, $copyFromDirPdf, $file);
array_push($filesPdf, $pathPdf);
}
}
$pathZip = $this->createZip($uploadToDirZip, $copyFromDirZip, $filesPdf);
}catch(BadRequestException $b){
//$this->Flash->error(__($b->getMessage()));
}
echo $pathZip;
}
}
private function excelToPdf($uploadToDir = null, $copyFromDir = null, $file = null){
$filePath = explode("/", $file);
$today = new Date();
$yearmonth = $today->i18nFormat('yyyyMM');
$dir = $uploadToDir.$filePath[0];
if(!file_exists($dir)){
if(!mkdir($dir, 0755, true)){
throw new BadRequestException('Couldn\'t make directory.');
}
chmod($dir, 0755);
}
$command = 'sudo /usr/bin/libreoffice --headless --invisible --norestore --nologo --nofirststartwizard --convert-to pdf --outdir "'
.$uploadToDir.$filePath[0].'" "'
.$copyFromDir.$file.'"';
$result = shell_exec($command);
if(is_null($result)){
throw new BadRequestException('pdf couldn\'t be created.');
}
$filenameArray = explode(".", $file);
$filename = "";
for($i = 0; $i < count($filenameArray)-1; $i++){
$filename .= $filenameArray[$i];
}
return 'temp/zip/'.$filename.'.pdf';
}
if(!file_exists($uploadToDir)){
if(!mkdir($uploadToDir, 0755, true)){
throw new BadRequestException('Can not mkdir.');
}
chmod($uploadToDir, 0755);
}
try {
$zip = new ZipArchive();
$zip_file_name = sha1(time() . rand()).".zip";
$zip_name = $uploadToDir.$zip_file_name; // Zip name
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($files as $file) {
$path = $copyFromDir.$file;
if(file_exists($path)){
$zip->addFromString(basename($path), file_get_contents($path));
}
else{
echo "file does not exist";
}
}
$zip->close();
return $zip_file_name;
} catch (BadRequestException $e) {
throw $e;
}
}
public function pdfDownload(){
if ($this->request->is('ajax')) {
$files = $this->request->data['files'];
$layout = 'ajax';
$this->loadModel('Documents');
$this->autoRender = false;
try {
$filesPdf = [];
$uploadToDirPdf = WWW_ROOT.'temp/zip/';
$copyFromDirPdf = WWW_ROOT.'uploads/customers/';
$uploadToDirZip = WWW_ROOT.'temp/zip/';
$copyFromDirZip = WWW_ROOT;
foreach($files as $file){
$extension = $this->getExtension($file);
if(in_array($extension,array_map('strtolower',['xlsx','xlsm','xls']))){
$pathPdf = $this->excelToPdf($uploadToDirPdf, $copyFromDirPdf, $file);
array_push($filesPdf, $pathPdf);
}
}
$pathZip = $this->createZip($uploadToDirZip, $copyFromDirZip, $filesPdf);
}catch(BadRequestException $b){
//$this->Flash->error(__($b->getMessage()));
}
echo $pathZip;
}
}
private function excelToPdf($uploadToDir = null, $copyFromDir = null, $file = null){
$filePath = explode("/", $file);
$today = new Date();
$yearmonth = $today->i18nFormat('yyyyMM');
$dir = $uploadToDir.$filePath[0];
if(!file_exists($dir)){
if(!mkdir($dir, 0755, true)){
throw new BadRequestException('Couldn\'t make directory.');
}
chmod($dir, 0755);
}
$command = 'sudo /usr/bin/libreoffice --headless --invisible --norestore --nologo --nofirststartwizard --convert-to pdf --outdir "'
.$uploadToDir.$filePath[0].'" "'
.$copyFromDir.$file.'"';
$result = shell_exec($command);
if(is_null($result)){
throw new BadRequestException('pdf couldn\'t be created.');
}
$filenameArray = explode(".", $file);
$filename = "";
for($i = 0; $i < count($filenameArray)-1; $i++){
$filename .= $filenameArray[$i];
}
return 'temp/zip/'.$filename.'.pdf';
}
Maintenant vous pouvez télécharger les fichiers comme PDF dans l'index.ctp.
Aucun commentaire:
Enregistrer un commentaire