add export excel and pdf report director

This commit is contained in:
arifal
2025-03-19 18:22:00 +07:00
parent 1713e32b67
commit 47a9fb1dfb
6 changed files with 302 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
<?php
namespace App\Exports;
use App\Models\BigdataResume;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
class ReportDirectorExport implements FromCollection, WithHeadings, WithMapping
{
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
return BigdataResume::select(
'potention_count',
'potention_sum',
'non_verified_count',
'non_verified_sum',
'verified_count',
'verified_sum',
'business_count',
'business_sum',
'non_business_count',
'non_business_sum',
'spatial_count',
'spatial_sum',
'waiting_click_dpmptsp_count',
'waiting_click_dpmptsp_sum',
'issuance_realization_pbg_count',
'issuance_realization_pbg_sum',
'process_in_technical_office_count',
'process_in_technical_office_sum',
'year',
'created_at'
)->orderBy('id', 'desc')->get();
}
public function headings(): array{
return [
"Jumlah Potensi" ,
"Total Potensi" ,
"Jumlah Berkas Belum Terverifikasi" ,
"Total Berkas Belum Terverifikasi" ,
"Jumlah Berkas Terverifikasi" ,
"Total Berkas Terverifikasi" ,
"Jumlah Usaha" ,
"Total Usaha" ,
"Jumlah Non Usaha" ,
"Total Non Usaha" ,
"Jumlah Tata Ruang" ,
"Total Tata Ruang" ,
"Jumlah Menunggu Klik DPMPTSP" ,
"Total Menunggu Klik DPMPTSP" ,
"Jumlah Realisasi Terbit PBG" ,
"Total Realisasi Terbit PBG" ,
"Jumlah Proses Dinas Teknis" ,
"Total Proses Dinas Teknis",
"Tahun",
"Created"
];
}
public function map($row): array
{
return [
$row->potention_count,
$row->potention_sum,
$row->non_verified_count,
$row->non_verified_sum,
$row->verified_count,
$row->verified_sum,
$row->business_count,
$row->business_sum,
$row->non_business_count,
$row->non_business_sum,
$row->spatial_count,
$row->spatial_sum,
$row->waiting_click_dpmptsp_count,
$row->waiting_click_dpmptsp_sum,
$row->issuance_realization_pbg_count,
$row->issuance_realization_pbg_sum,
$row->process_in_technical_office_count,
$row->process_in_technical_office_sum,
$row->year,
$row->created_at ? $row->created_at->format('Y-m-d H:i:s') : null, // Format created_at as Y-m-d
];
}
}

View File

@@ -2,12 +2,15 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Exports\ReportDirectorExport;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Resources\BigdataResumeResource; use App\Http\Resources\BigdataResumeResource;
use App\Models\BigdataResume; use App\Models\BigdataResume;
use App\Models\DataSetting; use App\Models\DataSetting;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
class BigDataResumeController extends Controller class BigDataResumeController extends Controller
{ {
@@ -219,7 +222,36 @@ class BigDataResumeController extends Controller
} }
} }
public function export_excel_report_director(){
return Excel::download(new ReportDirectorExport, 'laporan-pimpinan.xlsx');
}
public function export_pdf_report_director(){
$data = BigdataResume::select(
'potention_count',
'potention_sum',
'non_verified_count',
'non_verified_sum',
'verified_count',
'verified_sum',
'business_count',
'business_sum',
'non_business_count',
'non_business_sum',
'spatial_count',
'spatial_sum',
'waiting_click_dpmptsp_count',
'waiting_click_dpmptsp_sum',
'issuance_realization_pbg_count',
'issuance_realization_pbg_sum',
'process_in_technical_office_count',
'process_in_technical_office_sum',
'year',
'created_at'
)->orderBy('id', 'desc')->get();
$pdf = Pdf::loadView('exports.report_director', compact('data'))->setPaper('a4', 'landscape');
return $pdf->download('laporan-pimpinan.pdf');
}
private function response_empty_resume(){ private function response_empty_resume(){
$result = [ $result = [
'target_pad' => [ 'target_pad' => [

View File

@@ -17,6 +17,8 @@ class BigdataResume {
async initEvents() { async initEvents() {
await this.initBigdataResumeTable(); await this.initBigdataResumeTable();
// this.handleSearch(); // this.handleSearch();
await this.handleExportPDF();
await this.handleExportToExcel();
} }
async initBigdataResumeTable() { async initBigdataResumeTable() {
@@ -114,6 +116,100 @@ class BigdataResume {
}); });
} }
async handleExportToExcel() {
const button = document.getElementById("btn-export-excel");
if (!button) {
console.error("Button not found: #btn-export-excel");
return;
}
let exportUrl = button.getAttribute("data-url");
button.addEventListener("click", async () => {
button.disabled = true;
try {
const response = await fetch(`${exportUrl}`, {
method: "GET",
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
});
if (!response.ok) {
console.error("Error fetching data:", response.statusText);
button.disabled = false;
return;
}
// Convert response to Blob and trigger download
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "laporan-pimpinan.xlsx";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (error) {
console.error("Error fetching data:", error);
button.disabled = false;
return;
} finally {
button.disabled = false;
}
});
}
async handleExportPDF() {
const button = document.getElementById("btn-export-pdf");
if (!button) {
console.error("Button not found: #btn-export-pdf");
return;
}
let exportUrl = button.getAttribute("data-url");
button.addEventListener("click", async () => {
button.disabled = true;
try {
const response = await fetch(`${exportUrl}`, {
method: "GET",
credentials: "include",
headers: {
Authorization: `Bearer ${document
.querySelector('meta[name="api-token"]')
.getAttribute("content")}`,
},
});
if (!response.ok) {
console.error("Error fetching data:", response.statusText);
button.disabled = false;
return;
}
// Convert response to Blob and trigger download
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "laporan-pimpinan.pdf";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} catch (error) {
console.error("Error fetching data:", error);
button.disabled = false;
return;
} finally {
button.disabled = false;
}
});
}
handleSearch() { handleSearch() {
document.getElementById("search-btn").addEventListener("click", () => { document.getElementById("search-btn").addEventListener("click", () => {
let searchValue = document.getElementById("search-box").value; let searchValue = document.getElementById("search-box").value;

View File

@@ -13,6 +13,19 @@
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="card w-100 h-100"> <div class="card w-100 h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Laporan Pimpinan</h5>
<div class="d-flex gap-2">
<button class="btn btn-sm bg-black text-white d-flex align-items-center content-center gap-2" id="btn-export-excel" data-url="{{ route('api.report-director.excel') }}">
<span>.xlsx</span>
<iconify-icon icon="mingcute:file-export-line" width="20" height="20" class="d-flex align-items-center"></iconify-icon>
</button>
<button class="btn btn-sm bg-black text-white d-flex align-items-center content-center gap-2" id="btn-export-pdf" data-url="{{ route('api.report-director.pdf') }}">
<span>.pdf</span>
<iconify-icon icon="mingcute:file-export-line" width="20" height="20" class="d-flex align-items-center"></iconify-icon>
</button>
</div>
</div>
<div class="card-body"> <div class="card-body">
<div id="table-bigdata-resumes"></div> <div id="table-bigdata-resumes"></div>
</div> </div>

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Laporan Pimpinan</title>
<style>
body { font-size: 10px; } /* Reduce font size */
table { width: 100%; border-collapse: collapse; }
th, td { padding: 3px; font-size: 9px; border: 1px solid black;} /* Reduce padding */
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h2>Laporan Pimpinan</h2>
<table>
<thead>
<tr>
<th>Jumlah Potensi</th>
<th>Total Potensi</th>
<th>Jumlah Berkas Belum Terverifikasi</th>
<th>Total Berkas Belum Terverifikasi</th>
<th>Jumlah Berkas Terverifikasi</th>
<th>Total Berkas Terverifikasi</th>
<th>Jumlah Usaha</th>
<th>Total Usaha</th>
<th>Jumlah Non Usaha</th>
<th>Total Non Usaha</th>
<th>Jumlah Tata Ruang</th>
<th>Total Tata Ruang</th>
<th>Jumlah Menunggu Klik DPMPTSP</th>
<th>Total Menunggu Klik DPMPTSP</th>
<th>Jumlah Realisasi Terbit PBG</th>
<th>Total Realisasi Terbit PBG</th>
<th>Jumlah Proses Dinas Teknis</th>
<th>Total Proses Dinas Teknis</th>
<th>Tahun</th>
<th>Created</th>
</tr>
</thead>
<tbody>
@foreach($data as $item)
<tr>
<td>{{ $item->potention_count }}</td>
<td>{{ $item->potention_sum }}</td>
<td>{{ $item->non_verified_count }}</td>
<td>{{ $item->non_verified_sum }}</td>
<td>{{ $item->verified_count }}</td>
<td>{{ $item->verified_sum }}</td>
<td>{{ $item->business_count }}</td>
<td>{{ $item->business_sum }}</td>
<td>{{ $item->non_business_count }}</td>
<td>{{ $item->non_business_sum }}</td>
<td>{{ $item->spatial_count }}</td>
<td>{{ $item->spatial_sum }}</td>
<td>{{ $item->waiting_click_dpmptsp_count }}</td>
<td>{{ $item->waiting_click_dpmptsp_sum }}</td>
<td>{{ $item->issuance_realization_pbg_count }}</td>
<td>{{ $item->issuance_realization_pbg_sum }}</td>
<td>{{ $item->process_in_technical_office_count }}</td>
<td>{{ $item->process_in_technical_office_sum }}</td>
<td>{{ $item->year }}</td>
<td>{{ $item->created_at->format('Y-m-d') }}</td>
</tr>
@endforeach
</tbody>
</table>
</body>
</html>

View File

@@ -147,6 +147,8 @@ Route::group(['middleware' => 'auth:sanctum'], function (){
Route::get('/bigdata-resume', 'index')->name('api.bigdata-resume'); Route::get('/bigdata-resume', 'index')->name('api.bigdata-resume');
Route::get('/bigdata-report', 'bigdata_report')->name('api.bigdata-report'); Route::get('/bigdata-report', 'bigdata_report')->name('api.bigdata-report');
Route::get('/payment-recaps', 'payment_recaps')->name('api.payment-recaps'); Route::get('/payment-recaps', 'payment_recaps')->name('api.payment-recaps');
Route::get('/report-director/excel', 'export_excel_report_director')->name('api.report-director.excel');
Route::get('/report-director/pdf', 'export_pdf_report_director')->name('api.report-director.pdf');
}); });
// task-assignments // task-assignments