Batch printing PDF files with laravel - laravel

I have a program that can print an individual PDF when on a students file. I'm doing this using niklasravnsborg/laravel-pdf package in Laravel 5.7. It's working great because I can just stream the pdf from a view into the browser then print from there.
Now I'm wanting to batch print the PDF's at the end of the day instead of one by one. How can I do this? There's no documentation for this on the package repository.
Several ways I've thought of doing this: one, save each PDF as an image file then try to print all files in that folder at the end of the day. If I do this, how would I print all files in that folder?
Next: does anyone know a way to maybe append a new PDF to a variable containing all the previously looped pdf's?
For example:
$finalpdf;
$students = Student::all();
foreach($students as $student){
$pdf = PDF::loadView('pdf.document', $student);
$finalpdf .+ $pdf; //i know this line doesn't work, but how to alter it?
return $pdf->save('document.pdf');
}

After a few days of playing around, hopefully this solution helps someone in the future. I used another package called "lara pdf merger". By writing my files to a save destination, adding those files to a merged file, then deleting the saved files after download, I was able to get my functionality. This is my controller code:
use PDF;
use Illuminate\Filesystem\Filesystem;
use LynX39\LaraPdfMerger\Facades\PdfMerger;
public function batchPrint(){
$pdfMerger = PDFMerger::init();
$i = 0;
$students = Student::whereDate('updated_at', Carbon::today('America/Los_Angeles'))->get();
foreach ($students as $student) {
$pdf = PDF::loadView('printTables', compact('student'));
$pdf->save('pdf/document'.$i.'.pdf');
$pdfMerger->addPDF('pdf/document'.$i.'.pdf');
$i++;
}
$pdfMerger->merge();
$pdfMerger->save("file_name.pdf", "browser");
$file = new Filesystem;
$file->cleanDirectory('pdf');
}

Related

Delete wildcard files with Storage facade in Laravel

Is there a way which allows you to delete files with a wildcard through the Storage facade in Laravel?
use Illuminate\Support\Facades\Storage;
Storage::disk('foo')->delete('path/TO_DELETE*');
I may have a list like this
path/TO_DELETE_1
path/TO_DELETE_2
path/TO_KEEP_1
path/TO_PROCESS_1
But I want to delete only the files. I want to avoid path manipulation as much as possible
Suppose if you have files start with a_1.jpg,a_2.jpg then
$files = Storage::disk("public")->allFiles();
foreach ($files as $file){
if(Str::startsWith($file,"a_")){
Storage::disk('images')->delete($file);
}
}
or for multiple folder search
$directories = Storage::disk('public')->directories();
foreach ($directories as $directory){
$files= Storage::disk('public')->allFiles($directory);
foreach ($files as $file){
if(Str::startsWith($file,$directory."/"."a_")){
Storage::disk('public')->delete($file);
}
}
}
Another way is using File facade.
File::delete(File::glob(storage_path('app/public/*/a_*.*')));
For example you have multiple folders inside storage/app/pubic/ then you can specify like this.
app/public/*/a_*.*'
Here
First * is any folder inside public folder.
a_* means any file start from a_.
.* is any extension.
For last one i took help from this post
Ref:Delete files with wildcard in Laravel
The sub question here is how to get a list of filtered files in Laravel. This works pretty well:
$fileFilter = "someStringFilenameContains";
$files = collect($fileSource->files())->filter(function ($value) {
return str_contains($value, $fileFilter);
})->toArray();
You can modify str_contains (strstr(), substr() for instance) to suit your needs - anything that returns a truth value really.
This will give you an array of filenames that match your $fileFilter
then to answer the OP:
$fileSource->delete($files);

Paginate text file in Laravel 8

I want to display log file in browser, and that file could be big enough. So, I need to divide it, for example 100 lines per page.
Method looks like that for now:
public function show($request)
{
$file = File::get(storage_path("logs/$request.log"));
return view('backend.log', compact('file'));
}
How to add paginate(100) and how to display it in blade file? It doesn't work without Eloquent, but I don't need database.

Laravel Store only filename when uploading a file

I have the following code to upload and store the file.
$user->update([
'display_profile' => request()->display_profile->storeAs('avatars', $name,'public')
]);
This stores the file in the display_profile as avatars/filename.jpg.
Since I have multiple versions of the files for displaying around the views I am using prefixes like follow
thumb_filename.jpg
small_filename.jpg
large_filename.jpg
I will need to do a lot of string replace to insert the prefix in place to show the right version of the images. Is there anyway I can save just the filename in the database insteat of the full path?
If not whats the best way to show my files in the view?
I use this approach mostly:
$file = $request->file('display_profile');
$name = $file->getClientOriginalName() . '.' . $file->extension();
$file->storeAs('public/avatars', $name);
$user->update([
'display_profile' => $name
]);
When you retrieve a file from the request, this will be converted as an UploadedFile object. You can easily retrieve the original name as follow
$file = $request->display_profile;
$user->update([
'display_profile' => $file->getClientOriginalName()
]);
For your second question I suggest you to create a relation with a Image class where you can store all the image conversion you require. But this can be a little tricky and may require time to be coded. Fortunately there are tons of libraries that can handle this for you. My favourite is Laravel medialibrary

Append Rows to existing Excel document using Laravel-Excel

I have an existing Excel document, to which I want to append some data using Laravel-Excel. The package has nice documentation but unfortunately there is no full example showing how to do that, but only partial demonstration of manipulating rows.
What I am attempting to do is:
open the existing document
get the first sheet, append new
close the document
The code:
Excel::load($path . '/exported.xls', function($reader){
$sheet = $reader->getActiveSheet();
// Manipulate third row
$sheet->row(3, array(
'test1', 'test2'
));
});
Which results in
Call to undefined method PHPExcel_Worksheet::row()
Has anyone succeeded appending data with this package?
Laravel Excel 1.2.0 added support for appending rows (so modifying existing Excel files)
http://www.maatwebsite.nl/laravel-excel/docs/import#edit
The correct code would be:
Excel::load($path . '/exported.xls', function($reader)
{
$reader->sheet(function($sheet)
{
// Manipulate third row
$sheet->row(3, array(
'test1', 'test2'
));
});
})->export('xls');
It looks like you would use...
$sheet->appendRow(array(
'appended', 'appended'
));
Found in the docs here... http://www.maatwebsite.nl/laravel-excel/docs/export
Right now it is not possible to edit an Excel file like I intended to.
Source: package creator.

Migrating Wordpress Images to Drupal with Migrate 2.4

I'm having a time migrating images from Wordpress to Drupal with the Migrate 2.4 module. Here are my mappings:
$this->addFieldMapping('field_image','images');
$this->addFieldMapping('destination_file', 'images');
$this->addFieldMapping('field_image:source_dir')
->defaultValue('/Users/grafa/htdocs/wordpress/wp-content/uploads');
$this->addFieldMapping('field_image:file_class')
->defaultValue('MigrateFileUri');
The images come from a function that queries the wp_postmeta table then returns the result to the prepareRow() function.
function getImages($row) {
$post_id = $row->id;
$results = db_query("
SELECT pm.post_id, pm.meta_key, pm.meta_value FROM streetroots_wp.wp_postmeta AS pm LEFT JOIN streetroots_wp.wp_posts AS p ON pm.post_id=p.id WHERE p.post_parent = $post_id AND pm.meta_key='_wp_attached_file';");
$images = array();
foreach($results as $result) {
$images[] = $result->meta_value;
}
return !empty($images) ? $images : NULL;
}
This basically returns the image name and relative path from the wp_postmeta table something like '2012/05/figure1.jpg'. I then use prepareRow() like this:
function prepareRow($row) {
$row->images = $this->getImages($row);
}
I'm guessing there's something funky with how I'm using the new-ish migrate module that handles the file fields. The sql is outputs the file names correctly but it doesn't seem like the images are getting copied over. This is a Drupal 7 using Migrate 2.4. Any help is appreciated.
You might want to have a look at the beer.inc lines 377 - 383 within migrate_example folder and at the associated content type *migrate_example_beer* which has an image field defined not a file field which was my mistake and lead to my images not being populated.
Hope this helps!
Migrate 2.5 has largely simplified the handling of files, you should check it out!

Resources