E41220983_MuhamadSugengCahy.../praresi/lib/utils/pdf_exporter.dart

143 lines
4.5 KiB
Dart

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<String> exportSingleItemToPdf(
Map<String, dynamic> 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),
),
),
],
),
);
}
}