In this tutorial we’ll generate a full fledged letter in Word format using PHPWord in Laravel 8 app.
First, a little bit background of this letter. The letter is the covering page of a bank confirmation which the auditors send to banks annually for direct bank confirmation. We created a Laravel app where we generate this letter automatically for all bank confirmations of our audit clients.
Coming back to our app, you can start by creating a fresh Laravel app by entering following command:
composer create-project laravel/laravel app 8.*
Now install PHPWord by executing the following command inside project directory:
composer require phpoffice/phpword
In Laravel, there is a convenient way of handling a complex controller action – by creating a Single Action Controller. This type of controller contains single method __invoke() and can be called by controller name only without mentioning the method name. So, let’s create a Single Action Controller for generating our letter:
php artisan make:controller Letter --invokable
Now, open the newly created file Letter.php in app/Http/Controllers/ folder and enter the following code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Writer\Word2007;
use Carbon\Carbon;
class Letter extends Controller
{
public function __invoke(Request $request)
{
$phpWord = new PhpWord();
// Setting various styles to be used
$phpWord->addParagraphStyle('p1Style', array('align'=>'both', 'spaceAfter'=>0, 'spaceBefore'=>0));
$phpWord->addParagraphStyle('p2Style', array('align'=>'both'));
$phpWord->addParagraphStyle('p3Style', array('align'=>'right', 'spaceAfter'=>0, 'spaceBefore'=>0));
$phpWord->addFontStyle('f1Style', array('name' => 'Calibri', 'size'=>12));
$phpWord->addFontStyle('f2Style', array('name' => 'Calibri','bold'=>true, 'size'=>12));
$company = "ABC (Private) Limited";
// Defining data. For simplicity we're using hardcoded data; practically they will be fetched from database.
$no_of_banks = 3;
$branches = ["Clifton Branch","Defence Branch","15th Street Branch"];
$begin = Carbon::parse("1/1/2020");
$end = Carbon::parse("12/31/2020");
$year = $end->year;
$str = "first Monday of July {$year}";
$date = new Carbon($str);
// Getting first characters from company name for generating reference
$name = str_replace(["(",")"],"",$company);
$words = preg_split("/[\s,_-]+/", $name);
$acronym = "";
$count = 1;
foreach ($words as $w) {
$acronym .= $w[0];
}
// Generating letter for each branch
for($i=0;$i<count($branches);$i++) {
$section = $phpWord->addSection();
$textrun = $section->addTextRun();
$section->addTextBreak(2);
$ref = "MZ-BCONF/".$acronym."/".$year."/".$count++;
$section->addText($ref, 'f2Style', 'p1Style');
$textrun = $section->addTextRun();
$section->addTextBreak(1);
$section->addText($date->format('F j, Y'), 'f2Style', 'p1Style');
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$section->addText('The Manager,','f1Style','p1Style');
$section->addText($branches[$i],'f1Style','p1Style');
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$section->addText('Dear Sir,','f1Style','p2Style');
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun('p2Style');
$textrun->addText('Subject: ', 'f1Style');
$textrun->addText('Bank Report for Audit Purpose of ', 'f2Style');
$textrun->addText($company, 'f2Style');
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun('p2Style');
$textrun->addText(
"In accordance with your above named customer’s instructions given hereon, please send DIRECT to us at the below address, as auditors of your customer, the following information relating to their affairs at your branch as at the close of business on ",
'f1Style',
);
$textrun->addText($end->format('F j, Y'), 'f2Style');
$textrun->addText(
" and, in the case of items 2, 4 and 9, during the period since ",
'f1Style',
);
$textrun->addText($begin->format('F j, Y'), 'f2Style');
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun();
$textrun->addText(
"Please state against each item any factors which may limit the completeness of your reply; if there is nothing to report, state ‘NONE’.",
'f1Style', 'p2Style'
);
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun();
$textrun->addText(
"It is understood that any replies given are in strict confidence, for the purposes of audit.",
'f1Style', 'p2Style'
);
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun();
$textrun->addText(
"Yours truly,",
'f1Style', 'p2Style'
);
$section->addText(
"Disclosure Authorized",
'f2Style', 'p3Style'
);
$section->addText(
"For and on behalf of",
'f2Style', 'p3Style'
);
$textrun = $section->addTextRun();
$section->addTextBreak(1);
$textrun = $section->addTextRun();
$textrun->addText(
"Chartered Accountants ___________________",
'f2Style', 'p2Style'
);
$textrun = $section->addTextRun();
$section->addTextBreak(0);
$textrun = $section->addTextRun();
$textrun->addText(
"Enclosures:",
'f1Style', 'p2Style'
);
}
$writer = new Word2007($phpWord);
$writer->save('Bank Letters.docx');
}
}
Finally, open routes/web.php and put the following line at the top of it:
use App\Http\Controllers\Letter;
And then insert following route into this web.php:
Route::get('/letter', Letter::class)->name('letter');
Run Laravel development server by executing:
php artisan serve
Enter the following URL in your browser:
localhost:8000/letter
“Bank Letters.docx” file has been generated and saved in public folder of the app.