import 'dart:io'; import 'package:pdf/widgets.dart' as pw; import 'package:pdf/pdf.dart'; import 'package:intl/intl.dart'; import 'package:path_provider/path_provider.dart'; class PdfExporter { /// 🔹 Ekspor satu data pelanggan ke file PDF static Future exportSingleItemToPdf( Map item, { String format = 'A6', // 🔹 default A6 }) async { final pdf = pw.Document(); final dateFormat = DateFormat('dd MMM yyyy, HH:mm', 'id_ID'); final createdAt = item['created_at'] != null ? dateFormat.format(item['created_at']) : '-'; // Tentukan ukuran halaman berdasarkan format final pageFormat = switch (format.toUpperCase()) { 'A4' => PdfPageFormat.a4, 'A5' => PdfPageFormat.a5, _ => PdfPageFormat.a6, // default A6 }; // Pastikan total nominal berupa angka final totalNominal = num.tryParse(item['total']?.toString() ?? '0') ?? 0; // Ambil data toko (jika ada) final store = item['store'] ?? {}; final namaToko = store['namaToko'] ?? '-'; final alamatToko = store['alamat'] ?? '-'; final noHpToko = store['noHp'] ?? '-'; final noRegistrasi = store['noRegistrasi'] ?? '-'; final keteranganToko = store['keterangan'] ?? '-'; pdf.addPage( pw.Page( pageFormat: pageFormat, // 🔹 gunakan ukuran halaman sesuai format margin: const pw.EdgeInsets.all(12), build: (pw.Context context) { return pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Center( child: pw.Text( 'DATA PENGIRIMAN', style: pw.TextStyle( fontSize: 14, fontWeight: pw.FontWeight.bold, ), ), ), pw.SizedBox(height: 6), _buildRow('Nama Penerima', item['penerima']), _buildRow('No. WA', item['no_wa']), _buildRow('Alamat', item['alamat']), _buildRow('Kota', item['kota']), _buildRow('Provinsi', item['provinsi']), _buildRow('Barang', item['barang']), _buildRow( 'Total Nominal', 'Rp ${NumberFormat('#,##0', 'id_ID').format(totalNominal)}', ), _buildRow('Pembayaran', item['pembayaran']), _buildRow('Tanggal Dibuat', createdAt), pw.SizedBox(height: 6), pw.Divider(thickness: 0.8), pw.SizedBox(height: 4), pw.Text( 'DATA TOKO PENGIRIM', style: pw.TextStyle( fontSize: 12, fontWeight: pw.FontWeight.bold, ), ), pw.SizedBox(height: 4), _buildRow('Nama Toko', namaToko), _buildRow('Alamat Toko', alamatToko), _buildRow('No. HP Toko', noHpToko), _buildRow('No. Registrasi', noRegistrasi), _buildRow('Keterangan', keteranganToko), pw.Spacer(), pw.Center( child: pw.Text( 'Dicetak otomatis oleh sistem Praresi', style: const pw.TextStyle(fontSize: 8), ), ), ], ); }, ), ); // 🔹 Simpan ke folder Download (Android) Directory? downloadDir; if (Platform.isAndroid) { downloadDir = Directory('/storage/emulated/0/Download'); } else { downloadDir = await getApplicationDocumentsDirectory(); } final filePath = '${downloadDir.path}/Data_Pengiriman_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}_$format.pdf'; final file = File(filePath); await file.writeAsBytes(await pdf.save()); return filePath; } /// 🔹 Komponen baris label dan isi static pw.Widget _buildRow(String label, dynamic value) { return pw.Padding( padding: const pw.EdgeInsets.symmetric(vertical: 1.5), child: pw.Row( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Container( width: 90, child: pw.Text( label, style: pw.TextStyle( fontWeight: pw.FontWeight.bold, fontSize: 9.5, ), ), ), pw.Expanded( child: pw.Text( value?.toString() ?? '-', style: const pw.TextStyle(fontSize: 9.5), ), ), ], ), ); } }