GenerateDocxJob.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. namespace App\Jobs;
  3. use App\Models\Product;
  4. use Illuminate\Bus\Queueable;
  5. use Illuminate\Contracts\Queue\ShouldBeUnique;
  6. use Illuminate\Contracts\Queue\ShouldQueue;
  7. use Illuminate\Foundation\Bus\Dispatchable;
  8. use Illuminate\Queue\InteractsWithQueue;
  9. use Illuminate\Queue\SerializesModels;
  10. use Illuminate\Support\Facades\Log;
  11. use PhpOffice\PhpWord\TemplateProcessor;
  12. class GenerateDocxJob implements ShouldQueue
  13. {
  14. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  15. protected $ids;
  16. protected $descr;
  17. protected $filename;
  18. protected $template;
  19. /**
  20. * Create a new job instance.
  21. *
  22. * @return void
  23. */
  24. public function __construct($ids, $descr, $filename, $template)
  25. {
  26. $this->ids =$ids;
  27. $this->descr = $descr;
  28. $this->filename = $filename;
  29. $this->template = $template;
  30. }
  31. /**
  32. * Execute the job.
  33. *
  34. * @return void
  35. */
  36. public function handle()
  37. {
  38. $products = Product::query()->whereIn('id', $this->ids)->orderBy('series', 'asc')->get();
  39. $tmpfile = public_path('exported/docx/' . $this->filename . '.txt');
  40. $vars_for_template = [];
  41. $i = 1;
  42. foreach ($products as $product){
  43. switch ($this->descr) {
  44. case 1:
  45. $descr = $product->characteristics . "\r\n" . $product->tech_description_short;
  46. break;
  47. case 2:
  48. $descr = $product->characteristics . "\r\n" . $product->tech_description;
  49. break;
  50. case 3:
  51. $descr = $product->tech_description_short;
  52. break;
  53. case 4:
  54. $descr = $product->tech_description;
  55. break;
  56. case 5:
  57. default:
  58. $descr = $product->characteristics;
  59. break;
  60. }
  61. $vars_for_template = array_merge($vars_for_template, [
  62. 'series#' . $i => $product->series,
  63. 'product_group#' .$i => $product->product_group,
  64. 'num#' . $i => $i,
  65. 'name#' . $i => $product->name,
  66. 'name_for_form#' . $i => $product->name_for_form,
  67. 'price#' . $i => number_format($product->price, 2, '.', ' '),
  68. 'image#' . $i => $product->image_path,
  69. 'description#' . $i => str_replace("\n", '</w:t><w:br/><w:t xml:space="preserve">', $descr),
  70. ]);
  71. // remove last page break
  72. if($i < $products->count()) {
  73. $vars_for_template['page_br#' . $i] = '<w:p><w:r><w:br w:type="page"/></w:r></w:p>';
  74. } else {
  75. $vars_for_template['page_br#' . $i] = '';
  76. }
  77. $i++;
  78. }
  79. $my_template = new TemplateProcessor(storage_path('templates/' . $this->template));
  80. $my_template->cloneBlock('product_block', $products->count(), true, true, $vars_for_template);
  81. $i = 0;
  82. $total = count($vars_for_template);
  83. foreach ($vars_for_template as $k => $v){
  84. $file = public_path() . '/' . env('IMAGES_PATH') . '/' . $v;
  85. if(str_starts_with($k, 'image') && file_exists($file) && $v !== ''){
  86. $my_template->setImageValue($k, ['path' => $file, 'width' => 270, 'height' => 180]);
  87. } else {
  88. $my_template->setValue($k, $v);
  89. }
  90. if(($i++ % 50) == 0) {
  91. $f = fopen($tmpfile, 'w+');
  92. $percent = round(($i - 2) / ($total / 100), 0);
  93. fwrite($f, $percent);
  94. fclose($f);
  95. }
  96. }
  97. $my_template->saveAs(public_path('exported/docx/') . $this->filename);
  98. unlink($tmpfile);
  99. Log::notice('Generation finished: ' . $i . ' / ' . $total . ' Execution time: ' . microtime(true) - LARAVEL_START);
  100. }
  101. }