Laravel maatwebsite/excel (PhpSpreadsheet) and TCPDF wrong sheet orientation - laravel

I have a Laravel application using the maatwebsite/excel package to generate and excel file. I also allow the user to download that excel file as a PDF.
The problem is that when the pdf is generated, the pagination is vertical and the content gets cut.
I have the excel file set to landscape but the pagination is still vertical. I can not find in the docs a way to set the pdf direction
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
// Landscope orientation
$event->sheet->getDelegate()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
}
];
}
I'm exporting the PDF file using the TCPDF library. I've seen a parameter in the docs to set as landscape but I can not figure out the way to pass the parameter to the TCPDF constructor with the maatwebsite/excel api. This is the syntax:
return (new GanttExport)->download('gantt_' . time() . '.pdf', Excel::TCPDF);

Have you tried using BeforeSheet event? It does work in my code. And dont forget to implement Maatwebsite\Excel\Concerns\WithEvents interface within the class.
public function registerEvents(): array
{
return [
BeforeSheet::class => function (BeforeSheet $event) {
$event->sheet
->getPageSetup()
->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
}
];
}

Related

Can we make heading not editable in laravel-excel export

I'm using Maatwebsite\Excel to download excel file. When the file downloaded I want to make header row which specify the column heading, read only. After downloading no one can make any change in headers. Is it Possible to do make column name un-editable ? I looked for lock function , or protect function but couldn't find answer. please help.
i have registerEvents() function where i'm specifying all the editing parts like ,
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
$event->sheet->getDelegate()->getStyle('A1:C1')->getFont()->setSize(16);
},
];
}
is there any function i can write here or anywhere!?
This solution worked for me for making header uneditable
$sheet->protectCells('A1:G1', 'PASSWORD');
$sheet->getStyle('A2:G10')->getProtection()->setLocked(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_UNPROTECTED);
//A2:G10 is the range which can be editable
$sheet->getDelegate()->getProtection()->setSheet(true);

barryvdh/laravel-dompdf renders blank web page

I'm upgrading from Laravel 7 to 8 and would like to switch to barryvdh/laravel-dompdf for PDF generation. I was using niklasravnsborg/laravel-pdf up until now, but since that package doesn't support Laravel 8, I need to switch. So I am in the processing of altering my existing code to use barryvdh/laravel-dompdf, but I'm running into an issue.
This is my (simplified) controller:
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
$this->exportInvoice($invoice, $request);
}
}
This exportInvoice function is in the same controller file.
I'm using this to generate a test PDF:
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
Now I've managed to narrow down the issue to the place in my code where the PDF generation fails.
If I put the PDF generation code in the if statement in the update function above, then I get the expected result: a simple PDF file.
However, as soon as I move this piece of code to the exportInvoice function, I get a simple blank web page.
I've been googling around, but I was unable to find similar issues.
I've tried putting all my code together in the update function and guess what ... This works as expected. It's as if I'm doing something wrong with the subfunctions, but I can't figure out what.
Does anybody see what I'm doing wrong?
From your update() method, this will stream a PDF back to the browser:
return $pdf->stream();
But from a exportInvoice(), called by the update() method, that will just return the stream back to the update() method. If you don't do anything with it there, it won't reach the browser. You need to return the response returned from exportInvoice().
public function update(Request $request) {
$invoice = Invoice::find($request->invoice_id);
if(isset($request->export) AND $request->export == 1) {
// Note we need to *return* the response to the browser
return $this->exportInvoice($invoice, $request);
}
}
public function exportInvoice($invoice, $request) {
$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');
return $pdf->stream();
}

Setting up Laravel-excel and PhpSpreadsheet macro

I am using Maatwebsite Laravel-excel version 3.1. And I want to set the default styling of the sheet. I have read the documentation about including a macro in your laravel app by setting this in my AppServiceProvider boot() method. :
Sheet::macro('getDefaultStyle',function(Sheet $sheet){
$sheet->getDefaultStyle();
});
But when everytime i reload the page it crashes the page and the laravel server in my cmd stops and re run. Here is my Export.php looks like:
public function registerEvents():array
{
return[
AfterSheet::class=>function(AfterSheet $event){
$header_style_array = [
'font'=>['bold'=>true]
];
$style_array = [
'font'=>['bold'=>true]
];
$event->sheet->getStyle('A1:B1')->getAlignment()->setHorizontal('center');
$event->sheet->getStyle('A1:B1')->applyFromArray($header_style_array);
$event->sheet->getDefaultStyle()->getFont()->setSize(5);
}];
}
I already included use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\AfterSheet; above my Export.php file.
Is there something that I missed? I find this so hard to set up. And there's little article about setting this up.
Any help would be much appreciated
Refs: https://phpspreadsheet.readthedocs.io/en/latest/topics/recipes/#styles
https://docs.laravel-excel.com/3.1/exports/extending.html
If you examine the documentation for PhpSpreadsheet, I think you will find that the getDefaultStyle() method is not accessible from the active sheet.
To Laravel Excel, $event->sheet is equivalent to $spreadsheet->getActiveSheet(). This is why your current configuration will not work.
// this doesn't work
// $spreadsheet->getActiveSheet()->getDefaultStyle()->getFont()->setSize(5);
// this does
$spreadsheet->getDefaultStyle()->getFont()->setSize(5);
You should set default styles through the writer in BeforeWriting.
public function registerEvents():array
{
return [
BeforeWriting::class=>function(BeforeWriting $event){
$event->writer->getDefaultStyle()->getFont()->setSize(5);
},
];
}
If you want to turn this into a macro, you should use a Writer macro rather than a Sheet macro.
https://docs.laravel-excel.com/3.1/exports/extending.html#writer
public function registerEvents():array
{
Writer::macro('setDefaultStyle', function (Writer $writer) {
$writer->getDefaultStyle()->getFont()->setSize(5);
});
return [
BeforeWriting::class=>function(BeforeWriting $event){
$event->writer->setDefaultStyle();
},
];
}

How can I set encoding for export csv with Laravel Excel in Laravel

I using Laravel Excel for export CSV file in Laravel.
How can I set the encoding for export csv file.
I have tried several ways:
Change config in excel.php
'use_bom' => false,
Use mb_convert_encoding to convert content to before export.
$exportData = mb_convert_encoding($exportData, "SJIS", "UTF-8");
$pblClassExport = new \App\Exports\PblClassExport($exportData, 'test.csv');
But it's not working. The encoding of csv file auto change by file content.
you need to configure your PblClassExport.php headers
in PblClassExport.php
/**
* Optional headers
*/
private $headers = [
'Content-Type' => 'text/csv',
'Content-Encoding'=> 'SHIFT-JIS' // somthing like this ?
];
i have't done this but i think it will work
ref link
https://docs.laravel-excel.com/3.1/exports/exportables.html#exportables
Update
you can encode line by line
public function bindValue(Cell $cell, $value)
{
$value = mb_convert_encoding($value, "SJIS");
return parent::bindValue($cell, $value);
}
ref link https://www.gitmemory.com/issue/Maatwebsite/Laravel-Excel/1886/552849170
If you you use Laravel Excel 3.1, you can use WithCustomCsvSettings interface. Then you add your encoding setting in the getCsvSettings method like the following.
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
class InvoicesExport implements WithCustomCsvSettings
{
public function getCsvSettings(): array
{
return [
'output_encoding' => 'SJIS',
];
}
}
Plese refer to the docs for more details.
I resolved it. Let's me share my solution here.
Laravel Excel not support it by default.But we can do it by simple way.
Get csv content before download: \Excel::raw
Convert to another encoding: mb_convert_encoding
https://docs.laravel-excel.com/3.1/exports/collection.html#storing-raw-contents
Download csv.
$exportedObject= new \App\Exports\ClassExport($exportDataArray, $fileName);
$csvContent = \Excel::raw($exportedObject, $exportedObject->writerType);
$csvContent = mb_convert_encoding($csvContent, 'SJIS', 'auto');
// In my case, I upload my csv to S3.
$storageInstance = \Storage::disk('s3_import_csvs');
$putFileOnStorage = $storageInstance->put($fileName, $csvContent);
Note: Solution povided by OP on question section.

How to make PDF of a specific portion with dompdf in laravel

I am using dompdf with laravel. Wheni have to make PDF, i write the below code in controller.
public function download()
{
$courseoffers = Courseoffer::all()->get();
$pdf = PDF::loadView('admin.courses.pdf', compact('courseoffers'))->setPaper('a4','landscape');
return $pdf->download('courseoffer.pdf');
}
Here, pdf.blade.php is a specific file. But i don't want to use that. i want a specific portion of blade file to make pdf. How do i achieve it.?

Resources